h2pas.y 78 KB

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