h2pas.y 66 KB

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