pstatmnt.pas 59 KB

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