h2pas.y 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256
  1. %{
  2. program h2pas;
  3. (*
  4. $Id$
  5. Copyright (c) 1998-2000 by Florian Klaempfl
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************)
  18. uses
  19. {$ifdef go32v2}
  20. {$ifndef NOEXCP}
  21. dpmiexcp,
  22. {$endif NOEXCP}
  23. {$endif}
  24. {$IFDEF WIN32}
  25. SysUtils,
  26. {$else}
  27. strings,
  28. {$endif}
  29. options,scan,converu,lexlib,yacclib;
  30. type
  31. YYSTYPE = presobject;
  32. const
  33. INT_STR = 'longint';
  34. SHORT_STR = 'smallint';
  35. UINT_STR = 'dword';
  36. USHORT_STR = 'word';
  37. CHAR_STR = 'char';
  38. INT64_STR = 'int64';
  39. QWORD_STR = 'qword';
  40. { should we use byte or char for 'unsigned char' ?? }
  41. UCHAR_STR = 'byte';
  42. REAL_STR = 'double';
  43. var
  44. hp,ph : presobject;
  45. extfile : text; (* file for implementation headers extern procs *)
  46. IsExtern : boolean;
  47. must_write_packed_field : boolean;
  48. tempfile : text;
  49. No_pop : boolean;
  50. s,TN,PN : String;
  51. (* $ define yydebug
  52. compile with -dYYDEBUG to get debugging info *)
  53. const
  54. (* number of a?b:c construction in one define *)
  55. if_nb : longint = 0;
  56. is_packed : boolean = false;
  57. is_procvar : boolean = false;
  58. var space_array : array [0..255] of byte;
  59. space_index : byte;
  60. procedure shift(space_number : byte);
  61. var
  62. i : byte;
  63. begin
  64. space_array[space_index]:=space_number;
  65. inc(space_index);
  66. for i:=1 to space_number do
  67. aktspace:=aktspace+' ';
  68. end;
  69. procedure popshift;
  70. begin
  71. dec(space_index);
  72. if space_index<0 then
  73. internalerror(20);
  74. dec(byte(aktspace[0]),space_array[space_index]);
  75. end;
  76. function str(i : longint) : string;
  77. var
  78. s : string;
  79. begin
  80. system.str(i,s);
  81. str:=s;
  82. end;
  83. function hexstr(i : cardinal) : string;
  84. const
  85. HexTbl : array[0..15] of char='0123456789ABCDEF';
  86. var
  87. str : string;
  88. begin
  89. str:='';
  90. while i<>0 do
  91. begin
  92. str:=hextbl[i and $F]+str;
  93. i:=i shr 4;
  94. end;
  95. if str='' then str:='0';
  96. hexstr:='$'+str;
  97. end;
  98. function uppercase(s : string) : string;
  99. var
  100. i : byte;
  101. begin
  102. for i:=1 to length(s) do
  103. s[i]:=UpCase(s[i]);
  104. uppercase:=s;
  105. end;
  106. procedure write_type_specifier(var outfile:text; p : presobject);forward;
  107. procedure write_p_a_def(var outfile:text; p,simple_type : presobject);forward;
  108. procedure write_ifexpr(var outfile:text; p : presobject);forward;
  109. procedure write_funexpr(var outfile:text; p : presobject);forward;
  110. procedure yymsg(const msg : string);
  111. begin
  112. writeln('line ',line_no,': ',msg);
  113. end;
  114. procedure write_packed_fields_info(var outfile:text; p : presobject; ph : string);
  115. var
  116. hp1,hp2,hp3 : presobject;
  117. is_sized : boolean;
  118. line : string;
  119. flag_index : longint;
  120. name : pchar;
  121. ps : byte;
  122. begin
  123. { write out the tempfile created }
  124. close(tempfile);
  125. reset(tempfile);
  126. is_sized:=false;
  127. flag_index:=0;
  128. writeln(outfile,aktspace,'const');
  129. shift(3);
  130. while not eof(tempfile) do
  131. begin
  132. readln(tempfile,line);
  133. ps:=pos('&',line);
  134. if ps>0 then
  135. line:=copy(line,1,ps-1)+ph+'_'+copy(line,ps+1,255);
  136. writeln(outfile,aktspace,line);
  137. end;
  138. close(tempfile);
  139. rewrite(tempfile);
  140. popshift;
  141. (* walk through all members *)
  142. hp1 := p^.p1;
  143. while assigned(hp1) do
  144. begin
  145. (* hp2 is t_memberdec *)
  146. hp2:=hp1^.p1;
  147. (* hp3 is t_declist *)
  148. hp3:=hp2^.p2;
  149. while assigned(hp3) do
  150. begin
  151. if assigned(hp3^.p1^.p3) and
  152. (hp3^.p1^.p3^.typ = t_size_specifier) then
  153. begin
  154. is_sized:=true;
  155. name:=hp3^.p1^.p2^.p;
  156. { get function in interface }
  157. write(outfile,aktspace,'function ',name);
  158. write(outfile,'(var a : ',ph,') : ');
  159. shift(2);
  160. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  161. writeln(outfile,';');
  162. popshift;
  163. { get function in implementation }
  164. write(extfile,aktspace,'function ',name);
  165. write(extfile,'(var a : ',ph,') : ');
  166. shift(2);
  167. write_p_a_def(extfile,hp3^.p1^.p1,hp2^.p1);
  168. writeln(extfile,';');
  169. writeln(extfile,aktspace,'begin');
  170. shift(3);
  171. write(extfile,aktspace,name,':=(a.flag',flag_index);
  172. writeln(extfile,' and bm_',ph,'_',name,') shr bp_',ph,'_',name,';');
  173. popshift;
  174. writeln(extfile,aktspace,'end;');
  175. popshift;
  176. writeln(extfile);
  177. { set function in interface }
  178. write(outfile,aktspace,'procedure set_',name);
  179. write(outfile,'(var a : ',ph,'; __',name,' : ');
  180. shift(2);
  181. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  182. writeln(outfile,');');
  183. popshift;
  184. { set function in implementation }
  185. write(extfile,aktspace,'procedure set_',name);
  186. write(extfile,'(var a : ',ph,'; __',name,' : ');
  187. shift(2);
  188. write_p_a_def(extfile,hp3^.p1^.p1,hp2^.p1);
  189. writeln(extfile,');');
  190. writeln(extfile,aktspace,'begin');
  191. shift(3);
  192. write(extfile,aktspace,'a.flag',flag_index,':=');
  193. write(extfile,'a.flag',flag_index,' or ');
  194. writeln(extfile,'((__',name,' shl bp_',ph,'_',name,') and bm_',ph,'_',name,');');
  195. popshift;
  196. writeln(extfile,aktspace,'end;');
  197. popshift;
  198. writeln(extfile);
  199. end
  200. else if is_sized then
  201. begin
  202. is_sized:=false;
  203. inc(flag_index);
  204. end;
  205. hp3:=hp3^.next;
  206. end;
  207. hp1:=hp1^.next;
  208. end;
  209. must_write_packed_field:=false;
  210. block_type:=bt_no;
  211. end;
  212. procedure write_expr(var outfile:text; p : presobject);
  213. begin
  214. if assigned(p) then
  215. begin
  216. case p^.typ of
  217. t_id,t_ifexpr : write(outfile,p^.p);
  218. t_funexprlist : write_funexpr(outfile,p);
  219. t_preop : begin
  220. write(outfile,p^.p,'(');
  221. write_expr(outfile,p^.p1);
  222. write(outfile,')');
  223. flush(outfile);
  224. end;
  225. t_typespec : begin
  226. write_type_specifier(outfile,p^.p1);
  227. write(outfile,'(');
  228. write_expr(outfile,p^.p2);
  229. write(outfile,')');
  230. flush(outfile);
  231. end;
  232. t_bop : begin
  233. if p^.p1^.typ<>t_id then
  234. write(outfile,'(');
  235. write_expr(outfile,p^.p1);
  236. if p^.p1^.typ<>t_id then
  237. write(outfile,')');
  238. write(outfile,p^.p);
  239. if p^.p2^.typ<>t_id then
  240. write(outfile,'(');
  241. write_expr(outfile,p^.p2);
  242. if p^.p2^.typ<>t_id then
  243. write(outfile,')');
  244. flush(outfile);
  245. end;
  246. else internalerror(2);
  247. end;
  248. end;
  249. end;
  250. procedure write_ifexpr(var outfile:text; p : presobject);
  251. begin
  252. flush(outfile);
  253. write(outfile,'if ');
  254. write_expr(outfile,p^.p1);
  255. writeln(outfile,' then');
  256. write(outfile,aktspace,' ');
  257. write(outfile,p^.p);
  258. write(outfile,':=');
  259. write_expr(outfile,p^.p2);
  260. writeln(outfile);
  261. writeln(outfile,aktspace,'else');
  262. write(outfile,aktspace,' ');
  263. write(outfile,p^.p);
  264. write(outfile,':=');
  265. write_expr(outfile,p^.p3);
  266. writeln(outfile,';');
  267. write(outfile,aktspace);
  268. flush(outfile);
  269. end;
  270. procedure write_all_ifexpr(var outfile:text; p : presobject);
  271. begin
  272. if assigned(p) then
  273. begin
  274. case p^.typ of
  275. t_id :;
  276. t_preop :
  277. write_all_ifexpr(outfile,p^.p1);
  278. t_bop :
  279. begin
  280. write_all_ifexpr(outfile,p^.p1);
  281. write_all_ifexpr(outfile,p^.p2);
  282. end;
  283. t_ifexpr :
  284. begin
  285. write_all_ifexpr(outfile,p^.p1);
  286. write_all_ifexpr(outfile,p^.p2);
  287. write_all_ifexpr(outfile,p^.p3);
  288. write_ifexpr(outfile,p);
  289. end;
  290. t_typespec :
  291. write_all_ifexpr(outfile,p^.p2);
  292. t_funexprlist,
  293. t_exprlist :
  294. begin
  295. if assigned(p^.p1) then
  296. write_all_ifexpr(outfile,p^.p1);
  297. if assigned(p^.next) then
  298. write_all_ifexpr(outfile,p^.next);
  299. end
  300. else
  301. internalerror(6);
  302. end;
  303. end;
  304. end;
  305. procedure write_funexpr(var outfile:text; p : presobject);
  306. var
  307. i : longint;
  308. begin
  309. if assigned(p) then
  310. begin
  311. case p^.typ of
  312. t_ifexpr :
  313. write(outfile,p^.p);
  314. t_exprlist :
  315. begin
  316. write_expr(outfile,p^.p1);
  317. if assigned(p^.next) then
  318. begin
  319. write(outfile,',');
  320. write_funexpr(outfile,p^.next);
  321. end
  322. end;
  323. t_funcname :
  324. begin
  325. shift(2);
  326. if if_nb>0 then
  327. begin
  328. writeln(outfile,aktspace,'var');
  329. write(outfile,aktspace,' ');
  330. for i:=1 to if_nb do
  331. begin
  332. write(outfile,'if_local',i);
  333. if i<if_nb then
  334. write(outfile,', ')
  335. else
  336. writeln(outfile,' : longint;');
  337. end;
  338. writeln(outfile,aktspace,'(* result types are not known *)');
  339. if_nb:=0;
  340. end;
  341. writeln(outfile,aktspace,'begin');
  342. shift(3);
  343. write(outfile,aktspace);
  344. write_all_ifexpr(outfile,p^.p2);
  345. write_expr(outfile,p^.p1);
  346. write(outfile,':=');
  347. write_funexpr(outfile,p^.p2);
  348. writeln(outfile,';');
  349. popshift;
  350. writeln(outfile,aktspace,'end;');
  351. popshift;
  352. flush(outfile);
  353. end;
  354. t_funexprlist :
  355. begin
  356. if assigned(p^.p3) then
  357. begin
  358. write_type_specifier(outfile,p^.p3);
  359. write(outfile,'(');
  360. end;
  361. if assigned(p^.p1) then
  362. write_funexpr(outfile,p^.p1);
  363. if assigned(p^.p2) then
  364. begin
  365. write(outfile,'(');
  366. write_funexpr(outfile,p^.p2);
  367. write(outfile,')');
  368. end;
  369. if assigned(p^.p3) then
  370. write(outfile,')');
  371. end
  372. else internalerror(5);
  373. end;
  374. end;
  375. end;
  376. function ellipsisarg : presobject;
  377. begin
  378. ellipsisarg:=new(presobject,init_two(t_arg,nil,nil));
  379. end;
  380. const
  381. (* if in args *dname is replaced by pdname *)
  382. in_args : boolean = false;
  383. typedef_level : longint = 0;
  384. (* writes an argument list, where p is t_arglist *)
  385. procedure write_args(var outfile:text; p : presobject);
  386. var
  387. length,para : longint;
  388. old_in_args : boolean;
  389. varpara : boolean;
  390. begin
  391. para:=1;
  392. length:=0;
  393. old_in_args:=in_args;
  394. in_args:=true;
  395. write(outfile,'(');
  396. shift(2);
  397. (* walk through all arguments *)
  398. (* p must be of type t_arglist *)
  399. while assigned(p) do
  400. begin
  401. if p^.typ<>t_arglist then
  402. internalerror(10);
  403. (* is ellipsis ? *)
  404. if not assigned(p^.p1^.p1) and
  405. not assigned(p^.p1^.next) then
  406. begin
  407. { write(outfile,'...'); }
  408. write(outfile,'args:array of const');
  409. { if variable number of args we must allways pop }
  410. no_pop:=false;
  411. end
  412. (* we need to correct this in the pp file after *)
  413. else
  414. begin
  415. (* generate a call by reference parameter ? *)
  416. varpara:=usevarparas and assigned(p^.p1^.p2^.p1) and
  417. ((p^.p1^.p2^.p1^.typ=t_pointerdef) or
  418. (p^.p1^.p2^.p1^.typ=t_addrdef));
  419. (* do not do it for char pointer !! *)
  420. (* para : pchar; and var para : char; are *)
  421. (* completely different in pascal *)
  422. (* here we exclude all typename containing char *)
  423. (* is this a good method ?? *)
  424. if varpara and
  425. (p^.p1^.p2^.p1^.typ=t_pointerdef) and
  426. (p^.p1^.p2^.p1^.p1^.typ=t_id) and
  427. (pos('CHAR',uppercase(p^.p1^.p2^.p1^.p1^.str))<>0) then
  428. varpara:=false;
  429. if varpara then
  430. begin
  431. write(outfile,'var ');
  432. length:=length+4;
  433. end;
  434. (* write new type name *)
  435. if assigned(p^.p1^.p2^.p2) then
  436. begin
  437. write(outfile,p^.p1^.p2^.p2^.p);
  438. length:=length+p^.p1^.p2^.p2^.strlength;
  439. end
  440. else
  441. begin
  442. If removeUnderscore then
  443. begin
  444. Write (outfile,'para',para);
  445. Length:=(Length+5);
  446. end
  447. else
  448. begin
  449. write(outfile,'_para',para);
  450. length:=length+6;
  451. end;
  452. end;
  453. write(outfile,':');
  454. if varpara then
  455. write_p_a_def(outfile,p^.p1^.p2^.p1^.p1,p^.p1^.p1)
  456. else
  457. write_p_a_def(outfile,p^.p1^.p2^.p1,p^.p1^.p1);
  458. end;
  459. p:=p^.next;
  460. if assigned(p) then
  461. begin
  462. write(outfile,'; ');
  463. { if length>40 then : too complicated to compute }
  464. if (para mod 5) = 0 then
  465. begin
  466. writeln(outfile);
  467. write(outfile,aktspace);
  468. end;
  469. end;
  470. inc(para);
  471. end;
  472. write(outfile,')');
  473. flush(outfile);
  474. in_args:=old_in_args;
  475. popshift;
  476. end;
  477. procedure write_p_a_def(var outfile:text; p,simple_type : presobject);
  478. var
  479. i : longint;
  480. error : integer;
  481. constant : boolean;
  482. begin
  483. if not(assigned(p)) then
  484. begin
  485. write_type_specifier(outfile,simple_type);
  486. exit;
  487. end;
  488. case p^.typ of
  489. t_pointerdef : begin
  490. (* procedure variable ? *)
  491. if assigned(p^.p1) and (p^.p1^.typ=t_procdef) then
  492. begin
  493. is_procvar:=true;
  494. (* distinguish between procedure and function *)
  495. if (simple_type^.typ=t_void) and (p^.p1^.p1=nil) then
  496. begin
  497. write(outfile,'procedure ');
  498. shift(10);
  499. (* write arguments *)
  500. if assigned(p^.p1^.p2) then
  501. write_args(outfile,p^.p1^.p2);
  502. flush(outfile);
  503. popshift;
  504. end
  505. else
  506. begin
  507. write(outfile,'function ');
  508. shift(9);
  509. (* write arguments *)
  510. if assigned(p^.p1^.p2) then
  511. write_args(outfile,p^.p1^.p2);
  512. write(outfile,':');
  513. flush(outfile);
  514. write_p_a_def(outfile,p^.p1^.p1,simple_type);
  515. popshift;
  516. end
  517. end
  518. else
  519. begin
  520. (* generate "pointer" ? *)
  521. if (simple_type^.typ=t_void) and (p^.p1=nil) then
  522. begin
  523. write(outfile,'pointer');
  524. flush(outfile);
  525. end
  526. else
  527. begin
  528. write(outfile,'P');
  529. write_p_a_def(outfile,p^.p1,simple_type);
  530. end;
  531. end;
  532. end;
  533. t_arraydef : begin
  534. constant:=false;
  535. if p^.p2^.typ=t_id then
  536. begin
  537. val(p^.p2^.str,i,error);
  538. if error=0 then
  539. begin
  540. dec(i);
  541. constant:=true;
  542. end;
  543. end;
  544. if not constant then
  545. begin
  546. write(outfile,'array[0..(');
  547. write_expr(outfile,p^.p2);
  548. write(outfile,')-1] of ');
  549. end
  550. else
  551. begin
  552. write(outfile,'array[0..',i,'] of ');
  553. end;
  554. flush(outfile);
  555. write_p_a_def(outfile,p^.p1,simple_type);
  556. end;
  557. else internalerror(1);
  558. end;
  559. end;
  560. procedure write_type_specifier(var outfile:text; p : presobject);
  561. var
  562. hp1,hp2,hp3,lastexpr : presobject;
  563. i,l,w : longint;
  564. error : integer;
  565. mask : cardinal;
  566. flag_index,current_power : longint;
  567. current_level : byte;
  568. is_sized : boolean;
  569. begin
  570. case p^.typ of
  571. t_id :
  572. write(outfile,p^.p);
  573. { what can we do with void defs ? }
  574. t_void :
  575. write(outfile,'void');
  576. t_pointerdef :
  577. begin
  578. write(outfile,'P');
  579. write_type_specifier(outfile,p^.p1);
  580. end;
  581. t_enumdef :
  582. begin
  583. if (typedef_level>1) and (p^.p1=nil) and
  584. (p^.p2^.typ=t_id) then
  585. begin
  586. write(outfile,p^.p2^.p);
  587. end
  588. else
  589. if not EnumToConst then
  590. begin
  591. write(outfile,'(');
  592. hp1:=p^.p1;
  593. w:=length(aktspace);
  594. while assigned(hp1) do
  595. begin
  596. write(outfile,hp1^.p1^.p);
  597. if assigned(hp1^.p2) then
  598. begin
  599. write(outfile,' := ');
  600. write_expr(outfile,hp1^.p2);
  601. w:=w+6;(* strlen(hp1^.p); *)
  602. end;
  603. w:=w+length(hp1^.p1^.str);
  604. hp1:=hp1^.next;
  605. if assigned(hp1) then
  606. write(outfile,',');
  607. if w>40 then
  608. begin
  609. writeln(outfile);
  610. write(outfile,aktspace);
  611. w:=length(aktspace);
  612. end;
  613. flush(outfile);
  614. end;
  615. write(outfile,')');
  616. flush(outfile);
  617. end
  618. else
  619. begin
  620. Writeln (outfile,' Longint;');
  621. hp1:=p^.p1;
  622. l:=0;
  623. lastexpr:=nil;
  624. Writeln (outfile,copy(aktspace,1,length(aktspace)-2),'Const');
  625. while assigned(hp1) do
  626. begin
  627. write (outfile,aktspace,hp1^.p1^.p,' = ');
  628. if assigned(hp1^.p2) then
  629. begin
  630. write_expr(outfile,hp1^.p2);
  631. writeln(outfile,';');
  632. lastexpr:=hp1^.p2;
  633. if lastexpr^.typ=t_id then
  634. begin
  635. val(lastexpr^.str,l,error);
  636. if error=0 then
  637. begin
  638. inc(l);
  639. lastexpr:=nil;
  640. end
  641. else
  642. l:=1;
  643. end
  644. else
  645. l:=1;
  646. end
  647. else
  648. begin
  649. if assigned(lastexpr) then
  650. begin
  651. write(outfile,'(');
  652. write_expr(outfile,lastexpr);
  653. writeln(outfile,')+',l,';');
  654. end
  655. else
  656. writeln (outfile,l,';');
  657. inc(l);
  658. end;
  659. hp1:=hp1^.next;
  660. flush(outfile);
  661. end;
  662. block_type:=bt_const;
  663. end;
  664. end;
  665. t_structdef :
  666. begin
  667. inc(typedef_level);
  668. flag_index:=-1;
  669. is_sized:=false;
  670. current_level:=0;
  671. if (typedef_level>1) and (p^.p1=nil) and
  672. (p^.p2^.typ=t_id) then
  673. begin
  674. write(outfile,p^.p2^.p);
  675. end
  676. else
  677. begin
  678. writeln(outfile,'record');
  679. shift(3);
  680. hp1:=p^.p1;
  681. (* walk through all members *)
  682. while assigned(hp1) do
  683. begin
  684. (* hp2 is t_memberdec *)
  685. hp2:=hp1^.p1;
  686. (* hp3 is t_declist *)
  687. hp3:=hp2^.p2;
  688. while assigned(hp3) do
  689. begin
  690. if not assigned(hp3^.p1^.p3) or
  691. (hp3^.p1^.p3^.typ <> t_size_specifier) then
  692. begin
  693. if is_sized then
  694. begin
  695. if current_level <= 16 then
  696. writeln(outfile,'word;')
  697. else if current_level <= 32 then
  698. writeln(outfile,'longint;')
  699. else
  700. internalerror(11);
  701. is_sized:=false;
  702. end;
  703. write(outfile,aktspace,hp3^.p1^.p2^.p);
  704. write(outfile,' : ');
  705. shift(2);
  706. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  707. popshift;
  708. end;
  709. { size specifier or default value ? }
  710. if assigned(hp3^.p1^.p3) then
  711. begin
  712. { we could use mask to implement this }
  713. { because we need to respect the positions }
  714. if hp3^.p1^.p3^.typ = t_size_specifier then
  715. begin
  716. if not is_sized then
  717. begin
  718. current_power:=1;
  719. current_level:=0;
  720. inc(flag_index);
  721. write(outfile,aktspace,'flag',flag_index,' : ');
  722. end;
  723. must_write_packed_field:=true;
  724. is_sized:=true;
  725. { can it be something else than a constant ? }
  726. { it can be a macro !! }
  727. if hp3^.p1^.p3^.p1^.typ=t_id then
  728. begin
  729. val(hp3^.p1^.p3^.p1^.str,l,error);
  730. if error=0 then
  731. begin
  732. mask:=0;
  733. for i:=1 to l do
  734. begin
  735. mask:=mask+current_power;
  736. current_power:=current_power*2;
  737. end;
  738. write(tempfile,'bm_&',hp3^.p1^.p2^.p);
  739. writeln(tempfile,' = ',hexstr(mask),';');
  740. write(tempfile,'bp_&',hp3^.p1^.p2^.p);
  741. writeln(tempfile,' = ',current_level,';');
  742. current_level:=current_level + l;
  743. { go to next flag if 31 }
  744. if current_level = 32 then
  745. begin
  746. write(outfile,'longint');
  747. is_sized:=false;
  748. end;
  749. end;
  750. end;
  751. end
  752. else if hp3^.p1^.p3^.typ = t_default_value then
  753. begin
  754. write(outfile,'{=');
  755. write_expr(outfile,hp3^.p1^.p3^.p1);
  756. write(outfile,' ignored}');
  757. end;
  758. end;
  759. if not is_sized then
  760. begin
  761. if is_procvar then
  762. begin
  763. if not no_pop then
  764. begin
  765. write(outfile,';cdecl');
  766. no_pop:=true;
  767. end;
  768. is_procvar:=false;
  769. end;
  770. writeln(outfile,';');
  771. end;
  772. hp3:=hp3^.next;
  773. end;
  774. hp1:=hp1^.next;
  775. end;
  776. if is_sized then
  777. begin
  778. if current_level <= 16 then
  779. writeln(outfile,'word;')
  780. else if current_level <= 32 then
  781. writeln(outfile,'longint;')
  782. else
  783. internalerror(11);
  784. is_sized:=false;
  785. end;
  786. popshift;
  787. write(outfile,aktspace,'end');
  788. flush(outfile);
  789. end;
  790. dec(typedef_level);
  791. end;
  792. t_uniondef :
  793. begin
  794. if (typedef_level>1) and (p^.p1=nil) and
  795. (p^.p2^.typ=t_id) then
  796. begin
  797. write(outfile,p^.p2^.p);
  798. end
  799. else
  800. begin
  801. inc(typedef_level);
  802. writeln(outfile,'record');
  803. shift(2);
  804. writeln(outfile,aktspace,'case longint of');
  805. shift(3);
  806. l:=0;
  807. hp1:=p^.p1;
  808. (* walk through all members *)
  809. while assigned(hp1) do
  810. begin
  811. (* hp2 is t_memberdec *)
  812. hp2:=hp1^.p1;
  813. (* hp3 is t_declist *)
  814. hp3:=hp2^.p2;
  815. while assigned(hp3) do
  816. begin
  817. write(outfile,aktspace,l,' : ( ');
  818. write(outfile,hp3^.p1^.p2^.p,' : ');
  819. shift(2);
  820. write_p_a_def(outfile,hp3^.p1^.p1,hp2^.p1);
  821. popshift;
  822. writeln(outfile,' );');
  823. hp3:=hp3^.next;
  824. inc(l);
  825. end;
  826. hp1:=hp1^.next;
  827. end;
  828. popshift;
  829. write(outfile,aktspace,'end');
  830. popshift;
  831. flush(outfile);
  832. dec(typedef_level);
  833. end;
  834. end;
  835. else
  836. internalerror(3);
  837. end;
  838. end;
  839. procedure write_def_params(var outfile:text; p : presobject);
  840. var
  841. hp1 : presobject;
  842. begin
  843. case p^.typ of
  844. t_enumdef : begin
  845. hp1:=p^.p1;
  846. while assigned(hp1) do
  847. begin
  848. write(outfile,hp1^.p1^.p);
  849. hp1:=hp1^.next;
  850. if assigned(hp1) then
  851. write(outfile,',')
  852. else
  853. write(outfile);
  854. flush(outfile);
  855. end;
  856. flush(outfile);
  857. end;
  858. else internalerror(4);
  859. end;
  860. end;
  861. %}
  862. %token TYPEDEF DEFINE
  863. %token COLON SEMICOLON COMMA
  864. %token LKLAMMER RKLAMMER LECKKLAMMER RECKKLAMMER
  865. %token LGKLAMMER RGKLAMMER
  866. %token STRUCT UNION ENUM
  867. %token ID NUMBER CSTRING
  868. %token SHORT UNSIGNED LONG INT REAL _CHAR
  869. %token VOID _CONST
  870. %token _FAR _HUGE _NEAR
  871. %token _ASSIGN NEW_LINE SPACE_DEFINE
  872. %token EXTERN STDCALL CDECL CALLBACK PASCAL WINAPI APIENTRY WINGDIAPI SYS_TRAP
  873. %token _PACKED
  874. %token ELLIPSIS
  875. %right R_AND
  876. %left EQUAL UNEQUAL GT LT GTE LTE
  877. %left QUESTIONMARK COLON
  878. %left _OR
  879. %left _AND
  880. %left _PLUS MINUS
  881. %left _SHR _SHL
  882. %left STAR _SLASH
  883. %right _NOT
  884. %right LKLAMMER
  885. %right PSTAR
  886. %right P_AND
  887. %right LECKKLAMMER
  888. %left POINT DEREF
  889. %left COMMA
  890. %left STICK
  891. %%
  892. file : declaration_list
  893. ;
  894. error_info : {
  895. if not stripinfo then
  896. begin
  897. writeln(outfile,'(* error ');
  898. writeln(outfile,yyline);
  899. end;
  900. };
  901. declaration_list : declaration_list declaration
  902. { if yydebug then writeln('declaration reduced at line ',line_no);
  903. if yydebug then writeln(outfile,'(* declaration reduced *)');
  904. }
  905. | declaration_list define_dec
  906. { if yydebug then writeln('define declaration reduced at line ',line_no);
  907. if yydebug then writeln(outfile,'(* define declaration reduced *)');
  908. }
  909. | declaration
  910. { if yydebug then writeln('declaration reduced at line ',line_no);
  911. }
  912. | define_dec
  913. { if yydebug then writeln('define declaration reduced at line ',line_no);
  914. }
  915. ;
  916. dec_specifier :
  917. EXTERN { $$:=new(presobject,init_id('extern')); }
  918. |{ $$:=new(presobject,init_id('intern')); }
  919. ;
  920. dec_modifier :
  921. STDCALL { $$:=new(presobject,init_id('no_pop')); }
  922. | CDECL { $$:=new(presobject,init_id('cdecl')); }
  923. | CALLBACK { $$:=new(presobject,init_id('no_pop')); }
  924. | PASCAL { $$:=new(presobject,init_id('no_pop')); }
  925. | WINAPI { $$:=new(presobject,init_id('no_pop')); }
  926. | APIENTRY { $$:=new(presobject,init_id('no_pop')); }
  927. | WINGDIAPI { $$:=new(presobject,init_id('no_pop')); }
  928. | { $$:=nil }
  929. ;
  930. systrap_specifier:
  931. SYS_TRAP LKLAMMER dname RKLAMMER { $$:=$3; }
  932. | { $$:=nil; }
  933. ;
  934. declaration :
  935. dec_specifier type_specifier dec_modifier declarator_list systrap_specifier SEMICOLON
  936. { IsExtern:=false;
  937. (* by default we must pop the args pushed on stack *)
  938. no_pop:=false;
  939. (* writeln(outfile,'{ dec_specifier type_specifier declarator_list SEMICOLON}');
  940. if assigned($3) then writeln(outfile,'{*$3}');
  941. if assigned($3)and assigned($3.p1)
  942. then writeln(outfile,'{*$3^.p1}');
  943. if assigned($3)and assigned($3^.p1)and assigned($3^.p1^.p1)
  944. then writeln(outfile,'{*$3^.p1^.p1}');
  945. *)
  946. if (assigned($4)and assigned($4^.p1)and assigned($4^.p1^.p1))
  947. and ($4^.p1^.p1^.typ=t_procdef) then
  948. begin
  949. If UseLib then
  950. IsExtern:=true
  951. else
  952. IsExtern:=assigned($1)and($1^.str='extern');
  953. no_pop:=assigned($3) and ($3^.str='no_pop');
  954. if block_type<>bt_func then
  955. writeln(outfile);
  956. block_type:=bt_func;
  957. if not CompactMode then
  958. begin
  959. write(outfile,aktspace);
  960. if not IsExtern then
  961. write(extfile,aktspace);
  962. end;
  963. (* distinguish between procedure and function *)
  964. if assigned($2) then
  965. if ($2^.typ=t_void) and ($4^.p1^.p1^.p1=nil) then
  966. begin
  967. shift(10);
  968. write(outfile,'procedure ',$4^.p1^.p2^.p);
  969. if assigned($4^.p1^.p1^.p2) then
  970. write_args(outfile,$4^.p1^.p1^.p2);
  971. if not IsExtern then
  972. begin
  973. write(extfile,'procedure ',$4^.p1^.p2^.p);
  974. if assigned($4^.p1^.p1^.p2) then
  975. write_args(extfile,$4^.p1^.p1^.p2);
  976. end;
  977. end
  978. else
  979. begin
  980. shift(9);
  981. write(outfile,'function ',$4^.p1^.p2^.p);
  982. if assigned($4^.p1^.p1^.p2) then
  983. write_args(outfile,$4^.p1^.p1^.p2);
  984. write(outfile,':');
  985. write_p_a_def(outfile,$4^.p1^.p1^.p1,$2);
  986. if not IsExtern then
  987. begin
  988. write(extfile,'function ',$4^.p1^.p2^.p);
  989. if assigned($4^.p1^.p1^.p2) then
  990. write_args(extfile,$4^.p1^.p1^.p2);
  991. write(extfile,':');
  992. write_p_a_def(extfile,$4^.p1^.p1^.p1,$2);
  993. end;
  994. end;
  995. if assigned($5) then
  996. write(outfile,';systrap ',$5^.p);
  997. (* No CDECL in interface for Uselib *)
  998. if IsExtern and (not no_pop) then
  999. write(outfile,';cdecl');
  1000. popshift;
  1001. if UseLib then
  1002. begin
  1003. if IsExtern then
  1004. begin
  1005. write (outfile,';external');
  1006. If UseName then
  1007. Write(outfile,' External_library name ''',$4^.p1^.p2^.p,'''');
  1008. end;
  1009. writeln(outfile,';');
  1010. end
  1011. else
  1012. begin
  1013. writeln(extfile,';');
  1014. writeln(outfile,';');
  1015. if not IsExtern then
  1016. begin
  1017. writeln(extfile,aktspace,'begin');
  1018. writeln(extfile,aktspace,' { You must implemented this function }');
  1019. writeln(extfile,aktspace,'end;');
  1020. end;
  1021. end;
  1022. IsExtern:=false;
  1023. if not compactmode then
  1024. writeln(outfile);
  1025. end
  1026. else (* $4^.p1^.p1^.typ=t_procdef *)
  1027. if assigned($4)and assigned($4^.p1) then
  1028. begin
  1029. shift(2);
  1030. if block_type<>bt_var then
  1031. begin
  1032. if not(compactmode) then
  1033. writeln(outfile);
  1034. writeln(outfile,aktspace,'var');
  1035. end;
  1036. block_type:=bt_var;
  1037. shift(3);
  1038. IsExtern:=assigned($1)and($1^.str='extern');
  1039. (* walk through all declarations *)
  1040. hp:=$4;
  1041. while assigned(hp) and assigned(hp^.p1) do
  1042. begin
  1043. (* write new var name *)
  1044. if assigned(hp^.p1^.p2)and assigned(hp^.p1^.p2^.p)then
  1045. write(outfile,aktspace,hp^.p1^.p2^.p);
  1046. write(outfile,' : ');
  1047. shift(2);
  1048. (* write its type *)
  1049. write_p_a_def(outfile,hp^.p1^.p1,$2);
  1050. if assigned(hp^.p1^.p2)and assigned(hp^.p1^.p2^.p)then
  1051. begin
  1052. if isExtern then
  1053. write(outfile,';cvar;external ''')
  1054. else
  1055. write(outfile,';cvar;export ''');
  1056. write(outfile,hp^.p1^.p2^.p);
  1057. end;
  1058. writeln(outfile,''';');
  1059. popshift;
  1060. hp:=hp^.p2;
  1061. end;
  1062. popshift;
  1063. popshift;
  1064. end;
  1065. if assigned($1)then dispose($1,done);
  1066. if assigned($2)then dispose($2,done);
  1067. if assigned($4)then dispose($4,done);
  1068. } |
  1069. special_type_specifier SEMICOLON
  1070. {
  1071. if block_type<>bt_type then
  1072. begin
  1073. if not(compactmode) then
  1074. writeln(outfile);
  1075. writeln(outfile,aktspace,'type');
  1076. block_type:=bt_type;
  1077. end;
  1078. shift(3);
  1079. (* write new type name *)
  1080. TN:=strpas($1^.p2^.p);
  1081. if RemoveUnderScore and (length(tn)>1) and (tn[1]='_') then
  1082. Delete(TN,1,1);
  1083. if UsePPointers and
  1084. (($1^.typ=t_structdef) or ($1^.typ=t_uniondef)) then
  1085. begin
  1086. PN:='P'+TN;
  1087. if PrependTypes then
  1088. TN:='T'+TN;
  1089. Writeln (outfile,aktspace,PN,' = ^',TN,';');
  1090. end;
  1091. write(outfile,aktspace,TN,' = ');
  1092. shift(2);
  1093. hp:=$1;
  1094. write_type_specifier(outfile,hp);
  1095. popshift;
  1096. (* enum_to_const can make a switch to const *)
  1097. if block_type=bt_type then
  1098. writeln(outfile,';');
  1099. writeln(outfile);
  1100. flush(outfile);
  1101. popshift;
  1102. if must_write_packed_field then
  1103. write_packed_fields_info(outfile,hp,TN);
  1104. if assigned(hp) then
  1105. dispose(hp,done);
  1106. } |
  1107. TYPEDEF STRUCT dname dname SEMICOLON
  1108. {
  1109. if block_type<>bt_type then
  1110. begin
  1111. if not(compactmode) then
  1112. writeln(outfile);
  1113. writeln(outfile,aktspace,'type');
  1114. block_type:=bt_type;
  1115. end;
  1116. PN:=$3^.p;
  1117. TN:=$4^.p;
  1118. if RemoveUnderscore then
  1119. begin
  1120. if (length(pn)>1) and (PN[1]='_') then
  1121. Delete(Pn,1,1);
  1122. if (length(tn)>1) and (tN[1]='_') then
  1123. Delete(tn,1,1);
  1124. end;
  1125. if Uppercase(tn)<>Uppercase(pn) then
  1126. begin
  1127. shift(3);
  1128. writeln(outfile,aktspace,PN,' = ',TN,';');
  1129. popshift;
  1130. end;
  1131. if assigned($3) then
  1132. dispose($3,done);
  1133. if assigned($4) then
  1134. dispose($4,done);
  1135. } |
  1136. TYPEDEF type_specifier LKLAMMER dec_modifier declarator RKLAMMER LKLAMMER argument_declaration_list RKLAMMER
  1137. {
  1138. if block_type<>bt_type then
  1139. begin
  1140. if not(compactmode) then
  1141. writeln(outfile);
  1142. writeln(outfile,aktspace,'type');
  1143. block_type:=bt_type;
  1144. end;
  1145. no_pop:=assigned($4) and ($4^.str='no_pop');
  1146. shift(3);
  1147. (* walk through all declarations *)
  1148. hp:=$5;
  1149. ph:=nil;
  1150. if assigned(hp) then
  1151. begin
  1152. hp:=$8;
  1153. while assigned(hp^.p1) do
  1154. hp:=hp^.p1;
  1155. hp^.p1:=new(presobject,init_two(t_procdef,nil,$8));
  1156. hp:=$5;
  1157. if assigned(hp^.p1) and assigned(hp^.p1^.p2) then
  1158. begin
  1159. writeln(outfile);
  1160. (* write new type name *)
  1161. write(outfile,aktspace,hp^.p1^.p2^.p);
  1162. write(outfile,' = ');
  1163. shift(2);
  1164. if assigned(ph) then
  1165. write_p_a_def(outfile,hp^.p1^.p1,ph)
  1166. else
  1167. write_p_a_def(outfile,hp^.p1^.p1,$2);
  1168. (* simple def ? keep the name for the other defs *)
  1169. if (ph=nil) and (hp^.p1^.p1=nil) then
  1170. ph:=hp^.p1^.p2;
  1171. popshift;
  1172. (* if no_pop it is normal fpc calling convention *)
  1173. if is_procvar and
  1174. (not no_pop) then
  1175. write(outfile,';cdecl');
  1176. writeln(outfile,';');
  1177. flush(outfile);
  1178. end;
  1179. end;
  1180. popshift;
  1181. if assigned($2)then
  1182. dispose($2,done);
  1183. if assigned($4)then
  1184. dispose($4,done);
  1185. if assigned($5)then (* disposes also $8 *)
  1186. dispose($5,done);
  1187. } |
  1188. TYPEDEF type_specifier dec_modifier declarator_list SEMICOLON
  1189. {
  1190. if block_type<>bt_type then
  1191. begin
  1192. if not(compactmode) then
  1193. writeln(outfile);
  1194. writeln(outfile,aktspace,'type');
  1195. block_type:=bt_type;
  1196. end;
  1197. no_pop:=assigned($3) and ($3^.str='no_pop');
  1198. shift(3);
  1199. (* walk through all declarations *)
  1200. hp:=$4;
  1201. ph:=nil;
  1202. is_procvar:=false;
  1203. while assigned(hp) do
  1204. begin
  1205. if assigned(hp^.p1) and assigned(hp^.p1^.p2) then
  1206. begin
  1207. writeln(outfile);
  1208. (* write new type name *)
  1209. write(outfile,aktspace,hp^.p1^.p2^.p);
  1210. write(outfile,' = ');
  1211. shift(2);
  1212. if assigned(ph) then
  1213. write_p_a_def(outfile,hp^.p1^.p1,ph)
  1214. else
  1215. write_p_a_def(outfile,hp^.p1^.p1,$2);
  1216. (* simple def ? keep the name for the other defs *)
  1217. if (ph=nil) and (hp^.p1^.p1=nil) then
  1218. ph:=hp^.p1^.p2;
  1219. popshift;
  1220. (* if no_pop it is normal fpc calling convention *)
  1221. if is_procvar and
  1222. (not no_pop) then
  1223. write(outfile,';cdecl');
  1224. writeln(outfile,';');
  1225. flush(outfile);
  1226. end;
  1227. hp:=hp^.next;
  1228. end;
  1229. (* write tag name *)
  1230. if assigned(ph) and
  1231. (($2^.typ=t_structdef) or
  1232. ($2^.typ=t_enumdef) or
  1233. ($2^.typ=t_uniondef)) and
  1234. assigned($2^.p2) then
  1235. begin
  1236. writeln(outfile);
  1237. write(outfile,aktspace,$2^.p2^.p,' = ');
  1238. if assigned(ph) then
  1239. writeln(outfile,ph^.p,';')
  1240. else
  1241. begin
  1242. write_p_a_def(outfile,hp^.p1^.p1,$2);
  1243. writeln(outfile,';');
  1244. end;
  1245. end;
  1246. popshift;
  1247. if must_write_packed_field then
  1248. if assigned(ph) then
  1249. write_packed_fields_info(outfile,$2,ph^.str)
  1250. else if assigned($2^.p2) then
  1251. write_packed_fields_info(outfile,$2,$2^.p2^.str);
  1252. if assigned($2)then
  1253. dispose($2,done);
  1254. if assigned($3)then
  1255. dispose($3,done);
  1256. if assigned($4)then
  1257. dispose($4,done);
  1258. } |
  1259. TYPEDEF dname SEMICOLON
  1260. {
  1261. if block_type<>bt_type then
  1262. begin
  1263. if not(compactmode) then
  1264. writeln(outfile);
  1265. writeln(outfile,aktspace,'type');
  1266. block_type:=bt_type;
  1267. end;
  1268. shift(3);
  1269. (* write as pointer *)
  1270. writeln(outfile);
  1271. writeln(outfile,'(* generic typedef *)');
  1272. writeln(outfile,aktspace,$2^.p,' = pointer;');
  1273. flush(outfile);
  1274. popshift;
  1275. if assigned($2) then
  1276. dispose($2,done);
  1277. }
  1278. | error error_info SEMICOLON
  1279. { writeln(outfile,'in declaration at line ',line_no,' *)');
  1280. aktspace:='';
  1281. in_space_define:=0;
  1282. in_define:=false;
  1283. arglevel:=0;
  1284. if_nb:=0;
  1285. aktspace:=' ';
  1286. space_index:=1;
  1287. yyerrok;}
  1288. ;
  1289. define_dec :
  1290. DEFINE dname LKLAMMER enum_list RKLAMMER SPACE_DEFINE def_expr NEW_LINE
  1291. {
  1292. writeln (outfile,aktspace,'{ was #define dname(params) def_expr }');
  1293. writeln (extfile,aktspace,'{ was #define dname(params) def_expr }');
  1294. if assigned($4) then
  1295. begin
  1296. writeln (outfile,aktspace,'{ argument types are unknown }');
  1297. writeln (extfile,aktspace,'{ argument types are unknown }');
  1298. end;
  1299. if not assigned($7^.p3) then
  1300. begin
  1301. writeln(outfile,aktspace,'{ return type might be wrong } ');
  1302. writeln(extfile,aktspace,'{ return type might be wrong } ');
  1303. end;
  1304. block_type:=bt_func;
  1305. write(outfile,aktspace,'function ',$2^.p);
  1306. write(extfile,aktspace,'function ',$2^.p);
  1307. if assigned($4) then
  1308. begin
  1309. write(outfile,'(');
  1310. write(extfile,'(');
  1311. ph:=new(presobject,init_one(t_enumdef,$4));
  1312. write_def_params(outfile,ph);
  1313. write_def_params(extfile,ph);
  1314. if assigned(ph) then dispose(ph,done);
  1315. ph:=nil;
  1316. (* types are unknown *)
  1317. write(outfile,' : longint)');
  1318. write(extfile,' : longint)');
  1319. end;
  1320. if not assigned($7^.p3) then
  1321. begin
  1322. writeln(outfile,' : longint;');
  1323. writeln(outfile,aktspace,' { return type might be wrong } ');
  1324. flush(outfile);
  1325. writeln(extfile,' : longint;');
  1326. writeln(extfile,aktspace,' { return type might be wrong } ');
  1327. end
  1328. else
  1329. begin
  1330. write(outfile,' : ');
  1331. write_type_specifier(outfile,$7^.p3);
  1332. writeln(outfile,';');
  1333. flush(outfile);
  1334. write(extfile,' : ');
  1335. write_type_specifier(extfile,$7^.p3);
  1336. writeln(extfile,';');
  1337. end;
  1338. writeln(outfile);
  1339. flush(outfile);
  1340. hp:=new(presobject,init_two(t_funcname,$2,$7));
  1341. write_funexpr(extfile,hp);
  1342. writeln(extfile);
  1343. flush(extfile);
  1344. if assigned(hp)then dispose(hp,done);
  1345. }|
  1346. DEFINE dname SPACE_DEFINE NEW_LINE
  1347. {
  1348. writeln(outfile,'{$define ',$2^.p,'}');
  1349. flush(outfile);
  1350. if assigned($2)then
  1351. dispose($2,done);
  1352. }|
  1353. DEFINE dname NEW_LINE
  1354. {
  1355. writeln(outfile,'{$define ',$2^.p,'}');
  1356. flush(outfile);
  1357. if assigned($2)then
  1358. dispose($2,done);
  1359. } |
  1360. DEFINE dname SPACE_DEFINE def_expr NEW_LINE
  1361. {
  1362. if ($4^.typ=t_exprlist) and
  1363. $4^.p1^.is_const and
  1364. not assigned($4^.next) then
  1365. begin
  1366. if block_type<>bt_const then
  1367. begin
  1368. writeln(outfile);
  1369. writeln(outfile,aktspace,'const');
  1370. end;
  1371. block_type:=bt_const;
  1372. aktspace:=aktspace+' ';
  1373. write(outfile,aktspace,$2^.p);
  1374. write(outfile,' = ');
  1375. flush(outfile);
  1376. write_expr(outfile,$4^.p1);
  1377. writeln(outfile,';');
  1378. dec(byte(aktspace[0]),3);
  1379. if assigned($2) then
  1380. dispose($2,done);
  1381. if assigned($4) then
  1382. dispose($4,done);
  1383. end
  1384. else
  1385. begin
  1386. aktspace:=aktspace+' ';
  1387. writeln (outfile,aktspace,'{ was #define dname def_expr }');
  1388. writeln (extfile,aktspace,'{ was #define dname def_expr }');
  1389. block_type:=bt_func;
  1390. write(outfile,aktspace,'function ',$2^.p);
  1391. write(extfile,aktspace,'function ',$2^.p);
  1392. if not assigned($4^.p3) then
  1393. begin
  1394. writeln(outfile,' : longint;');
  1395. writeln(outfile,aktspace,' { return type might be wrong }');
  1396. flush(outfile);
  1397. writeln(extfile,' : longint;');
  1398. writeln(extfile,aktspace,' { return type might be wrong }');
  1399. end
  1400. else
  1401. begin
  1402. write(outfile,' : ');
  1403. write_type_specifier(outfile,$4^.p3);
  1404. writeln(outfile,';');
  1405. flush(outfile);
  1406. write(extfile,' : ');
  1407. write_type_specifier(extfile,$4^.p3);
  1408. writeln(extfile,';');
  1409. end;
  1410. writeln(outfile);
  1411. flush(outfile);
  1412. hp:=new(presobject,init_two(t_funcname,$2,$4));
  1413. write_funexpr(extfile,hp);
  1414. dec(byte(aktspace[0]),2);
  1415. dispose(hp,done);
  1416. writeln(extfile);
  1417. flush(extfile);
  1418. end;
  1419. }
  1420. | error error_info NEW_LINE
  1421. { writeln(outfile,'in define line ',line_no,' *)');
  1422. aktspace:='';
  1423. in_space_define:=0;
  1424. in_define:=false;
  1425. arglevel:=0;
  1426. if_nb:=0;
  1427. aktspace:=' ';
  1428. space_index:=1;
  1429. yyerrok;}
  1430. ;
  1431. closed_list : LGKLAMMER member_list RGKLAMMER
  1432. {$$:=$2;} |
  1433. error error_info RGKLAMMER
  1434. { writeln(outfile,' in member_list *)');
  1435. yyerrok;
  1436. $$:=nil;
  1437. }
  1438. ;
  1439. closed_enum_list : LGKLAMMER enum_list RGKLAMMER
  1440. {$$:=$2;} |
  1441. error error_info RGKLAMMER
  1442. { writeln(outfile,' in enum_list *)');
  1443. yyerrok;
  1444. $$:=nil;
  1445. }
  1446. ;
  1447. special_type_specifier :
  1448. STRUCT dname closed_list _PACKED
  1449. {
  1450. if not is_packed then
  1451. writeln(outfile,'{$PACKRECORDS 1}');
  1452. is_packed:=true;
  1453. $$:=new(presobject,init_two(t_structdef,$3,$2));
  1454. } |
  1455. STRUCT dname closed_list
  1456. {
  1457. if is_packed then
  1458. writeln(outfile,'{$PACKRECORDS 4}');
  1459. is_packed:=false;
  1460. $$:=new(presobject,init_two(t_structdef,$3,$2));
  1461. } |
  1462. UNION dname closed_list _PACKED
  1463. {
  1464. if not is_packed then
  1465. writeln(outfile,'{$PACKRECORDS 1}');
  1466. is_packed:=true;
  1467. $$:=new(presobject,init_two(t_uniondef,$3,$2));
  1468. } |
  1469. UNION dname closed_list
  1470. {
  1471. $$:=new(presobject,init_two(t_uniondef,$3,$2));
  1472. } |
  1473. UNION dname
  1474. {
  1475. $$:=new(presobject,init_two(t_uniondef,nil,$2));
  1476. } |
  1477. STRUCT dname
  1478. {
  1479. $$:=new(presobject,init_two(t_structdef,nil,$2));
  1480. } |
  1481. ENUM dname closed_enum_list
  1482. {
  1483. $$:=new(presobject,init_two(t_enumdef,$3,$2));
  1484. } |
  1485. ENUM dname
  1486. {
  1487. $$:=new(presobject,init_two(t_enumdef,nil,$2));
  1488. };
  1489. type_specifier :
  1490. _CONST type_specifier
  1491. {
  1492. if not stripinfo then
  1493. writeln(outfile,'(* Const before type ignored *)');
  1494. $$:=$2;
  1495. } |
  1496. UNION closed_list _PACKED
  1497. {
  1498. if not is_packed then
  1499. writeln(outfile,'{$PACKRECORDS 1}');
  1500. is_packed:=true;
  1501. $$:=new(presobject,init_one(t_uniondef,$2));
  1502. } |
  1503. UNION closed_list
  1504. {
  1505. $$:=new(presobject,init_one(t_uniondef,$2));
  1506. } |
  1507. STRUCT closed_list _PACKED
  1508. {
  1509. if not is_packed then
  1510. writeln(outfile,'{$PACKRECORDS 1}');
  1511. is_packed:=true;
  1512. $$:=new(presobject,init_one(t_structdef,$2));
  1513. } |
  1514. STRUCT closed_list
  1515. {
  1516. if is_packed then
  1517. writeln(outfile,'{$PACKRECORDS 4}');
  1518. is_packed:=false;
  1519. $$:=new(presobject,init_one(t_structdef,$2));
  1520. } |
  1521. ENUM closed_enum_list
  1522. {
  1523. $$:=new(presobject,init_one(t_enumdef,$2));
  1524. } |
  1525. special_type_specifier
  1526. {
  1527. $$:=$1;
  1528. } |
  1529. simple_type_name { $$:=$1; }
  1530. ;
  1531. member_list : member_declaration member_list
  1532. {
  1533. $$:=new(presobject,init_one(t_memberdeclist,$1));
  1534. $$^.next:=$2;
  1535. } |
  1536. member_declaration
  1537. {
  1538. $$:=new(presobject,init_one(t_memberdeclist,$1));
  1539. }
  1540. ;
  1541. member_declaration :
  1542. type_specifier declarator_list SEMICOLON
  1543. {
  1544. $$:=new(presobject,init_two(t_memberdec,$1,$2));
  1545. }
  1546. ;
  1547. dname : ID { (*dname*)
  1548. $$:=new(presobject,init_id(act_token));
  1549. }
  1550. ;
  1551. special_type_name : INT
  1552. {
  1553. $$:=new(presobject,init_id(INT_STR));
  1554. } |
  1555. UNSIGNED INT
  1556. {
  1557. $$:=new(presobject,init_id(UINT_STR));
  1558. } |
  1559. LONG
  1560. {
  1561. $$:=new(presobject,init_id(INT_STR));
  1562. } |
  1563. REAL
  1564. {
  1565. $$:=new(presobject,init_id(REAL_STR));
  1566. } |
  1567. LONG INT
  1568. {
  1569. $$:=new(presobject,init_id(INT_STR));
  1570. } |
  1571. LONG LONG INT
  1572. {
  1573. $$:=new(presobject,init_id(INT64_STR));
  1574. } |
  1575. UNSIGNED LONG LONG INT
  1576. {
  1577. $$:=new(presobject,init_id(QWORD_STR));
  1578. } |
  1579. LONG LONG
  1580. {
  1581. $$:=new(presobject,init_id(INT64_STR));
  1582. } |
  1583. UNSIGNED LONG LONG
  1584. {
  1585. $$:=new(presobject,init_id(QWORD_STR));
  1586. } |
  1587. UNSIGNED LONG INT
  1588. {
  1589. $$:=new(presobject,init_id(UINT_STR));
  1590. } |
  1591. UNSIGNED LONG
  1592. {
  1593. $$:=new(presobject,init_id(UINT_STR));
  1594. } |
  1595. UNSIGNED
  1596. {
  1597. $$:=new(presobject,init_id(UINT_STR));
  1598. } |
  1599. UNSIGNED SHORT
  1600. {
  1601. $$:=new(presobject,init_id(USHORT_STR));
  1602. } |
  1603. UNSIGNED _CHAR
  1604. {
  1605. $$:=new(presobject,init_id(UCHAR_STR));
  1606. } |
  1607. VOID
  1608. {
  1609. $$:=new(presobject,init_no(t_void));
  1610. } |
  1611. SHORT
  1612. {
  1613. $$:=new(presobject,init_id(SHORT_STR));
  1614. } |
  1615. _CHAR
  1616. {
  1617. $$:=new(presobject,init_id(CHAR_STR));
  1618. }
  1619. ;
  1620. simple_type_name :
  1621. special_type_name
  1622. {
  1623. $$:=$1;
  1624. }
  1625. |
  1626. dname
  1627. {
  1628. $$:=$1;
  1629. tn:=$$^.str;
  1630. if removeunderscore and
  1631. (length(tn)>1) and (tn[1]='_') then
  1632. $$^.setstr(Copy(tn,2,length(tn)-1));
  1633. }
  1634. ;
  1635. declarator_list :
  1636. declarator_list COMMA declarator
  1637. {
  1638. $$:=$1;
  1639. hp:=$1;
  1640. while assigned(hp^.next) do
  1641. hp:=hp^.next;
  1642. hp^.next:=new(presobject,init_one(t_declist,$3));
  1643. }|
  1644. error error_info COMMA declarator_list
  1645. {
  1646. writeln(outfile,' in declarator_list *)');
  1647. $$:=$4;
  1648. yyerrok;
  1649. }|
  1650. error error_info
  1651. {
  1652. writeln(outfile,' in declarator_list *)');
  1653. yyerrok;
  1654. }|
  1655. declarator
  1656. {
  1657. $$:=new(presobject,init_one(t_declist,$1));
  1658. }
  1659. ;
  1660. argument_declaration : type_specifier declarator
  1661. {
  1662. $$:=new(presobject,init_two(t_arg,$1,$2));
  1663. } |
  1664. type_specifier STAR declarator
  1665. {
  1666. hp:=new(presobject,init_one(t_pointerdef,$1));
  1667. $$:=new(presobject,init_two(t_arg,hp,$3));
  1668. } |
  1669. type_specifier abstract_declarator
  1670. {
  1671. $$:=new(presobject,init_two(t_arg,$1,$2));
  1672. }
  1673. ;
  1674. argument_declaration_list : argument_declaration
  1675. {
  1676. $$:=new(presobject,init_two(t_arglist,$1,nil));
  1677. } |
  1678. argument_declaration COMMA argument_declaration_list
  1679. {
  1680. $$:=new(presobject,init_two(t_arglist,$1,nil));
  1681. $$^.next:=$3;
  1682. } |
  1683. ELLIPSIS
  1684. {
  1685. $$:=new(presobject,init_two(t_arglist,ellipsisarg,nil));
  1686. (*** ELLIPSIS PROBLEM ***)
  1687. }
  1688. ;
  1689. size_overrider :
  1690. _FAR
  1691. { $$:=new(presobject,init_id('far'));}
  1692. | _NEAR
  1693. { $$:=new(presobject,init_id('near'));}
  1694. | _HUGE
  1695. { $$:=new(presobject,init_id('huge'));}
  1696. ;
  1697. declarator :
  1698. _CONST declarator
  1699. {
  1700. if not stripinfo then
  1701. writeln(outfile,'(* Const before declarator ignored *)');
  1702. $$:=$2;
  1703. } |
  1704. size_overrider STAR declarator
  1705. {
  1706. if not stripinfo then
  1707. writeln(outfile,aktspace,'(* ',$1^.p,' ignored *)');
  1708. dispose($1,done);
  1709. hp:=$3;
  1710. $$:=hp;
  1711. while assigned(hp^.p1) do
  1712. hp:=hp^.p1;
  1713. hp^.p1:=new(presobject,init_one(t_pointerdef,nil));
  1714. } |
  1715. STAR declarator
  1716. {
  1717. (* %prec PSTAR this was wrong!! *)
  1718. hp:=$2;
  1719. $$:=hp;
  1720. while assigned(hp^.p1) do
  1721. hp:=hp^.p1;
  1722. hp^.p1:=new(presobject,init_one(t_pointerdef,nil));
  1723. } |
  1724. _AND declarator %prec P_AND
  1725. {
  1726. hp:=$2;
  1727. $$:=hp;
  1728. while assigned(hp^.p1) do
  1729. hp:=hp^.p1;
  1730. hp^.p1:=new(presobject,init_one(t_addrdef,nil));
  1731. } |
  1732. dname COLON expr
  1733. {
  1734. (* size specifier supported *)
  1735. hp:=new(presobject,init_one(t_size_specifier,$3));
  1736. $$:=new(presobject,init_three(t_dec,nil,$1,hp));
  1737. }|
  1738. dname ASSIGN expr
  1739. {
  1740. if not stripinfo then
  1741. writeln(outfile,'(* Warning : default value for ',$1^.p,' ignored *)');
  1742. hp:=new(presobject,init_one(t_default_value,$3));
  1743. $$:=new(presobject,init_three(t_dec,nil,$1,hp));
  1744. }|
  1745. dname
  1746. {
  1747. $$:=new(presobject,init_two(t_dec,nil,$1));
  1748. }|
  1749. declarator LKLAMMER argument_declaration_list RKLAMMER
  1750. {
  1751. hp:=$1;
  1752. $$:=hp;
  1753. while assigned(hp^.p1) do
  1754. hp:=hp^.p1;
  1755. hp^.p1:=new(presobject,init_two(t_procdef,nil,$3));
  1756. } |
  1757. declarator no_arg
  1758. {
  1759. hp:=$1;
  1760. $$:=hp;
  1761. while assigned(hp^.p1) do
  1762. hp:=hp^.p1;
  1763. hp^.p1:=new(presobject,init_two(t_procdef,nil,nil));
  1764. } |
  1765. declarator LECKKLAMMER expr RECKKLAMMER
  1766. {
  1767. hp:=$1;
  1768. $$:=hp;
  1769. while assigned(hp^.p1) do
  1770. hp:=hp^.p1;
  1771. hp^.p1:=new(presobject,init_two(t_arraydef,nil,$3));
  1772. } |
  1773. LKLAMMER declarator RKLAMMER { $$:=$2; }
  1774. ;
  1775. no_arg : LKLAMMER RKLAMMER |
  1776. LKLAMMER VOID RKLAMMER;
  1777. abstract_declarator :
  1778. _CONST abstract_declarator
  1779. {
  1780. if not stripinfo then
  1781. writeln(outfile,'(* Const before abstract_declarator ignored *)');
  1782. $$:=$2;
  1783. } |
  1784. size_overrider STAR abstract_declarator
  1785. {
  1786. if not stripinfo then
  1787. writeln(outfile,aktspace,'(* ',$1^.p,' ignored *)');
  1788. dispose($1,done);
  1789. hp:=$3;
  1790. $$:=hp;
  1791. while assigned(hp^.p1) do
  1792. hp:=hp^.p1;
  1793. hp^.p1:=new(presobject,init_one(t_pointerdef,nil));
  1794. } |
  1795. STAR abstract_declarator %prec PSTAR
  1796. {
  1797. hp:=$2;
  1798. $$:=hp;
  1799. while assigned(hp^.p1) do
  1800. hp:=hp^.p1;
  1801. hp^.p1:=new(presobject,init_one(t_pointerdef,nil));
  1802. } |
  1803. abstract_declarator LKLAMMER argument_declaration_list RKLAMMER
  1804. {
  1805. hp:=$1;
  1806. $$:=hp;
  1807. while assigned(hp^.p1) do
  1808. hp:=hp^.p1;
  1809. hp^.p1:=new(presobject,init_two(t_procdef,nil,$3));
  1810. } |
  1811. abstract_declarator no_arg
  1812. {
  1813. hp:=$1;
  1814. $$:=hp;
  1815. while assigned(hp^.p1) do
  1816. hp:=hp^.p1;
  1817. hp^.p1:=new(presobject,init_two(t_procdef,nil,nil));
  1818. } |
  1819. abstract_declarator LECKKLAMMER expr RECKKLAMMER
  1820. {
  1821. hp:=$1;
  1822. $$:=hp;
  1823. while assigned(hp^.p1) do
  1824. hp:=hp^.p1;
  1825. hp^.p1:=new(presobject,init_two(t_arraydef,nil,$3));
  1826. } |
  1827. LKLAMMER abstract_declarator RKLAMMER
  1828. { $$:=$2; } |
  1829. {
  1830. $$:=new(presobject,init_two(t_dec,nil,nil));
  1831. }
  1832. ;
  1833. expr :
  1834. shift_expr
  1835. {$$:=$1;}
  1836. ;
  1837. shift_expr :
  1838. expr EQUAL expr
  1839. { $$:=new(presobject,init_bop(' = ',$1,$3));}
  1840. | expr UNEQUAL expr
  1841. { $$:=new(presobject,init_bop(' <> ',$1,$3));}
  1842. | expr GT expr
  1843. { $$:=new(presobject,init_bop(' > ',$1,$3));}
  1844. | expr GTE expr
  1845. { $$:=new(presobject,init_bop(' >= ',$1,$3));}
  1846. | expr LT expr
  1847. { $$:=new(presobject,init_bop(' < ',$1,$3));}
  1848. | expr LTE expr
  1849. { $$:=new(presobject,init_bop(' <= ',$1,$3));}
  1850. | expr _PLUS expr
  1851. { $$:=new(presobject,init_bop(' + ',$1,$3));}
  1852. | expr MINUS expr
  1853. { $$:=new(presobject,init_bop(' - ',$1,$3));}
  1854. | expr STAR expr
  1855. { $$:=new(presobject,init_bop(' * ',$1,$3));}
  1856. | expr _SLASH expr
  1857. { $$:=new(presobject,init_bop(' / ',$1,$3));}
  1858. | expr _OR expr
  1859. { $$:=new(presobject,init_bop(' or ',$1,$3));}
  1860. | expr _AND expr
  1861. { $$:=new(presobject,init_bop(' and ',$1,$3));}
  1862. | expr _NOT expr
  1863. { $$:=new(presobject,init_bop(' not ',$1,$3));}
  1864. | expr _SHL expr
  1865. { $$:=new(presobject,init_bop(' shl ',$1,$3));}
  1866. | expr _SHR expr
  1867. { $$:=new(presobject,init_bop(' shr ',$1,$3));}
  1868. | expr QUESTIONMARK colon_expr
  1869. { $3^.p1:=$1;
  1870. $$:=$3;
  1871. inc(if_nb);
  1872. $$^.p:=strpnew('if_local'+str(if_nb));
  1873. } |
  1874. unary_expr {$$:=$1;}
  1875. ;
  1876. colon_expr : expr COLON expr
  1877. { (* if A then B else C *)
  1878. $$:=new(presobject,init_three(t_ifexpr,nil,$1,$3));}
  1879. ;
  1880. maybe_empty_unary_expr :
  1881. unary_expr
  1882. { $$:=$1; }
  1883. |
  1884. { $$:=nil;}
  1885. ;
  1886. unary_expr:
  1887. dname
  1888. {
  1889. $$:=$1;
  1890. } |
  1891. CSTRING
  1892. {
  1893. (* remove L prefix for widestrings *)
  1894. s:=act_token;
  1895. if Win32headers and (s[1]='L') then
  1896. delete(s,1,1);
  1897. $$:=new(presobject,init_id(''''+copy(s,2,length(s)-2)+''''));
  1898. } |
  1899. NUMBER
  1900. {
  1901. $$:=new(presobject,init_id(act_token));
  1902. } |
  1903. unary_expr POINT expr
  1904. {
  1905. $$:=new(presobject,init_bop('.',$1,$3));
  1906. } |
  1907. unary_expr DEREF expr
  1908. {
  1909. $$:=new(presobject,init_bop('^.',$1,$3));
  1910. } |
  1911. MINUS unary_expr
  1912. {
  1913. $$:=new(presobject,init_preop('-',$2));
  1914. }|
  1915. _AND unary_expr %prec R_AND
  1916. {
  1917. $$:=new(presobject,init_preop('@',$2));
  1918. }|
  1919. _NOT unary_expr
  1920. {
  1921. $$:=new(presobject,init_preop(' not ',$2));
  1922. } |
  1923. LKLAMMER dname RKLAMMER maybe_empty_unary_expr
  1924. {
  1925. if assigned($4) then
  1926. $$:=new(presobject,init_two(t_typespec,$2,$4))
  1927. else
  1928. $$:=$2;
  1929. } |
  1930. LKLAMMER type_specifier RKLAMMER unary_expr
  1931. {
  1932. $$:=new(presobject,init_two(t_typespec,$2,$4));
  1933. } |
  1934. LKLAMMER type_specifier STAR RKLAMMER unary_expr
  1935. {
  1936. hp:=new(presobject,init_one(t_pointerdef,$2));
  1937. $$:=new(presobject,init_two(t_typespec,hp,$5));
  1938. } |
  1939. LKLAMMER type_specifier size_overrider STAR RKLAMMER unary_expr
  1940. {
  1941. if not stripinfo then
  1942. writeln(outfile,aktspace,'(* ',$3^.p,' ignored *)');
  1943. dispose($3,done);
  1944. write_type_specifier(outfile,$2);
  1945. writeln(outfile,' ignored *)');
  1946. hp:=new(presobject,init_one(t_pointerdef,$2));
  1947. $$:=new(presobject,init_two(t_typespec,hp,$6));
  1948. } |
  1949. dname LKLAMMER exprlist RKLAMMER
  1950. {
  1951. hp:=new(presobject,init_one(t_exprlist,$1));
  1952. $$:=new(presobject,init_three(t_funexprlist,hp,$3,nil));
  1953. } |
  1954. LKLAMMER shift_expr RKLAMMER
  1955. {
  1956. $$:=$2;
  1957. }
  1958. ;
  1959. enum_list :
  1960. enum_element COMMA enum_list
  1961. { (*enum_element COMMA enum_list *)
  1962. $$:=$1;
  1963. $$^.next:=$3;
  1964. } |
  1965. enum_element {
  1966. $$:=$1;
  1967. } |
  1968. {(* empty enum list *)
  1969. $$:=nil;};
  1970. enum_element :
  1971. dname _ASSIGN expr
  1972. { begin (*enum_element: dname _ASSIGN expr *)
  1973. $$:=new(presobject,init_two(t_enumlist,$1,$3));
  1974. end;
  1975. } |
  1976. dname
  1977. {
  1978. begin (*enum_element: dname*)
  1979. $$:=new(presobject,init_two(t_enumlist,$1,nil));
  1980. end;
  1981. };
  1982. def_expr : unary_expr
  1983. {
  1984. if $1^.typ=t_funexprlist then
  1985. $$:=$1
  1986. else
  1987. $$:=new(presobject,init_two(t_exprlist,$1,nil));
  1988. (* if here is a type specifier
  1989. we know the return type *)
  1990. if ($1^.typ=t_typespec) then
  1991. $$^.p3:=$1^.p1^.get_copy;
  1992. }
  1993. ;
  1994. exprlist : exprelem COMMA exprlist
  1995. { (*exprlist COMMA expr*)
  1996. $$:=$1;
  1997. $1^.next:=$3;
  1998. } |
  1999. exprelem
  2000. {
  2001. $$:=$1;
  2002. } |
  2003. { (* empty expression list *)
  2004. $$:=nil; };
  2005. exprelem :
  2006. expr
  2007. {
  2008. $$:=new(presobject,init_one(t_exprlist,$1));
  2009. };
  2010. %%
  2011. function yylex : Integer;
  2012. begin
  2013. yylex:=scan.yylex;
  2014. line_no:=yylineno;
  2015. end;
  2016. var
  2017. SS : string;
  2018. i : longint;
  2019. begin
  2020. { Initialize }
  2021. yydebug:=true;
  2022. aktspace:='';
  2023. block_type:=bt_no;
  2024. IsExtern:=false;
  2025. { Read commandline options }
  2026. ProcessOptions;
  2027. if not CompactMode then
  2028. aktspace:=' ';
  2029. { open input and output files }
  2030. assign(yyinput, inputfilename);
  2031. {$I-}
  2032. reset(yyinput);
  2033. {$I+}
  2034. if ioresult<>0 then
  2035. begin
  2036. writeln('file ',inputfilename,' not found!');
  2037. halt(1);
  2038. end;
  2039. assign(outfile, outputfilename);
  2040. rewrite(outfile);
  2041. { write unit header }
  2042. if not includefile then
  2043. begin
  2044. writeln(outfile,'unit ',unitname,';');
  2045. writeln(outfile,aktspace,'interface');
  2046. writeln(outfile);
  2047. writeln(outfile,'{ Automatically converted by H2Pas ',version,' from ',inputfilename,' }');
  2048. writeln(outfile,'{ The following command line parameters were used:');
  2049. for i:=1 to paramcount do
  2050. writeln(outfile,' ',paramstr(i));
  2051. writeln(outfile,'}');
  2052. writeln(outfile);
  2053. end;
  2054. if UseName then
  2055. begin
  2056. writeln(outfile,aktspace,'const');
  2057. writeln(outfile,aktspace,' External_library=''',libfilename,'''; {Setup as you need}');
  2058. writeln(outfile);
  2059. end;
  2060. if UsePPointers then
  2061. begin
  2062. Writeln(outfile,aktspace,'{ Pointers to basic pascal types, inserted by h2pas conversion program.}');
  2063. Writeln(outfile,aktspace,'Type');
  2064. Writeln(outfile,aktspace,' PLongint = ^Longint;');
  2065. Writeln(outfile,aktspace,' PSmallInt = ^SmallInt;');
  2066. Writeln(outfile,aktspace,' PByte = ^Byte;');
  2067. Writeln(outfile,aktspace,' PWord = ^Word;');
  2068. Writeln(outfile,aktspace,' PDWord = ^DWord;');
  2069. Writeln(outfile,aktspace,' PDouble = ^Double;');
  2070. Writeln(outfile);
  2071. end;
  2072. writeln(outfile,'{$PACKRECORDS C}');
  2073. writeln(outfile);
  2074. { Open tempfiles }
  2075. Assign(extfile,'ext.tmp');
  2076. rewrite(extfile);
  2077. Assign(tempfile,'ext2.tmp');
  2078. rewrite(tempfile);
  2079. { Parse! }
  2080. yyparse;
  2081. { Write implementation if needed }
  2082. if not(includefile) then
  2083. begin
  2084. writeln(outfile);
  2085. writeln(outfile,aktspace,'implementation');
  2086. writeln(outfile);
  2087. end;
  2088. { here we have a problem if a line is longer than 255 chars !! }
  2089. reset(extfile);
  2090. while not eof(extfile) do
  2091. begin
  2092. readln(extfile,SS);
  2093. writeln(outfile,SS);
  2094. end;
  2095. { write end of file }
  2096. writeln(outfile);
  2097. if not(includefile) then
  2098. writeln(outfile,'end.');
  2099. { close and erase tempfiles }
  2100. close(extfile);
  2101. erase(extfile);
  2102. close(outfile);
  2103. close(tempfile);
  2104. erase(tempfile);
  2105. end.
  2106. (*
  2107. $Log$
  2108. Revision 1.7 2000-04-01 20:19:38 florian
  2109. + implemented support for 64 bit int types
  2110. + options are written now to output file
  2111. * improved compact mode
  2112. * fixed writing of variables
  2113. Revision 1.6 2000/04/01 14:16:32 peter
  2114. * addition for another procvar style decl (not working correct yet)
  2115. Revision 1.5 2000/03/28 06:56:31 michael
  2116. + RemoveUNderscore now also does not add underscores to generated parameter names
  2117. Revision 1.4 2000/03/27 21:39:20 peter
  2118. + -S, -T, -c modes added
  2119. * crash fixes
  2120. * removed double opening of inputfile
  2121. Revision 1.3 2000/02/09 16:44:15 peter
  2122. * log truncated
  2123. Revision 1.2 2000/01/07 16:46:05 daniel
  2124. * copyright 2000
  2125. #ifdef ID to {$ifdef ID}
  2126. #ifundef ID to {$ifundef ID}
  2127. #else to {$else}
  2128. #define ID to {$define ID}
  2129. #endif to {$endif}
  2130. -"extern" fully handled . Adds proc/func + 'external _ExternalLibrary;'to
  2131. implementation section
  2132. you must assign _ExternalLibrary later.
  2133. -"const" skips in func/proc arguments.
  2134. changes in convert.y and scan.l
  2135. - "convert" renamed to "h2pas"
  2136. - Inserted the checking "IsAssigned(Pointer)" everywhere access to pointers
  2137. It preserv from Acces Violation Errors.
  2138. - A little remade for TP Lex and Yacc 4.01 -
  2139. changed function "input" to "get_char"
  2140. -!!! because of peculiarity TPLY4.01 you must create unit CONVERU.PAS by
  2141. your hand! Cut const definitions from CONVERT.PAS and paste into CONVERU.PAS
  2142. What need
  2143. * handle struct a { }; in the right way
  2144. * all predefined C types
  2145. * misplaced comments
  2146. * handle functions without result
  2147. *)