pstatmnt.pas 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563
  1. {
  2. $Id$
  3. Copyright (c) 1998 by Florian Klaempfl
  4. Does the parsing of the statements
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit pstatmnt;
  19. interface
  20. uses tree;
  21. var
  22. { true, if we are in a except block }
  23. in_except_block : boolean;
  24. { reads a block }
  25. function block(islibrary : boolean) : ptree;
  26. { reads an assembler block }
  27. function assembler_block : ptree;
  28. implementation
  29. uses
  30. globtype,systems,tokens,
  31. strings,cobjects,globals,files,verbose,
  32. symtable,aasm,pass_1,types,scanner,hcodegen,ppu
  33. ,pbase,pexpr,pdecl
  34. {$ifdef i386}
  35. {$ifdef Ag386Bin}
  36. ,i386base,i386asm
  37. {$else}
  38. ,i386
  39. {$endif}
  40. ,tgeni386
  41. {$ifndef NoRa386Int}
  42. ,ra386int
  43. {$endif NoRa386Int}
  44. {$ifndef NoRa386Att}
  45. ,ra386att
  46. {$endif NoRa386Att}
  47. {$ifndef NoRa386Dir}
  48. ,ra386dir
  49. {$endif NoRa386Dir}
  50. {$endif i386}
  51. {$ifdef m68k}
  52. ,m68k,tgen68k
  53. {$ifndef NoRa68kMot}
  54. ,ra68kmot
  55. {$endif NoRa68kMot}
  56. {$endif m68k}
  57. ;
  58. const
  59. statement_level : longint = 0;
  60. function statement : ptree;forward;
  61. function if_statement : ptree;
  62. var
  63. ex,if_a,else_a : ptree;
  64. begin
  65. consume(_IF);
  66. ex:=comp_expr(true);
  67. consume(_THEN);
  68. if token<>_ELSE then
  69. if_a:=statement
  70. else
  71. if_a:=nil;
  72. if token=_ELSE then
  73. begin
  74. consume(_ELSE);
  75. else_a:=statement;
  76. end
  77. else
  78. else_a:=nil;
  79. if_statement:=genloopnode(ifn,ex,if_a,else_a,false);
  80. end;
  81. { creates a block (list) of statements, til the next END token }
  82. function statements_til_end : ptree;
  83. var
  84. first,last : ptree;
  85. begin
  86. first:=nil;
  87. while token<>_END do
  88. begin
  89. if first=nil then
  90. begin
  91. last:=gennode(statementn,nil,statement);
  92. first:=last;
  93. end
  94. else
  95. begin
  96. last^.left:=gennode(statementn,nil,statement);
  97. last:=last^.left;
  98. end;
  99. if token<>SEMICOLON then
  100. break
  101. else
  102. consume(SEMICOLON);
  103. while token=SEMICOLON do
  104. consume(SEMICOLON);
  105. end;
  106. consume(_END);
  107. statements_til_end:=gensinglenode(blockn,first);
  108. end;
  109. function case_statement : ptree;
  110. var
  111. { contains the label number of currently parsed case block }
  112. aktcaselabel : plabel;
  113. firstlabel : boolean;
  114. root : pcaserecord;
  115. { the typ of the case expression }
  116. casedef : pdef;
  117. procedure newcaselabel(l,h : longint;first:boolean);
  118. var
  119. hcaselabel : pcaserecord;
  120. procedure insertlabel(var p : pcaserecord);
  121. begin
  122. if p=nil then p:=hcaselabel
  123. else
  124. if (p^._low>hcaselabel^._low) and
  125. (p^._low>hcaselabel^._high) then
  126. if (hcaselabel^.statement = p^.statement) and
  127. (p^._low = hcaselabel^._high + 1) then
  128. begin
  129. p^._low := hcaselabel^._low;
  130. freelabel(hcaselabel^._at);
  131. dispose(hcaselabel);
  132. end
  133. else
  134. insertlabel(p^.less)
  135. else
  136. if (p^._high<hcaselabel^._low) and
  137. (p^._high<hcaselabel^._high) then
  138. if (hcaselabel^.statement = p^.statement) and
  139. (p^._high+1 = hcaselabel^._low) then
  140. begin
  141. p^._high := hcaselabel^._high;
  142. freelabel(hcaselabel^._at);
  143. dispose(hcaselabel);
  144. end
  145. else
  146. insertlabel(p^.greater)
  147. else Message(parser_e_double_caselabel);
  148. end;
  149. begin
  150. new(hcaselabel);
  151. hcaselabel^.less:=nil;
  152. hcaselabel^.greater:=nil;
  153. hcaselabel^.statement:=aktcaselabel;
  154. hcaselabel^.firstlabel:=first;
  155. getlabel(hcaselabel^._at);
  156. hcaselabel^._low:=l;
  157. hcaselabel^._high:=h;
  158. insertlabel(root);
  159. end;
  160. var
  161. code,caseexpr,p,instruc,elseblock : ptree;
  162. hl1,hl2 : longint;
  163. begin
  164. consume(_CASE);
  165. caseexpr:=comp_expr(true);
  166. { determines result type }
  167. cleartempgen;
  168. do_firstpass(caseexpr);
  169. casedef:=caseexpr^.resulttype;
  170. if not(is_ordinal(casedef)) then
  171. Message(type_e_ordinal_expr_expected);
  172. consume(_OF);
  173. inc(statement_level);
  174. root:=nil;
  175. instruc:=nil;
  176. repeat
  177. getlabel(aktcaselabel);
  178. firstlabel:=true;
  179. { may be an instruction has more case labels }
  180. repeat
  181. p:=expr;
  182. cleartempgen;
  183. do_firstpass(p);
  184. if (p^.treetype=rangen) then
  185. begin
  186. { type checking for case statements }
  187. if not is_subequal(casedef, p^.left^.resulttype) then
  188. Message(parser_e_case_mismatch);
  189. { type checking for case statements }
  190. if not is_subequal(casedef, p^.right^.resulttype) then
  191. Message(parser_e_case_mismatch);
  192. hl1:=get_ordinal_value(p^.left);
  193. hl2:=get_ordinal_value(p^.right);
  194. testrange(casedef,hl1);
  195. testrange(casedef,hl2);
  196. if hl1>hl2 then
  197. Message(parser_e_case_lower_less_than_upper_bound);
  198. newcaselabel(hl1,hl2,firstlabel);
  199. end
  200. else
  201. begin
  202. { type checking for case statements }
  203. if not is_subequal(casedef, p^.resulttype) then
  204. Message(parser_e_case_mismatch);
  205. hl1:=get_ordinal_value(p);
  206. testrange(casedef,hl1);
  207. newcaselabel(hl1,hl1,firstlabel);
  208. end;
  209. disposetree(p);
  210. if token=COMMA then
  211. consume(COMMA)
  212. else
  213. break;
  214. firstlabel:=false;
  215. until false;
  216. consume(COLON);
  217. { handles instruction block }
  218. p:=gensinglenode(labeln,statement);
  219. p^.labelnr:=aktcaselabel;
  220. { concats instruction }
  221. instruc:=gennode(statementn,instruc,p);
  222. if not((token=_ELSE) or (token=_OTHERWISE) or (token=_END)) then
  223. consume(SEMICOLON);
  224. until (token=_ELSE) or (token=_OTHERWISE) or (token=_END);
  225. if (token=_ELSE) or (token=_OTHERWISE) then
  226. begin
  227. if token=_ELSE then consume(_ELSE)
  228. else consume(_OTHERWISE);
  229. elseblock:=statements_til_end;
  230. end
  231. else
  232. begin
  233. elseblock:=nil;
  234. consume(_END);
  235. end;
  236. dec(statement_level);
  237. code:=gencasenode(caseexpr,instruc,root);
  238. code^.elseblock:=elseblock;
  239. case_statement:=code;
  240. end;
  241. function repeat_statement : ptree;
  242. var
  243. first,last,p_e : ptree;
  244. begin
  245. consume(_REPEAT);
  246. first:=nil;
  247. inc(statement_level);
  248. while token<>_UNTIL do
  249. begin
  250. if first=nil then
  251. begin
  252. last:=gennode(statementn,nil,statement);
  253. first:=last;
  254. end
  255. else
  256. begin
  257. last^.left:=gennode(statementn,nil,statement);
  258. last:=last^.left;
  259. end;
  260. if token<>SEMICOLON then
  261. break;
  262. consume(SEMICOLON);
  263. while token=SEMICOLON do
  264. consume(SEMICOLON);
  265. end;
  266. consume(_UNTIL);
  267. dec(statement_level);
  268. first:=gensinglenode(blockn,first);
  269. p_e:=comp_expr(true);
  270. repeat_statement:=genloopnode(repeatn,p_e,first,nil,false);
  271. end;
  272. function while_statement : ptree;
  273. var
  274. p_e,p_a : ptree;
  275. begin
  276. consume(_WHILE);
  277. p_e:=comp_expr(true);
  278. consume(_DO);
  279. p_a:=statement;
  280. while_statement:=genloopnode(whilen,p_e,p_a,nil,false);
  281. end;
  282. function for_statement : ptree;
  283. var
  284. p_e,tovalue,p_a : ptree;
  285. backward : boolean;
  286. begin
  287. { parse loop header }
  288. consume(_FOR);
  289. p_e:=expr;
  290. if token=_DOWNTO then
  291. begin
  292. consume(_DOWNTO);
  293. backward:=true;
  294. end
  295. else
  296. begin
  297. consume(_TO);
  298. backward:=false;
  299. end;
  300. tovalue:=comp_expr(true);
  301. consume(_DO);
  302. { ... now the instruction }
  303. p_a:=statement;
  304. for_statement:=genloopnode(forn,p_e,tovalue,p_a,backward);
  305. end;
  306. function _with_statement : ptree;
  307. var
  308. right,hp,p : ptree;
  309. i,levelcount : longint;
  310. withsymtable,symtab : psymtable;
  311. obj : pobjectdef;
  312. begin
  313. Must_be_valid:=false;
  314. p:=comp_expr(true);
  315. do_firstpass(p);
  316. right:=nil;
  317. if (not codegenerror) and
  318. (p^.resulttype^.deftype in [objectdef,recorddef]) then
  319. begin
  320. case p^.resulttype^.deftype of
  321. objectdef : begin
  322. obj:=pobjectdef(p^.resulttype);
  323. withsymtable:=new(pwithsymtable,init);
  324. withsymtable^.root:=obj^.publicsyms^.root;
  325. withsymtable^.defowner:=obj;
  326. symtab:=withsymtable;
  327. levelcount:=1;
  328. obj:=obj^.childof;
  329. while assigned(obj) do
  330. begin
  331. symtab^.next:=new(pwithsymtable,init);
  332. symtab:=symtab^.next;
  333. symtab^.root:=obj^.publicsyms^.root;
  334. {$ifndef NODIRECTWITH}
  335. if (p^.treetype=loadn) and
  336. (p^.symtable=aktprocsym^.definition^.localst) then
  337. pwithsymtable(symtab)^.direct_with:=true;
  338. {symtab^.withnode:=p; not yet allocated !! }
  339. pwithsymtable(symtab)^.withrefnode:=p;
  340. {$endif ndef NODIRECTWITH}
  341. symtab^.defowner:=obj;
  342. obj:=obj^.childof;
  343. inc(levelcount);
  344. end;
  345. symtab^.next:=symtablestack;
  346. symtablestack:=withsymtable;
  347. end;
  348. recorddef : begin
  349. symtab:=precdef(p^.resulttype)^.symtable;
  350. levelcount:=1;
  351. withsymtable:=new(pwithsymtable,init);
  352. withsymtable^.root:=symtab^.root;
  353. withsymtable^.next:=symtablestack;
  354. {$ifndef NODIRECTWITH}
  355. if (p^.treetype=loadn) and
  356. (p^.symtable=aktprocsym^.definition^.localst) then
  357. pwithsymtable(withsymtable)^.direct_with:=true;
  358. {symtab^.withnode:=p; not yet allocated !! }
  359. pwithsymtable(withsymtable)^.withrefnode:=p;
  360. {$endif ndef NODIRECTWITH}
  361. withsymtable^.defowner:=obj;
  362. symtablestack:=withsymtable;
  363. end;
  364. end;
  365. if token=COMMA then
  366. begin
  367. consume(COMMA);
  368. {$ifdef tp}
  369. right:=_with_statement;
  370. {$else}
  371. right:=_with_statement();
  372. {$endif}
  373. end
  374. else
  375. begin
  376. consume(_DO);
  377. if token<>SEMICOLON then
  378. right:=statement
  379. else
  380. right:=nil;
  381. end;
  382. for i:=1 to levelcount do
  383. symtablestack:=symtablestack^.next;
  384. _with_statement:=genwithnode(pwithsymtable(withsymtable),p,right,levelcount);
  385. end
  386. else
  387. begin
  388. Message(parser_e_false_with_expr);
  389. { try to recover from error }
  390. if token=COMMA then
  391. begin
  392. consume(COMMA);
  393. {$ifdef tp}
  394. hp:=_with_statement;
  395. {$else}
  396. hp:=_with_statement();
  397. {$endif}
  398. end
  399. else
  400. begin
  401. consume(_DO);
  402. { ignore all }
  403. if token<>SEMICOLON then
  404. statement;
  405. end;
  406. _with_statement:=nil;
  407. end;
  408. end;
  409. function with_statement : ptree;
  410. begin
  411. consume(_WITH);
  412. with_statement:=_with_statement;
  413. end;
  414. function raise_statement : ptree;
  415. var
  416. p1,p2 : ptree;
  417. begin
  418. p1:=nil;
  419. p2:=nil;
  420. consume(_RAISE);
  421. if token<>SEMICOLON then
  422. begin
  423. p1:=comp_expr(true);
  424. if (token=ID) and (pattern='AT') then
  425. begin
  426. consume(ID);
  427. p2:=comp_expr(true);
  428. end;
  429. end
  430. else
  431. begin
  432. if not(in_except_block) then
  433. Message(parser_e_no_reraise_possible);
  434. end;
  435. raise_statement:=gennode(raisen,p1,p2);
  436. end;
  437. function try_statement : ptree;
  438. var
  439. p_try_block,p_finally_block,first,last,
  440. p_default,p_specific,hp : ptree;
  441. ot : pobjectdef;
  442. sym : pvarsym;
  443. old_in_except_block : boolean;
  444. exceptsymtable : psymtable;
  445. objname : stringid;
  446. begin
  447. procinfo.flags:=procinfo.flags or
  448. pi_uses_exceptions;
  449. p_default:=nil;
  450. p_specific:=nil;
  451. { read statements to try }
  452. consume(_TRY);
  453. first:=nil;
  454. inc(statement_level);
  455. while (token<>_FINALLY) and (token<>_EXCEPT) do
  456. begin
  457. if first=nil then
  458. begin
  459. last:=gennode(statementn,nil,statement);
  460. first:=last;
  461. end
  462. else
  463. begin
  464. last^.left:=gennode(statementn,nil,statement);
  465. last:=last^.left;
  466. end;
  467. if token<>SEMICOLON then
  468. break;
  469. consume(SEMICOLON);
  470. emptystats;
  471. end;
  472. p_try_block:=gensinglenode(blockn,first);
  473. if token=_FINALLY then
  474. begin
  475. consume(_FINALLY);
  476. p_finally_block:=statements_til_end;
  477. try_statement:=gennode(tryfinallyn,p_try_block,p_finally_block);
  478. dec(statement_level);
  479. end
  480. else
  481. begin
  482. consume(_EXCEPT);
  483. old_in_except_block:=in_except_block;
  484. in_except_block:=true;
  485. p_specific:=nil;
  486. if token=_ON then
  487. { catch specific exceptions }
  488. begin
  489. repeat
  490. consume(_ON);
  491. if token=ID then
  492. begin
  493. getsym(pattern,false);
  494. objname:=pattern;
  495. consume(ID);
  496. { is a explicit name for the exception given ? }
  497. if token=COLON then
  498. begin
  499. consume(COLON);
  500. getsym(pattern,true);
  501. consume(ID);
  502. if srsym^.typ=unitsym then
  503. begin
  504. consume(POINT);
  505. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  506. consume(ID);
  507. end;
  508. if (srsym^.typ=typesym) and
  509. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  510. pobjectdef(ptypesym(srsym)^.definition)^.isclass then
  511. ot:=pobjectdef(ptypesym(srsym)^.definition)
  512. else
  513. begin
  514. message(type_e_class_type_expected);
  515. ot:=pobjectdef(generrordef);
  516. end;
  517. sym:=new(pvarsym,init(objname,ot));
  518. exceptsymtable:=new(psymtable,init(stt_exceptsymtable));
  519. exceptsymtable^.insert(sym);
  520. { insert the exception symtable stack }
  521. exceptsymtable^.next:=symtablestack;
  522. symtablestack:=exceptsymtable;
  523. end
  524. else
  525. begin
  526. { only exception type }
  527. if srsym^.typ=unitsym then
  528. begin
  529. consume(POINT);
  530. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  531. consume(ID);
  532. end;
  533. if (srsym^.typ=typesym) and
  534. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  535. pobjectdef(ptypesym(srsym)^.definition)^.isclass then
  536. ot:=pobjectdef(ptypesym(srsym)^.definition)
  537. else
  538. begin
  539. message(type_e_class_type_expected);
  540. ot:=pobjectdef(generrordef);
  541. end;
  542. exceptsymtable:=nil;
  543. end;
  544. end
  545. else
  546. consume(ID);
  547. consume(_DO);
  548. hp:=gennode(onn,nil,statement);
  549. if ot^.deftype=errordef then
  550. begin
  551. disposetree(hp);
  552. hp:=genzeronode(errorn);
  553. end;
  554. if p_specific=nil then
  555. begin
  556. last:=hp;
  557. p_specific:=last;
  558. end
  559. else
  560. begin
  561. last^.left:=hp;
  562. last:=last^.left;
  563. end;
  564. { set the informations }
  565. last^.excepttype:=ot;
  566. last^.exceptsymtable:=exceptsymtable;
  567. last^.disposetyp:=dt_onn;
  568. { remove exception symtable }
  569. if assigned(exceptsymtable) then
  570. dellexlevel;
  571. if token<>SEMICOLON then
  572. break;
  573. consume(SEMICOLON);
  574. emptystats;
  575. until (token=_END) or(token=_ELSE);
  576. if token=_ELSE then
  577. { catch the other exceptions }
  578. begin
  579. consume(_ELSE);
  580. p_default:=statements_til_end;
  581. end
  582. else
  583. consume(_END);
  584. end
  585. else
  586. { catch all exceptions }
  587. begin
  588. p_default:=statements_til_end;
  589. end;
  590. dec(statement_level);
  591. in_except_block:=old_in_except_block;
  592. try_statement:=genloopnode(tryexceptn,p_try_block,p_specific,p_default,false);
  593. end;
  594. end;
  595. function exit_statement : ptree;
  596. var
  597. p : ptree;
  598. begin
  599. consume(_EXIT);
  600. if token=LKLAMMER then
  601. begin
  602. consume(LKLAMMER);
  603. p:=comp_expr(true);
  604. consume(RKLAMMER);
  605. if procinfo.retdef=pdef(voiddef) then
  606. Message(parser_e_void_function)
  607. else
  608. procinfo.funcret_is_valid:=true;
  609. end
  610. else
  611. p:=nil;
  612. exit_statement:=gensinglenode(exitn,p);
  613. end;
  614. function _asm_statement : ptree;
  615. var
  616. asmstat : ptree;
  617. Marker : Pai;
  618. begin
  619. if (aktprocsym^.definition^.options and poinline)<>0 then
  620. Begin
  621. Message1(parser_w_not_supported_for_inline,'asm statement');
  622. Message(parser_w_inlining_disabled);
  623. aktprocsym^.definition^.options:= aktprocsym^.definition^.options and not poinline;
  624. End;
  625. Inside_asm_statement:=true;
  626. case aktasmmode of
  627. {$ifdef i386}
  628. {$ifndef NoRA386Att}
  629. asmmode_i386_att:
  630. asmstat:=ra386att.assemble;
  631. {$endif NoRA386Att}
  632. {$ifndef NoRA386Int}
  633. asmmode_i386_intel:
  634. asmstat:=ra386int.assemble;
  635. {$endif NoRA386Int}
  636. {$ifndef NoRA386Dir}
  637. asmmode_i386_direct:
  638. asmstat:=ra386dir.assemble;
  639. {$endif NoRA386Dir}
  640. {$endif}
  641. {$ifdef m68k}
  642. {$ifndef NoRA68kMot}
  643. asmmode_m68k_mot:
  644. asmstat:=ra68kmot.assemble;
  645. {$endif NoRA68kMot}
  646. {$endif}
  647. else
  648. Message(parser_f_assembler_reader_not_supported);
  649. end;
  650. { Read first the _ASM statement }
  651. consume(_ASM);
  652. { END is read }
  653. if token=LECKKLAMMER then
  654. begin
  655. { it's possible to specify the modified registers }
  656. consume(LECKKLAMMER);
  657. asmstat^.object_preserved:=true;
  658. if token<>RECKKLAMMER then
  659. repeat
  660. { uppercase, because it's a CSTRING }
  661. uppervar(pattern);
  662. {$ifdef i386}
  663. if pattern='EAX' then
  664. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  665. else if pattern='EBX' then
  666. usedinproc:=usedinproc or ($80 shr byte(R_EBX))
  667. else if pattern='ECX' then
  668. usedinproc:=usedinproc or ($80 shr byte(R_ECX))
  669. else if pattern='EDX' then
  670. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  671. else if pattern='ESI' then
  672. begin
  673. usedinproc:=usedinproc or ($80 shr byte(R_ESI));
  674. asmstat^.object_preserved:=false;
  675. end
  676. else if pattern='EDI' then
  677. usedinproc:=usedinproc or ($80 shr byte(R_EDI))
  678. {$endif i386}
  679. {$ifdef m68k}
  680. if pattern='D0' then
  681. usedinproc:=usedinproc or ($800 shr word(R_D0))
  682. else if pattern='D1' then
  683. usedinproc:=usedinproc or ($800 shr word(R_D1))
  684. else if pattern='D6' then
  685. usedinproc:=usedinproc or ($800 shr word(R_D6))
  686. else if pattern='A0' then
  687. usedinproc:=usedinproc or ($800 shr word(R_A0))
  688. else if pattern='A1' then
  689. usedinproc:=usedinproc or ($800 shr word(R_A1))
  690. {$endif m68k}
  691. else consume(RECKKLAMMER);
  692. consume(CSTRING);
  693. if token=COMMA then consume(COMMA)
  694. else break;
  695. until false;
  696. consume(RECKKLAMMER);
  697. end
  698. else usedinproc:=$ff;
  699. { mark the start and the end of the assembler block for the optimizer }
  700. If Assigned(AsmStat^.p_asm) Then
  701. Begin
  702. Marker := New(Pai_Marker, Init(AsmBlockStart));
  703. AsmStat^.p_asm^.Insert(Marker);
  704. Marker := New(Pai_Marker, Init(AsmBlockEnd));
  705. AsmStat^.p_asm^.Concat(Marker);
  706. End;
  707. Inside_asm_statement:=false;
  708. _asm_statement:=asmstat;
  709. end;
  710. function new_dispose_statement : ptree;
  711. var
  712. p,p2 : ptree;
  713. ht : ttoken;
  714. store_allow : boolean;
  715. again : boolean; { dummy for do_proc_call }
  716. destrukname : stringid;
  717. sym : psym;
  718. classh : pobjectdef;
  719. pd,pd2 : pdef;
  720. store_valid : boolean;
  721. tt : ttreetyp;
  722. begin
  723. ht:=token;
  724. if token=_NEW then consume(_NEW)
  725. else consume(_DISPOSE);
  726. if ht=_NEW then
  727. tt:=hnewn
  728. else
  729. tt:=hdisposen;
  730. consume(LKLAMMER);
  731. p:=comp_expr(true);
  732. { calc return type }
  733. cleartempgen;
  734. Store_valid := Must_be_valid;
  735. Must_be_valid := False;
  736. do_firstpass(p);
  737. Must_be_valid := Store_valid;
  738. {var o:Pobject;
  739. begin
  740. new(o,init); (*Also a valid new statement*)
  741. end;}
  742. if token=COMMA then
  743. begin
  744. { extended syntax of new and dispose }
  745. { function styled new is handled in factor }
  746. consume(COMMA);
  747. { destructors have no parameters }
  748. destrukname:=pattern;
  749. consume(ID);
  750. pd:=p^.resulttype;
  751. pd2:=pd;
  752. if (p^.resulttype = nil) or (pd^.deftype<>pointerdef) then
  753. begin
  754. Message(type_e_pointer_type_expected);
  755. p:=factor(false);
  756. consume(RKLAMMER);
  757. new_dispose_statement:=genzeronode(errorn);
  758. exit;
  759. end;
  760. { first parameter must be an object or class }
  761. if ppointerdef(pd)^.definition^.deftype<>objectdef then
  762. begin
  763. Message(parser_e_pointer_to_class_expected);
  764. new_dispose_statement:=factor(false);
  765. consume_all_until(RKLAMMER);
  766. consume(RKLAMMER);
  767. exit;
  768. end;
  769. { check, if the first parameter is a pointer to a _class_ }
  770. classh:=pobjectdef(ppointerdef(pd)^.definition);
  771. if (classh^.options and oo_is_class)<>0 then
  772. begin
  773. Message(parser_e_no_new_or_dispose_for_classes);
  774. new_dispose_statement:=factor(false);
  775. { while token<>RKLAMMER do
  776. consume(token); }
  777. consume_all_until(RKLAMMER);
  778. consume(RKLAMMER);
  779. exit;
  780. end;
  781. { search cons-/destructor, also in parent classes }
  782. sym:=nil;
  783. while assigned(classh) do
  784. begin
  785. store_allow:=allow_only_static;
  786. allow_only_static:=false;
  787. sym:=classh^.publicsyms^.search(pattern);
  788. allow_only_static:=store_allow;
  789. srsymtable:=classh^.publicsyms;
  790. if assigned(sym) then
  791. break;
  792. classh:=classh^.childof;
  793. end;
  794. { the second parameter of new/dispose must be a call }
  795. { to a cons-/destructor }
  796. if (not assigned(sym)) or (sym^.typ<>procsym) then
  797. begin
  798. Message(parser_e_expr_have_to_be_destructor_call);
  799. new_dispose_statement:=genzeronode(errorn);
  800. end
  801. else
  802. begin
  803. p2:=gensinglenode(tt,p);
  804. if ht=_NEW then
  805. begin
  806. { Constructors can take parameters.}
  807. p2^.resulttype:=ppointerdef(pd)^.definition;
  808. do_member_read(false,sym,p2,pd,again);
  809. end
  810. else
  811. { destructors can't.}
  812. p2:=genmethodcallnode(pprocsym(sym),srsymtable,p2);
  813. { we need the real called method }
  814. cleartempgen;
  815. do_firstpass(p2);
  816. if not codegenerror then
  817. begin
  818. if (ht=_NEW) and ((p2^.procdefinition^.options and poconstructor)=0) then
  819. Message(parser_e_expr_have_to_be_constructor_call);
  820. if (ht=_DISPOSE) and ((p2^.procdefinition^.options and podestructor)=0) then
  821. Message(parser_e_expr_have_to_be_destructor_call);
  822. if ht=_NEW then
  823. begin
  824. p2:=gennode(assignn,getcopy(p),gensinglenode(newn,p2));
  825. p2^.right^.resulttype:=pd2;
  826. end;
  827. end;
  828. new_dispose_statement:=p2;
  829. end;
  830. end
  831. else
  832. begin
  833. if (p^.resulttype=nil) or (p^.resulttype^.deftype<>pointerdef) then
  834. Begin
  835. Message(type_e_pointer_type_expected);
  836. new_dispose_statement:=genzeronode(errorn);
  837. end
  838. else
  839. begin
  840. if (ppointerdef(p^.resulttype)^.definition^.deftype=objectdef) then
  841. Message(parser_w_use_extended_syntax_for_objects);
  842. case ht of
  843. _NEW : new_dispose_statement:=gensinglenode(simplenewn,p);
  844. _DISPOSE : new_dispose_statement:=gensinglenode(simpledisposen,p);
  845. end;
  846. end;
  847. end;
  848. consume(RKLAMMER);
  849. end;
  850. function statement_block(starttoken : ttoken) : ptree;
  851. var
  852. first,last : ptree;
  853. filepos : tfileposinfo;
  854. begin
  855. first:=nil;
  856. filepos:=tokenpos;
  857. consume(starttoken);
  858. inc(statement_level);
  859. while not(token in [_END,_FINALIZATION]) do
  860. begin
  861. if first=nil then
  862. begin
  863. last:=gennode(statementn,nil,statement);
  864. first:=last;
  865. end
  866. else
  867. begin
  868. last^.left:=gennode(statementn,nil,statement);
  869. last:=last^.left;
  870. end;
  871. if (token in [_END,_FINALIZATION]) then
  872. break
  873. else
  874. begin
  875. { if no semicolon, then error and go on }
  876. if token<>SEMICOLON then
  877. begin
  878. consume(SEMICOLON);
  879. consume_all_until(SEMICOLON);
  880. end;
  881. consume(SEMICOLON);
  882. end;
  883. emptystats;
  884. end;
  885. { don't consume the finalization token, it is consumed when
  886. reading the finalization block, but allow it only after
  887. an initalization ! }
  888. if (starttoken<>_INITIALIZATION) or (token<>_FINALIZATION) then
  889. consume(_END);
  890. dec(statement_level);
  891. last:=gensinglenode(blockn,first);
  892. set_tree_filepos(last,filepos);
  893. statement_block:=last;
  894. end;
  895. function statement : ptree;
  896. var
  897. p : ptree;
  898. code : ptree;
  899. labelnr : plabel;
  900. filepos : tfileposinfo;
  901. label
  902. ready;
  903. begin
  904. filepos:=tokenpos;
  905. case token of
  906. _GOTO : begin
  907. if not(cs_support_goto in aktmoduleswitches)then
  908. Message(sym_e_goto_and_label_not_supported);
  909. consume(_GOTO);
  910. if (token<>INTCONST) and (token<>ID) then
  911. begin
  912. Message(sym_e_label_not_found);
  913. code:=genzeronode(errorn);
  914. end
  915. else
  916. begin
  917. getsym(pattern,true);
  918. consume(token);
  919. if srsym^.typ<>labelsym then
  920. begin
  921. Message(sym_e_id_is_no_label_id);
  922. code:=genzeronode(errorn);
  923. end
  924. else
  925. code:=genlabelnode(goton,
  926. plabelsym(srsym)^.number);
  927. end;
  928. end;
  929. _BEGIN : code:=statement_block(_BEGIN);
  930. _IF : code:=if_statement;
  931. _CASE : code:=case_statement;
  932. _REPEAT : code:=repeat_statement;
  933. _WHILE : code:=while_statement;
  934. _FOR : code:=for_statement;
  935. _NEW,_DISPOSE : code:=new_dispose_statement;
  936. _WITH : code:=with_statement;
  937. _TRY : code:=try_statement;
  938. _RAISE : code:=raise_statement;
  939. { semicolons,else until and end are ignored }
  940. SEMICOLON,
  941. _ELSE,
  942. _UNTIL,
  943. _END:
  944. code:=genzeronode(niln);
  945. _FAIL : begin
  946. { internalerror(100); }
  947. if (aktprocsym^.definition^.options and poconstructor)=0 then
  948. Message(parser_e_fail_only_in_constructor);
  949. consume(_FAIL);
  950. code:=genzeronode(failn);
  951. end;
  952. _EXIT : code:=exit_statement;
  953. _ASM : begin
  954. code:=_asm_statement;
  955. end;
  956. _EOF : begin
  957. Message(scan_f_end_of_file);
  958. end;
  959. else
  960. begin
  961. if (token=INTCONST) or
  962. ((token=ID) and
  963. not((m_result in aktmodeswitches) and
  964. (pattern='RESULT'))) then
  965. begin
  966. getsym(pattern,true);
  967. lastsymknown:=true;
  968. lastsrsym:=srsym;
  969. { it is NOT necessarily the owner
  970. it can be a withsymtable !!! }
  971. lastsrsymtable:=srsymtable;
  972. if assigned(srsym) and (srsym^.typ=labelsym) then
  973. begin
  974. consume(token);
  975. consume(COLON);
  976. if plabelsym(srsym)^.defined then
  977. Message(sym_e_label_already_defined);
  978. plabelsym(srsym)^.defined:=true;
  979. { statement modifies srsym }
  980. labelnr:=plabelsym(srsym)^.number;
  981. lastsymknown:=false;
  982. { the pointer to the following instruction }
  983. { isn't a very clean way }
  984. {$ifdef tp}
  985. code:=gensinglenode(labeln,statement);
  986. {$else}
  987. code:=gensinglenode(labeln,statement());
  988. {$endif}
  989. code^.labelnr:=labelnr;
  990. { sorry, but there is a jump the easiest way }
  991. goto ready;
  992. end;
  993. end;
  994. p:=expr;
  995. if not(p^.treetype in [calln,assignn,breakn,inlinen,
  996. continuen]) then
  997. Message(cg_e_illegal_expression);
  998. { specify that we don't use the value returned by the call }
  999. { Question : can this be also improtant
  1000. for inlinen ??
  1001. it is used for :
  1002. - dispose of temp stack space
  1003. - dispose on FPU stack }
  1004. if p^.treetype=calln then
  1005. p^.return_value_used:=false;
  1006. code:=p;
  1007. end;
  1008. end;
  1009. ready:
  1010. if assigned(code) then
  1011. set_tree_filepos(code,filepos);
  1012. statement:=code;
  1013. end;
  1014. function block(islibrary : boolean) : ptree;
  1015. var
  1016. funcretsym : pfuncretsym;
  1017. begin
  1018. if procinfo.retdef<>pdef(voiddef) then
  1019. begin
  1020. { if the current is a function aktprocsym is non nil }
  1021. { and there is a local symtable set }
  1022. funcretsym:=new(pfuncretsym,init(aktprocsym^.name,@procinfo));
  1023. { insert in local symtable }
  1024. symtablestack^.insert(funcretsym);
  1025. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  1026. procinfo.retoffset:=-funcretsym^.address;
  1027. procinfo.funcretsym:=funcretsym;
  1028. end;
  1029. read_declarations(islibrary);
  1030. { temporary space is set, while the BEGIN of the procedure }
  1031. if (symtablestack^.symtabletype=localsymtable) then
  1032. procinfo.firsttemp := -symtablestack^.datasize
  1033. else procinfo.firsttemp := 0;
  1034. { space for the return value }
  1035. { !!!!! this means that we can not set the return value
  1036. in a subfunction !!!!! }
  1037. { because we don't know yet where the address is }
  1038. if procinfo.retdef<>pdef(voiddef) then
  1039. begin
  1040. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  1041. { if (procinfo.retdef^.deftype=orddef) or
  1042. (procinfo.retdef^.deftype=pointerdef) or
  1043. (procinfo.retdef^.deftype=enumdef) or
  1044. (procinfo.retdef^.deftype=procvardef) or
  1045. (procinfo.retdef^.deftype=floatdef) or
  1046. (
  1047. (procinfo.retdef^.deftype=setdef) and
  1048. (psetdef(procinfo.retdef)^.settype=smallset)
  1049. ) then }
  1050. begin
  1051. { the space has been set in the local symtable }
  1052. procinfo.retoffset:=-funcretsym^.address;
  1053. if (procinfo.flags and pi_operator)<>0 then
  1054. {opsym^.address:=procinfo.call_offset; is wrong PM }
  1055. opsym^.address:=-procinfo.retoffset;
  1056. { eax is modified by a function }
  1057. {$ifdef i386}
  1058. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  1059. if is_64bitint(procinfo.retdef) then
  1060. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  1061. {$endif}
  1062. {$ifdef m68k}
  1063. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1064. if is_64bitint(procinfo.retdef) then
  1065. usedinproc:=usedinproc or ($800 shr byte(R_D1))
  1066. {$endif}
  1067. end;
  1068. end;
  1069. {Unit initialization?.}
  1070. if (lexlevel=unit_init_level) and (current_module^.is_unit) then
  1071. if (token=_END) then
  1072. begin
  1073. consume(_END);
  1074. block:=nil;
  1075. end
  1076. else
  1077. begin
  1078. if token=_INITIALIZATION then
  1079. begin
  1080. current_module^.flags:=current_module^.flags or uf_init;
  1081. block:=statement_block(_INITIALIZATION);
  1082. end
  1083. else if (token=_FINALIZATION) then
  1084. begin
  1085. if (current_module^.flags and uf_finalize)<>0 then
  1086. block:=statement_block(_FINALIZATION)
  1087. else
  1088. begin
  1089. block:=nil;
  1090. exit;
  1091. end;
  1092. end
  1093. else
  1094. begin
  1095. current_module^.flags:=current_module^.flags or uf_init;
  1096. block:=statement_block(_BEGIN);
  1097. end;
  1098. end
  1099. else
  1100. block:=statement_block(_BEGIN);
  1101. end;
  1102. function assembler_block : ptree;
  1103. begin
  1104. read_declarations(false);
  1105. { temporary space is set, while the BEGIN of the procedure }
  1106. if symtablestack^.symtabletype=localsymtable then
  1107. procinfo.firsttemp := -symtablestack^.datasize
  1108. else procinfo.firsttemp := 0;
  1109. { assembler code does not allocate }
  1110. { space for the return value }
  1111. if procinfo.retdef<>pdef(voiddef) then
  1112. begin
  1113. if ret_in_acc(procinfo.retdef) then
  1114. begin
  1115. { in assembler code the result should be directly in %eax
  1116. procinfo.retoffset:=procinfo.firsttemp-procinfo.retdef^.size;
  1117. procinfo.firsttemp:=procinfo.retoffset; }
  1118. {$ifdef i386}
  1119. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  1120. {$endif}
  1121. {$ifdef m68k}
  1122. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1123. {$endif}
  1124. end
  1125. {
  1126. else if not is_fpu(procinfo.retdef) then
  1127. should we allow assembler functions of big elements ?
  1128. YES (FK)!!
  1129. Message(parser_e_asm_incomp_with_function_return);
  1130. }
  1131. end;
  1132. { set the framepointer to esp for assembler functions }
  1133. { but only if the are no local variables }
  1134. { added no parameter also (PM) }
  1135. if ((aktprocsym^.definition^.options and poassembler)<>0) and
  1136. (aktprocsym^.definition^.localst^.datasize=0) and
  1137. (aktprocsym^.definition^.parast^.datasize=0) and
  1138. not(ret_in_param(aktprocsym^.definition^.retdef)) then
  1139. begin
  1140. {$ifdef i386}
  1141. procinfo.framepointer:=R_ESP;
  1142. {$endif}
  1143. {$ifdef m68k}
  1144. procinfo.framepointer:=R_SP;
  1145. {$endif}
  1146. { set the right value for parameters }
  1147. dec(aktprocsym^.definition^.parast^.call_offset,target_os.size_of_pointer);
  1148. dec(procinfo.call_offset,target_os.size_of_pointer);
  1149. end;
  1150. { force the asm statement }
  1151. if token<>_ASM then
  1152. consume(_ASM);
  1153. Procinfo.Flags := ProcInfo.Flags Or pi_is_assembler;
  1154. assembler_block:=_asm_statement;
  1155. { becuase the END is already read we need to get the
  1156. last_endtoken_filepos here (PFV) }
  1157. last_endtoken_filepos:=tokenpos;
  1158. end;
  1159. end.
  1160. {
  1161. $Log$
  1162. Revision 1.69 1999-03-02 02:56:15 peter
  1163. + stabs support for binary writers
  1164. * more fixes and missing updates from the previous commit :(
  1165. Revision 1.68 1999/02/26 00:48:23 peter
  1166. * assembler writers fixed for ag386bin
  1167. Revision 1.67 1999/02/22 13:07:01 pierre
  1168. + -b and -bl options work !
  1169. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1170. is not enabled when quitting global section
  1171. * local vars and procedures are not yet stored into PPU
  1172. Revision 1.66 1999/02/22 02:15:31 peter
  1173. * updates for ag386bin
  1174. Revision 1.65 1999/02/15 13:13:15 pierre
  1175. * fix for bug0216
  1176. Revision 1.64 1999/02/11 09:46:26 pierre
  1177. * fix for normal method calls inside static methods :
  1178. WARNING there were both parser and codegen errors !!
  1179. added static_call boolean to calln tree
  1180. Revision 1.63 1999/02/09 15:45:47 florian
  1181. + complex results for assembler functions, fixes bug0155
  1182. Revision 1.62 1999/01/27 13:06:57 pierre
  1183. * memory leak in case optimization fixed
  1184. Revision 1.61 1999/01/25 22:49:09 peter
  1185. * more fixes for the on bug with unknown id
  1186. Revision 1.60 1999/01/23 23:29:38 florian
  1187. * first running version of the new code generator
  1188. * when compiling exceptions under Linux fixed
  1189. Revision 1.59 1999/01/21 16:41:02 pierre
  1190. * fix for constructor inside with statements
  1191. Revision 1.58 1999/01/05 08:20:07 florian
  1192. * mainly problem with invalid case ranges fixed (reported by Jonas)
  1193. Revision 1.57 1998/12/29 18:48:15 jonas
  1194. + optimize pascal code surrounding assembler blocks
  1195. Revision 1.56 1998/12/23 22:52:56 peter
  1196. * fixed new(x) crash if x contains an error
  1197. Revision 1.55 1998/12/16 12:30:59 jonas
  1198. * released CaseRange
  1199. Revision 1.54 1998/12/15 22:32:24 jonas
  1200. + convert consecutive case labels to a single range (-dCaseRange)
  1201. Revision 1.53 1998/12/15 11:52:18 peter
  1202. * fixed dup release of statement label in case
  1203. Revision 1.52 1998/12/11 00:03:37 peter
  1204. + globtype,tokens,version unit splitted from globals
  1205. Revision 1.51 1998/12/10 09:47:24 florian
  1206. + basic operations with int64/qord (compiler with -dint64)
  1207. + rtti of enumerations extended: names are now written
  1208. Revision 1.50 1998/11/13 15:40:25 pierre
  1209. + added -Se in Makefile cvstest target
  1210. + lexlevel cleanup
  1211. normal_function_level main_program_level and unit_init_level defined
  1212. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  1213. (test added in code !)
  1214. * -Un option was wrong
  1215. * _FAIL and _SELF only keyword inside
  1216. constructors and methods respectively
  1217. Revision 1.49 1998/11/12 12:55:17 pierre
  1218. * fix for bug0176 and bug0177
  1219. Revision 1.48 1998/11/05 23:43:24 peter
  1220. * fixed assembler directive and then not an ASM statement
  1221. Revision 1.47 1998/10/30 16:20:22 peter
  1222. * fixed dispose(destructor) crash when destructor didn't exists
  1223. Revision 1.46 1998/10/20 08:06:53 pierre
  1224. * several memory corruptions due to double freemem solved
  1225. => never use p^.loc.location:=p^.left^.loc.location;
  1226. + finally I added now by default
  1227. that ra386dir translates global and unit symbols
  1228. + added a first field in tsymtable and
  1229. a nextsym field in tsym
  1230. (this allows to obtain ordered type info for
  1231. records and objects in gdb !)
  1232. Revision 1.45 1998/10/19 08:55:01 pierre
  1233. * wrong stabs info corrected once again !!
  1234. + variable vmt offset with vmt field only if required
  1235. implemented now !!!
  1236. Revision 1.44 1998/10/13 13:10:27 peter
  1237. * new style for m68k/i386 infos and enums
  1238. Revision 1.43 1998/10/08 13:46:22 peter
  1239. * added eof message
  1240. * fixed unit init section parsing with finalize
  1241. Revision 1.42 1998/09/26 17:45:38 peter
  1242. + idtoken and only one token table
  1243. Revision 1.41 1998/09/24 23:49:15 peter
  1244. + aktmodeswitches
  1245. Revision 1.40 1998/09/23 21:53:04 florian
  1246. * the following doesn't work: on texception do, was a parser error, fixed
  1247. Revision 1.39 1998/09/21 10:26:07 peter
  1248. * merged fix
  1249. Revision 1.38.2.1 1998/09/21 10:24:43 peter
  1250. * fixed error recovery with with
  1251. Revision 1.38 1998/09/04 08:42:04 peter
  1252. * updated some error messages
  1253. Revision 1.37 1998/08/21 14:08:52 pierre
  1254. + TEST_FUNCRET now default (old code removed)
  1255. works also for m68k (at least compiles)
  1256. Revision 1.36 1998/08/20 21:36:41 peter
  1257. * fixed 'with object do' bug
  1258. Revision 1.35 1998/08/20 09:26:42 pierre
  1259. + funcret setting in underproc testing
  1260. compile with _dTEST_FUNCRET
  1261. Revision 1.34 1998/08/17 10:10:09 peter
  1262. - removed OLDPPU
  1263. Revision 1.33 1998/08/12 19:39:30 peter
  1264. * fixed some crashes
  1265. Revision 1.32 1998/08/10 14:50:17 peter
  1266. + localswitches, moduleswitches, globalswitches splitting
  1267. Revision 1.31 1998/08/02 16:41:59 florian
  1268. * on o : tobject do should also work now, the exceptsymtable shouldn't be
  1269. disposed by dellexlevel
  1270. Revision 1.30 1998/07/30 16:07:10 florian
  1271. * try ... expect <statement> end; works now
  1272. Revision 1.29 1998/07/30 13:30:37 florian
  1273. * final implemenation of exception support, maybe it needs
  1274. some fixes :)
  1275. Revision 1.28 1998/07/30 11:18:18 florian
  1276. + first implementation of try ... except on .. do end;
  1277. * limitiation of 65535 bytes parameters for cdecl removed
  1278. Revision 1.27 1998/07/28 21:52:55 florian
  1279. + implementation of raise and try..finally
  1280. + some misc. exception stuff
  1281. Revision 1.26 1998/07/27 21:57:14 florian
  1282. * fix to allow tv like stream registration:
  1283. @tmenu.load doesn't work if load had parameters or if load was only
  1284. declared in an anchestor class of tmenu
  1285. Revision 1.25 1998/07/14 21:46:53 peter
  1286. * updated messages file
  1287. Revision 1.24 1998/07/10 10:48:42 peter
  1288. * fixed realnumber scanning
  1289. * [] after asmblock was not uppercased anymore
  1290. Revision 1.23 1998/06/25 08:48:18 florian
  1291. * first version of rtti support
  1292. Revision 1.22 1998/06/24 14:48:36 peter
  1293. * ifdef newppu -> ifndef oldppu
  1294. Revision 1.21 1998/06/24 14:06:34 peter
  1295. * fixed the name changes
  1296. Revision 1.20 1998/06/23 14:00:16 peter
  1297. * renamed RA* units
  1298. Revision 1.19 1998/06/08 22:59:50 peter
  1299. * smartlinking works for win32
  1300. * some defines to exclude some compiler parts
  1301. Revision 1.18 1998/06/05 14:37:35 pierre
  1302. * fixes for inline for operators
  1303. * inline procedure more correctly restricted
  1304. Revision 1.17 1998/06/04 09:55:43 pierre
  1305. * demangled name of procsym reworked to become independant of the mangling scheme
  1306. Revision 1.16 1998/06/02 17:03:04 pierre
  1307. * with node corrected for objects
  1308. * small bugs for SUPPORT_MMX fixed
  1309. Revision 1.15 1998/05/30 14:31:06 peter
  1310. + $ASMMODE
  1311. Revision 1.14 1998/05/29 09:58:14 pierre
  1312. * OPR_REGISTER for 1 arg was missing in ratti386.pas
  1313. (probably a merging problem)
  1314. * errors at start of line were lost
  1315. Revision 1.13 1998/05/28 17:26:50 peter
  1316. * fixed -R switch, it didn't work after my previous akt/init patch
  1317. * fixed bugs 110,130,136
  1318. Revision 1.12 1998/05/21 19:33:33 peter
  1319. + better procedure directive handling and only one table
  1320. Revision 1.11 1998/05/20 09:42:35 pierre
  1321. + UseTokenInfo now default
  1322. * unit in interface uses and implementation uses gives error now
  1323. * only one error for unknown symbol (uses lastsymknown boolean)
  1324. the problem came from the label code !
  1325. + first inlined procedures and function work
  1326. (warning there might be allowed cases were the result is still wrong !!)
  1327. * UseBrower updated gives a global list of all position of all used symbols
  1328. with switch -gb
  1329. Revision 1.10 1998/05/11 13:07:56 peter
  1330. + $ifdef NEWPPU for the new ppuformat
  1331. + $define GDB not longer required
  1332. * removed all warnings and stripped some log comments
  1333. * no findfirst/findnext anymore to remove smartlink *.o files
  1334. Revision 1.9 1998/05/06 08:38:46 pierre
  1335. * better position info with UseTokenInfo
  1336. UseTokenInfo greatly simplified
  1337. + added check for changed tree after first time firstpass
  1338. (if we could remove all the cases were it happen
  1339. we could skip all firstpass if firstpasscount > 1)
  1340. Only with ExtDebug
  1341. Revision 1.8 1998/05/05 12:05:42 florian
  1342. * problems with properties fixed
  1343. * crash fixed: i:=l when i and l are undefined, was a problem with
  1344. implementation of private/protected
  1345. Revision 1.7 1998/05/01 16:38:46 florian
  1346. * handling of private and protected fixed
  1347. + change_keywords_to_tp implemented to remove
  1348. keywords which aren't supported by tp
  1349. * break and continue are now symbols of the system unit
  1350. + widestring, longstring and ansistring type released
  1351. Revision 1.6 1998/04/30 15:59:42 pierre
  1352. * GDB works again better :
  1353. correct type info in one pass
  1354. + UseTokenInfo for better source position
  1355. * fixed one remaining bug in scanner for line counts
  1356. * several little fixes
  1357. Revision 1.5 1998/04/29 10:33:59 pierre
  1358. + added some code for ansistring (not complete nor working yet)
  1359. * corrected operator overloading
  1360. * corrected nasm output
  1361. + started inline procedures
  1362. + added starstarn : use ** for exponentiation (^ gave problems)
  1363. + started UseTokenInfo cond to get accurate positions
  1364. Revision 1.4 1998/04/08 16:58:05 pierre
  1365. * several bugfixes
  1366. ADD ADC and AND are also sign extended
  1367. nasm output OK (program still crashes at end
  1368. and creates wrong assembler files !!)
  1369. procsym types sym in tdef removed !!
  1370. }