pstatmnt.pas 53 KB

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