h2pas.y 69 KB

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