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. var
  22. { true, if we are in a except block }
  23. in_except_block : boolean;
  24. { reads a block }
  25. function block(islibrary : boolean) : ptree;
  26. { reads an assembler block }
  27. function assembler_block : ptree;
  28. implementation
  29. uses
  30. globtype,systems,tokens,
  31. strings,cobjects,globals,files,verbose,
  32. symconst,symtable,aasm,pass_1,types,scanner,
  33. {$ifdef newcg}
  34. cgbase,
  35. {$else}
  36. hcodegen,
  37. {$endif}
  38. ppu
  39. ,pbase,pexpr,pdecl,cpubase,cpuasm
  40. {$ifdef i386}
  41. ,tgeni386
  42. {$ifndef NoRa386Int}
  43. ,ra386int
  44. {$endif NoRa386Int}
  45. {$ifndef NoRa386Att}
  46. ,ra386att
  47. {$endif NoRa386Att}
  48. {$ifndef NoRa386Dir}
  49. ,ra386dir
  50. {$endif NoRa386Dir}
  51. {$endif i386}
  52. {$ifdef m68k}
  53. ,tgen68k
  54. {$ifndef NoRa68kMot}
  55. ,ra68kmot
  56. {$endif NoRa68kMot}
  57. {$endif m68k}
  58. {$ifdef alpha}
  59. ,tgeni386 { this is a dummy!! }
  60. {$endif alpha}
  61. {$ifdef powerpc}
  62. ,tgeni386 { this is a dummy!! }
  63. {$endif powerpc}
  64. ;
  65. const
  66. statement_level : longint = 0;
  67. function statement : ptree;forward;
  68. function if_statement : ptree;
  69. var
  70. ex,if_a,else_a : ptree;
  71. begin
  72. consume(_IF);
  73. ex:=comp_expr(true);
  74. consume(_THEN);
  75. if token<>_ELSE then
  76. if_a:=statement
  77. else
  78. if_a:=nil;
  79. if try_to_consume(_ELSE) then
  80. else_a:=statement
  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 not try_to_consume(_SEMICOLON) then
  104. break;
  105. emptystats;
  106. end;
  107. consume(_END);
  108. statements_til_end:=gensinglenode(blockn,first);
  109. end;
  110. function case_statement : ptree;
  111. var
  112. { contains the label number of currently parsed case block }
  113. aktcaselabel : pasmlabel;
  114. firstlabel : boolean;
  115. root : pcaserecord;
  116. { the typ of the case expression }
  117. casedef : pdef;
  118. procedure newcaselabel(l,h : longint;first:boolean);
  119. var
  120. hcaselabel : pcaserecord;
  121. procedure insertlabel(var p : pcaserecord);
  122. begin
  123. if p=nil then p:=hcaselabel
  124. else
  125. if (p^._low>hcaselabel^._low) and
  126. (p^._low>hcaselabel^._high) then
  127. if (hcaselabel^.statement = p^.statement) and
  128. (p^._low = hcaselabel^._high + 1) then
  129. begin
  130. p^._low := hcaselabel^._low;
  131. freelabel(hcaselabel^._at);
  132. dispose(hcaselabel);
  133. end
  134. else
  135. insertlabel(p^.less)
  136. else
  137. if (p^._high<hcaselabel^._low) and
  138. (p^._high<hcaselabel^._high) then
  139. if (hcaselabel^.statement = p^.statement) and
  140. (p^._high+1 = hcaselabel^._low) then
  141. begin
  142. p^._high := hcaselabel^._high;
  143. freelabel(hcaselabel^._at);
  144. dispose(hcaselabel);
  145. end
  146. else
  147. insertlabel(p^.greater)
  148. else Message(parser_e_double_caselabel);
  149. end;
  150. begin
  151. new(hcaselabel);
  152. hcaselabel^.less:=nil;
  153. hcaselabel^.greater:=nil;
  154. hcaselabel^.statement:=aktcaselabel;
  155. hcaselabel^.firstlabel:=first;
  156. getlabel(hcaselabel^._at);
  157. hcaselabel^._low:=l;
  158. hcaselabel^._high:=h;
  159. insertlabel(root);
  160. end;
  161. var
  162. code,caseexpr,p,instruc,elseblock : ptree;
  163. hl1,hl2 : longint;
  164. casedeferror : boolean;
  165. begin
  166. consume(_CASE);
  167. caseexpr:=comp_expr(true);
  168. { determines result type }
  169. cleartempgen;
  170. do_firstpass(caseexpr);
  171. casedeferror:=false;
  172. casedef:=caseexpr^.resulttype;
  173. if not(is_ordinal(casedef) or is_64bitint(casedef)) then
  174. begin
  175. Message(type_e_ordinal_expr_expected);
  176. { set error flag so no rangechecks are done }
  177. casedeferror:=true;
  178. end;
  179. consume(_OF);
  180. inc(statement_level);
  181. root:=nil;
  182. instruc:=nil;
  183. repeat
  184. getlabel(aktcaselabel);
  185. firstlabel:=true;
  186. { may be an instruction has more case labels }
  187. repeat
  188. p:=expr;
  189. cleartempgen;
  190. do_firstpass(p);
  191. hl1:=0;
  192. hl2:=0;
  193. if (p^.treetype=rangen) then
  194. begin
  195. { type checking for case statements }
  196. if is_subequal(casedef, p^.left^.resulttype) and
  197. is_subequal(casedef, p^.right^.resulttype) then
  198. begin
  199. hl1:=get_ordinal_value(p^.left);
  200. hl2:=get_ordinal_value(p^.right);
  201. if hl1>hl2 then
  202. Message(parser_e_case_lower_less_than_upper_bound);
  203. if not casedeferror then
  204. begin
  205. testrange(casedef,hl1);
  206. testrange(casedef,hl2);
  207. end;
  208. end
  209. else
  210. Message(parser_e_case_mismatch);
  211. newcaselabel(hl1,hl2,firstlabel);
  212. end
  213. else
  214. begin
  215. { type checking for case statements }
  216. if not is_subequal(casedef, p^.resulttype) then
  217. Message(parser_e_case_mismatch);
  218. hl1:=get_ordinal_value(p);
  219. if not casedeferror then
  220. testrange(casedef,hl1);
  221. newcaselabel(hl1,hl1,firstlabel);
  222. end;
  223. disposetree(p);
  224. if token=_COMMA then
  225. consume(_COMMA)
  226. else
  227. break;
  228. firstlabel:=false;
  229. until false;
  230. consume(_COLON);
  231. { handles instruction block }
  232. p:=gensinglenode(labeln,statement);
  233. p^.labelnr:=aktcaselabel;
  234. { concats instruction }
  235. instruc:=gennode(statementn,instruc,p);
  236. if not((token=_ELSE) or (token=_OTHERWISE) or (token=_END)) then
  237. consume(_SEMICOLON);
  238. until (token=_ELSE) or (token=_OTHERWISE) or (token=_END);
  239. if (token=_ELSE) or (token=_OTHERWISE) then
  240. begin
  241. if not try_to_consume(_ELSE) then
  242. consume(_OTHERWISE);
  243. elseblock:=statements_til_end;
  244. end
  245. else
  246. begin
  247. elseblock:=nil;
  248. consume(_END);
  249. end;
  250. dec(statement_level);
  251. code:=gencasenode(caseexpr,instruc,root);
  252. code^.elseblock:=elseblock;
  253. case_statement:=code;
  254. end;
  255. function repeat_statement : ptree;
  256. var
  257. first,last,p_e : ptree;
  258. begin
  259. consume(_REPEAT);
  260. first:=nil;
  261. inc(statement_level);
  262. while token<>_UNTIL do
  263. begin
  264. if first=nil then
  265. begin
  266. last:=gennode(statementn,nil,statement);
  267. first:=last;
  268. end
  269. else
  270. begin
  271. last^.left:=gennode(statementn,nil,statement);
  272. last:=last^.left;
  273. end;
  274. if not try_to_consume(_SEMICOLON) then
  275. break;
  276. emptystats;
  277. end;
  278. consume(_UNTIL);
  279. dec(statement_level);
  280. first:=gensinglenode(blockn,first);
  281. p_e:=comp_expr(true);
  282. repeat_statement:=genloopnode(repeatn,p_e,first,nil,false);
  283. end;
  284. function while_statement : ptree;
  285. var
  286. p_e,p_a : ptree;
  287. begin
  288. consume(_WHILE);
  289. p_e:=comp_expr(true);
  290. consume(_DO);
  291. p_a:=statement;
  292. while_statement:=genloopnode(whilen,p_e,p_a,nil,false);
  293. end;
  294. function for_statement : ptree;
  295. var
  296. p_e,tovalue,p_a : ptree;
  297. backward : boolean;
  298. begin
  299. { parse loop header }
  300. consume(_FOR);
  301. p_e:=expr;
  302. if token=_DOWNTO then
  303. begin
  304. consume(_DOWNTO);
  305. backward:=true;
  306. end
  307. else
  308. begin
  309. consume(_TO);
  310. backward:=false;
  311. end;
  312. tovalue:=comp_expr(true);
  313. consume(_DO);
  314. { ... now the instruction }
  315. p_a:=statement;
  316. for_statement:=genloopnode(forn,p_e,tovalue,p_a,backward);
  317. end;
  318. function _with_statement : ptree;
  319. var
  320. right,hp,p : ptree;
  321. i,levelcount : longint;
  322. withsymtable,symtab : psymtable;
  323. obj : pobjectdef;
  324. begin
  325. Must_be_valid:=false;
  326. p:=comp_expr(true);
  327. do_firstpass(p);
  328. right:=nil;
  329. if (not codegenerror) and
  330. (p^.resulttype^.deftype in [objectdef,recorddef]) then
  331. begin
  332. case p^.resulttype^.deftype of
  333. objectdef : begin
  334. obj:=pobjectdef(p^.resulttype);
  335. withsymtable:=new(pwithsymtable,init);
  336. withsymtable^.symsearch:=obj^.symtable^.symsearch;
  337. withsymtable^.defowner:=obj;
  338. symtab:=withsymtable;
  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. levelcount:=1;
  345. obj:=obj^.childof;
  346. while assigned(obj) do
  347. begin
  348. symtab^.next:=new(pwithsymtable,init);
  349. symtab:=symtab^.next;
  350. symtab^.symsearch:=obj^.symtable^.symsearch;
  351. if (p^.treetype=loadn) and
  352. (p^.symtable=aktprocsym^.definition^.localst) then
  353. pwithsymtable(symtab)^.direct_with:=true;
  354. {symtab^.withnode:=p; not yet allocated !! }
  355. pwithsymtable(symtab)^.withrefnode:=p;
  356. symtab^.defowner:=obj;
  357. obj:=obj^.childof;
  358. inc(levelcount);
  359. end;
  360. symtab^.next:=symtablestack;
  361. symtablestack:=withsymtable;
  362. end;
  363. recorddef : begin
  364. symtab:=precorddef(p^.resulttype)^.symtable;
  365. levelcount:=1;
  366. withsymtable:=new(pwithsymtable,init);
  367. withsymtable^.symsearch:=symtab^.symsearch;
  368. withsymtable^.next:=symtablestack;
  369. if (p^.treetype=loadn) and
  370. (p^.symtable=aktprocsym^.definition^.localst) then
  371. pwithsymtable(withsymtable)^.direct_with:=true;
  372. {symtab^.withnode:=p; not yet allocated !! }
  373. pwithsymtable(withsymtable)^.withrefnode:=p;
  374. withsymtable^.defowner:=obj;
  375. symtablestack:=withsymtable;
  376. end;
  377. end;
  378. if token=_COMMA then
  379. begin
  380. consume(_COMMA);
  381. {$ifdef tp}
  382. right:=_with_statement;
  383. {$else}
  384. right:=_with_statement();
  385. {$endif}
  386. end
  387. else
  388. begin
  389. consume(_DO);
  390. if token<>_SEMICOLON then
  391. right:=statement
  392. else
  393. right:=nil;
  394. end;
  395. for i:=1 to levelcount do
  396. symtablestack:=symtablestack^.next;
  397. _with_statement:=genwithnode(pwithsymtable(withsymtable),p,right,levelcount);
  398. end
  399. else
  400. begin
  401. Message(parser_e_false_with_expr);
  402. { try to recover from error }
  403. if token=_COMMA then
  404. begin
  405. consume(_COMMA);
  406. {$ifdef tp}
  407. hp:=_with_statement;
  408. {$else}
  409. hp:=_with_statement();
  410. {$endif}
  411. end
  412. else
  413. begin
  414. consume(_DO);
  415. { ignore all }
  416. if token<>_SEMICOLON then
  417. statement;
  418. end;
  419. _with_statement:=nil;
  420. end;
  421. end;
  422. function with_statement : ptree;
  423. begin
  424. consume(_WITH);
  425. with_statement:=_with_statement;
  426. end;
  427. function raise_statement : ptree;
  428. var
  429. p1,p2 : ptree;
  430. begin
  431. p1:=nil;
  432. p2:=nil;
  433. consume(_RAISE);
  434. if token<>_SEMICOLON then
  435. begin
  436. p1:=comp_expr(true);
  437. if (idtoken=_AT) then
  438. begin
  439. consume(_ID);
  440. p2:=comp_expr(true);
  441. end;
  442. end
  443. else
  444. begin
  445. if not(in_except_block) then
  446. Message(parser_e_no_reraise_possible);
  447. end;
  448. raise_statement:=gennode(raisen,p1,p2);
  449. end;
  450. function try_statement : ptree;
  451. var
  452. p_try_block,p_finally_block,first,last,
  453. p_default,p_specific,hp : ptree;
  454. ot : pobjectdef;
  455. sym : pvarsym;
  456. old_in_except_block : boolean;
  457. exceptsymtable : psymtable;
  458. objname : stringid;
  459. begin
  460. procinfo^.flags:=procinfo^.flags or
  461. pi_uses_exceptions;
  462. p_default:=nil;
  463. p_specific:=nil;
  464. { read statements to try }
  465. consume(_TRY);
  466. first:=nil;
  467. inc(statement_level);
  468. while (token<>_FINALLY) and (token<>_EXCEPT) do
  469. begin
  470. if first=nil then
  471. begin
  472. last:=gennode(statementn,nil,statement);
  473. first:=last;
  474. end
  475. else
  476. begin
  477. last^.left:=gennode(statementn,nil,statement);
  478. last:=last^.left;
  479. end;
  480. if not try_to_consume(_SEMICOLON) then
  481. break;
  482. emptystats;
  483. end;
  484. p_try_block:=gensinglenode(blockn,first);
  485. if try_to_consume(_FINALLY) then
  486. begin
  487. p_finally_block:=statements_til_end;
  488. try_statement:=gennode(tryfinallyn,p_try_block,p_finally_block);
  489. dec(statement_level);
  490. end
  491. else
  492. begin
  493. consume(_EXCEPT);
  494. old_in_except_block:=in_except_block;
  495. in_except_block:=true;
  496. p_specific:=nil;
  497. if token=_ON then
  498. { catch specific exceptions }
  499. begin
  500. repeat
  501. consume(_ON);
  502. if token=_ID then
  503. begin
  504. getsym(pattern,false);
  505. objname:=pattern;
  506. consume(_ID);
  507. { is a explicit name for the exception given ? }
  508. if try_to_consume(_COLON) then
  509. begin
  510. getsym(pattern,true);
  511. consume(_ID);
  512. if srsym^.typ=unitsym then
  513. begin
  514. consume(_POINT);
  515. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  516. consume(_ID);
  517. end;
  518. if (srsym^.typ=typesym) and
  519. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  520. pobjectdef(ptypesym(srsym)^.definition)^.is_class then
  521. ot:=pobjectdef(ptypesym(srsym)^.definition)
  522. else
  523. begin
  524. ot:=pobjectdef(generrordef);
  525. if (srsym^.typ=typesym) then
  526. Message1(type_e_class_type_expected,ptypesym(srsym)^.definition^.typename)
  527. else
  528. Message1(type_e_class_type_expected,ot^.typename);
  529. end;
  530. sym:=new(pvarsym,init(objname,ot));
  531. exceptsymtable:=new(psymtable,init(stt_exceptsymtable));
  532. exceptsymtable^.insert(sym);
  533. { insert the exception symtable stack }
  534. exceptsymtable^.next:=symtablestack;
  535. symtablestack:=exceptsymtable;
  536. end
  537. else
  538. begin
  539. { only exception type }
  540. if srsym^.typ=unitsym then
  541. begin
  542. consume(_POINT);
  543. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  544. consume(_ID);
  545. end;
  546. if (srsym^.typ=typesym) and
  547. (ptypesym(srsym)^.definition^.deftype=objectdef) and
  548. pobjectdef(ptypesym(srsym)^.definition)^.is_class then
  549. ot:=pobjectdef(ptypesym(srsym)^.definition)
  550. else
  551. begin
  552. ot:=pobjectdef(generrordef);
  553. if (srsym^.typ=typesym) then
  554. Message1(type_e_class_type_expected,ptypesym(srsym)^.definition^.typename)
  555. else
  556. Message1(type_e_class_type_expected,ot^.typename);
  557. end;
  558. exceptsymtable:=nil;
  559. end;
  560. end
  561. else
  562. consume(_ID);
  563. consume(_DO);
  564. hp:=gennode(onn,nil,statement);
  565. if ot^.deftype=errordef then
  566. begin
  567. disposetree(hp);
  568. hp:=genzeronode(errorn);
  569. end;
  570. if p_specific=nil then
  571. begin
  572. last:=hp;
  573. p_specific:=last;
  574. end
  575. else
  576. begin
  577. last^.left:=hp;
  578. last:=last^.left;
  579. end;
  580. { set the informations }
  581. last^.excepttype:=ot;
  582. last^.exceptsymtable:=exceptsymtable;
  583. last^.disposetyp:=dt_onn;
  584. { remove exception symtable }
  585. if assigned(exceptsymtable) then
  586. dellexlevel;
  587. if not try_to_consume(_SEMICOLON) then
  588. break;
  589. emptystats;
  590. until (token=_END) or(token=_ELSE);
  591. if token=_ELSE then
  592. { catch the other exceptions }
  593. begin
  594. consume(_ELSE);
  595. p_default:=statements_til_end;
  596. end
  597. else
  598. consume(_END);
  599. end
  600. else
  601. { catch all exceptions }
  602. begin
  603. p_default:=statements_til_end;
  604. end;
  605. dec(statement_level);
  606. in_except_block:=old_in_except_block;
  607. try_statement:=genloopnode(tryexceptn,p_try_block,p_specific,p_default,false);
  608. end;
  609. end;
  610. function exit_statement : ptree;
  611. var
  612. p : ptree;
  613. begin
  614. consume(_EXIT);
  615. if try_to_consume(_LKLAMMER) then
  616. begin
  617. p:=comp_expr(true);
  618. consume(_RKLAMMER);
  619. if in_except_block then
  620. Message(parser_e_exit_with_argument_not__possible);
  621. if procinfo^.retdef=pdef(voiddef) then
  622. Message(parser_e_void_function);
  623. {
  624. else
  625. procinfo^.funcret_is_valid:=true;
  626. }
  627. end
  628. else
  629. p:=nil;
  630. p:=gensinglenode(exitn,p);
  631. p^.resulttype:=procinfo^.retdef;
  632. exit_statement:=p;
  633. end;
  634. function _asm_statement : ptree;
  635. var
  636. asmstat : ptree;
  637. Marker : Pai;
  638. begin
  639. Inside_asm_statement:=true;
  640. case aktasmmode of
  641. asmmode_none : ; { just be there to allow to a compile without
  642. any assembler readers }
  643. {$ifdef i386}
  644. {$ifndef NoRA386Att}
  645. asmmode_i386_att:
  646. asmstat:=ra386att.assemble;
  647. {$endif NoRA386Att}
  648. {$ifndef NoRA386Int}
  649. asmmode_i386_intel:
  650. asmstat:=ra386int.assemble;
  651. {$endif NoRA386Int}
  652. {$ifndef NoRA386Dir}
  653. asmmode_i386_direct:
  654. begin
  655. if not target_asm.allowdirect then
  656. Message(parser_f_direct_assembler_not_allowed);
  657. if (pocall_inline in aktprocsym^.definition^.proccalloptions) then
  658. Begin
  659. Message1(parser_w_not_supported_for_inline,'direct asm');
  660. Message(parser_w_inlining_disabled);
  661. {$ifdef INCLUDEOK}
  662. exclude(aktprocsym^.definition^.proccalloptions,pocall_inline);
  663. {$else}
  664. aktprocsym^.definition^.proccalloptions:=aktprocsym^.definition^.proccalloptions-[pocall_inline];
  665. {$endif}
  666. End;
  667. asmstat:=ra386dir.assemble;
  668. end;
  669. {$endif NoRA386Dir}
  670. {$endif}
  671. {$ifdef m68k}
  672. {$ifndef NoRA68kMot}
  673. asmmode_m68k_mot:
  674. asmstat:=ra68kmot.assemble;
  675. {$endif NoRA68kMot}
  676. {$endif}
  677. else
  678. Message(parser_f_assembler_reader_not_supported);
  679. end;
  680. { Read first the _ASM statement }
  681. consume(_ASM);
  682. {$ifndef newcg}
  683. { END is read }
  684. if try_to_consume(_LECKKLAMMER) then
  685. begin
  686. { it's possible to specify the modified registers }
  687. asmstat^.object_preserved:=true;
  688. if token<>_RECKKLAMMER then
  689. repeat
  690. { uppercase, because it's a CSTRING }
  691. uppervar(pattern);
  692. {$ifdef i386}
  693. if pattern='EAX' then
  694. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  695. else if pattern='EBX' then
  696. usedinproc:=usedinproc or ($80 shr byte(R_EBX))
  697. else if pattern='ECX' then
  698. usedinproc:=usedinproc or ($80 shr byte(R_ECX))
  699. else if pattern='EDX' then
  700. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  701. else if pattern='ESI' then
  702. begin
  703. usedinproc:=usedinproc or ($80 shr byte(R_ESI));
  704. asmstat^.object_preserved:=false;
  705. end
  706. else if pattern='EDI' then
  707. usedinproc:=usedinproc or ($80 shr byte(R_EDI))
  708. {$endif i386}
  709. {$ifdef m68k}
  710. if pattern='D0' then
  711. usedinproc:=usedinproc or ($800 shr word(R_D0))
  712. else if pattern='D1' then
  713. usedinproc:=usedinproc or ($800 shr word(R_D1))
  714. else if pattern='D6' then
  715. usedinproc:=usedinproc or ($800 shr word(R_D6))
  716. else if pattern='A0' then
  717. usedinproc:=usedinproc or ($800 shr word(R_A0))
  718. else if pattern='A1' then
  719. usedinproc:=usedinproc or ($800 shr word(R_A1))
  720. {$endif m68k}
  721. else consume(_RECKKLAMMER);
  722. consume(_CSTRING);
  723. if not try_to_consume(_COMMA) then
  724. break;
  725. until false;
  726. consume(_RECKKLAMMER);
  727. end
  728. else usedinproc:=$ff;
  729. {$endif newcg}
  730. { mark the start and the end of the assembler block for the optimizer }
  731. If Assigned(AsmStat^.p_asm) Then
  732. Begin
  733. Marker := New(Pai_Marker, Init(AsmBlockStart));
  734. AsmStat^.p_asm^.Insert(Marker);
  735. Marker := New(Pai_Marker, Init(AsmBlockEnd));
  736. AsmStat^.p_asm^.Concat(Marker);
  737. End;
  738. Inside_asm_statement:=false;
  739. _asm_statement:=asmstat;
  740. end;
  741. function new_dispose_statement : ptree;
  742. var
  743. p,p2 : ptree;
  744. ht : ttoken;
  745. again : boolean; { dummy for do_proc_call }
  746. destrukname : stringid;
  747. sym : psym;
  748. classh : pobjectdef;
  749. pd,pd2 : pdef;
  750. store_valid : boolean;
  751. tt : ttreetyp;
  752. begin
  753. ht:=token;
  754. if try_to_consume(_NEW) then
  755. tt:=hnewn
  756. else
  757. begin
  758. consume(_DISPOSE);
  759. tt:=hdisposen;
  760. end;
  761. consume(_LKLAMMER);
  762. { displaced here to avoid warnings in BP mode (PM) }
  763. Store_valid := Must_be_valid;
  764. if tt=hnewn then
  765. Must_be_valid := False
  766. else
  767. Must_be_valid:=true;
  768. p:=comp_expr(true);
  769. { calc return type }
  770. cleartempgen;
  771. do_firstpass(p);
  772. Must_be_valid := Store_valid;
  773. {var o:Pobject;
  774. begin
  775. new(o,init); (*Also a valid new statement*)
  776. end;}
  777. if try_to_consume(_COMMA) then
  778. begin
  779. { extended syntax of new and dispose }
  780. { function styled new is handled in factor }
  781. { destructors have no parameters }
  782. destrukname:=pattern;
  783. consume(_ID);
  784. pd:=p^.resulttype;
  785. if pd=nil then
  786. pd:=generrordef;
  787. pd2:=pd;
  788. if (pd^.deftype<>pointerdef) then
  789. begin
  790. Message1(type_e_pointer_type_expected,pd^.typename);
  791. p:=factor(false);
  792. consume(_RKLAMMER);
  793. new_dispose_statement:=genzeronode(errorn);
  794. exit;
  795. end;
  796. { first parameter must be an object or class }
  797. if ppointerdef(pd)^.definition^.deftype<>objectdef then
  798. begin
  799. Message(parser_e_pointer_to_class_expected);
  800. new_dispose_statement:=factor(false);
  801. consume_all_until(_RKLAMMER);
  802. consume(_RKLAMMER);
  803. exit;
  804. end;
  805. { check, if the first parameter is a pointer to a _class_ }
  806. classh:=pobjectdef(ppointerdef(pd)^.definition);
  807. if classh^.is_class then
  808. begin
  809. Message(parser_e_no_new_or_dispose_for_classes);
  810. new_dispose_statement:=factor(false);
  811. consume_all_until(_RKLAMMER);
  812. consume(_RKLAMMER);
  813. exit;
  814. end;
  815. { search cons-/destructor, also in parent classes }
  816. sym:=search_class_member(classh,pattern);
  817. { the second parameter of new/dispose must be a call }
  818. { to a cons-/destructor }
  819. if (not assigned(sym)) or (sym^.typ<>procsym) then
  820. begin
  821. Message(parser_e_expr_have_to_be_destructor_call);
  822. new_dispose_statement:=genzeronode(errorn);
  823. end
  824. else
  825. begin
  826. p2:=gensinglenode(tt,p);
  827. if ht=_NEW then
  828. begin
  829. { Constructors can take parameters.}
  830. p2^.resulttype:=ppointerdef(pd)^.definition;
  831. do_member_read(false,sym,p2,pd,again);
  832. end
  833. else
  834. { destructors can't.}
  835. p2:=genmethodcallnode(pprocsym(sym),srsymtable,p2);
  836. { we need the real called method }
  837. cleartempgen;
  838. do_firstpass(p2);
  839. if not codegenerror then
  840. begin
  841. if (ht=_NEW) and (p2^.procdefinition^.proctypeoption<>potype_constructor) then
  842. Message(parser_e_expr_have_to_be_constructor_call);
  843. if (ht=_DISPOSE) and (p2^.procdefinition^.proctypeoption<>potype_destructor) then
  844. Message(parser_e_expr_have_to_be_destructor_call);
  845. if ht=_NEW then
  846. begin
  847. p2:=gennode(assignn,getcopy(p),gensinglenode(newn,p2));
  848. p2^.right^.resulttype:=pd2;
  849. end;
  850. end;
  851. new_dispose_statement:=p2;
  852. end;
  853. end
  854. else
  855. begin
  856. if p^.resulttype=nil then
  857. p^.resulttype:=generrordef;
  858. if (p^.resulttype^.deftype<>pointerdef) then
  859. Begin
  860. Message1(type_e_pointer_type_expected,p^.resulttype^.typename);
  861. new_dispose_statement:=genzeronode(errorn);
  862. end
  863. else
  864. begin
  865. if (ppointerdef(p^.resulttype)^.definition^.deftype=objectdef) and
  866. (oo_has_vmt in pobjectdef(ppointerdef(p^.resulttype)^.definition)^.objectoptions) then
  867. Message(parser_w_use_extended_syntax_for_objects);
  868. if (ppointerdef(p^.resulttype)^.definition^.deftype=orddef) and
  869. (porddef(ppointerdef(p^.resulttype)^.definition)^.typ=uvoid) then
  870. if (m_tp in aktmodeswitches) or
  871. (m_delphi in aktmodeswitches) then
  872. Message(parser_w_no_new_dispose_on_void_pointers)
  873. else
  874. Message(parser_e_no_new_dispose_on_void_pointers);
  875. case ht of
  876. _NEW : new_dispose_statement:=gensinglenode(simplenewn,p);
  877. _DISPOSE : new_dispose_statement:=gensinglenode(simpledisposen,p);
  878. end;
  879. end;
  880. end;
  881. consume(_RKLAMMER);
  882. end;
  883. function statement_block(starttoken : ttoken) : ptree;
  884. var
  885. first,last : ptree;
  886. filepos : tfileposinfo;
  887. begin
  888. first:=nil;
  889. filepos:=tokenpos;
  890. consume(starttoken);
  891. inc(statement_level);
  892. while not(token in [_END,_FINALIZATION]) do
  893. begin
  894. if first=nil then
  895. begin
  896. last:=gennode(statementn,nil,statement);
  897. first:=last;
  898. end
  899. else
  900. begin
  901. last^.left:=gennode(statementn,nil,statement);
  902. last:=last^.left;
  903. end;
  904. if (token in [_END,_FINALIZATION]) then
  905. break
  906. else
  907. begin
  908. { if no semicolon, then error and go on }
  909. if token<>_SEMICOLON then
  910. begin
  911. consume(_SEMICOLON);
  912. consume_all_until(_SEMICOLON);
  913. end;
  914. consume(_SEMICOLON);
  915. end;
  916. emptystats;
  917. end;
  918. { don't consume the finalization token, it is consumed when
  919. reading the finalization block, but allow it only after
  920. an initalization ! }
  921. if (starttoken<>_INITIALIZATION) or (token<>_FINALIZATION) then
  922. consume(_END);
  923. dec(statement_level);
  924. last:=gensinglenode(blockn,first);
  925. set_tree_filepos(last,filepos);
  926. statement_block:=last;
  927. end;
  928. function statement : ptree;
  929. var
  930. p : ptree;
  931. code : ptree;
  932. labelnr : pasmlabel;
  933. filepos : tfileposinfo;
  934. label
  935. ready;
  936. begin
  937. filepos:=tokenpos;
  938. case token of
  939. _GOTO : begin
  940. if not(cs_support_goto in aktmoduleswitches)then
  941. Message(sym_e_goto_and_label_not_supported);
  942. consume(_GOTO);
  943. if (token<>_INTCONST) and (token<>_ID) then
  944. begin
  945. Message(sym_e_label_not_found);
  946. code:=genzeronode(errorn);
  947. end
  948. else
  949. begin
  950. getsym(pattern,true);
  951. consume(token);
  952. if srsym^.typ<>labelsym then
  953. begin
  954. Message(sym_e_id_is_no_label_id);
  955. code:=genzeronode(errorn);
  956. end
  957. else
  958. code:=genlabelnode(goton,
  959. plabelsym(srsym)^.lab);
  960. end;
  961. end;
  962. _BEGIN : code:=statement_block(_BEGIN);
  963. _IF : code:=if_statement;
  964. _CASE : code:=case_statement;
  965. _REPEAT : code:=repeat_statement;
  966. _WHILE : code:=while_statement;
  967. _FOR : code:=for_statement;
  968. _NEW,_DISPOSE : code:=new_dispose_statement;
  969. _WITH : code:=with_statement;
  970. _TRY : code:=try_statement;
  971. _RAISE : code:=raise_statement;
  972. { semicolons,else until and end are ignored }
  973. _SEMICOLON,
  974. _ELSE,
  975. _UNTIL,
  976. _END:
  977. code:=genzeronode(niln);
  978. _FAIL : begin
  979. { internalerror(100); }
  980. if (aktprocsym^.definition^.proctypeoption<>potype_constructor) then
  981. Message(parser_e_fail_only_in_constructor);
  982. consume(_FAIL);
  983. code:=genzeronode(failn);
  984. end;
  985. _EXIT : code:=exit_statement;
  986. _ASM : begin
  987. code:=_asm_statement;
  988. end;
  989. _EOF : begin
  990. Message(scan_f_end_of_file);
  991. end;
  992. else
  993. begin
  994. if (token in [_INTCONST,_ID]) then
  995. begin
  996. getsym(pattern,true);
  997. lastsymknown:=true;
  998. lastsrsym:=srsym;
  999. { it is NOT necessarily the owner
  1000. it can be a withsymtable !!! }
  1001. lastsrsymtable:=srsymtable;
  1002. if assigned(srsym) and (srsym^.typ=labelsym) then
  1003. begin
  1004. consume(token);
  1005. consume(_COLON);
  1006. if plabelsym(srsym)^.defined then
  1007. Message(sym_e_label_already_defined);
  1008. plabelsym(srsym)^.defined:=true;
  1009. { statement modifies srsym }
  1010. labelnr:=plabelsym(srsym)^.lab;
  1011. lastsymknown:=false;
  1012. { the pointer to the following instruction }
  1013. { isn't a very clean way }
  1014. code:=gensinglenode(labeln,statement{$ifndef tp}(){$endif});
  1015. code^.labelnr:=labelnr;
  1016. { sorry, but there is a jump the easiest way }
  1017. goto ready;
  1018. end;
  1019. end;
  1020. p:=expr;
  1021. if not(p^.treetype in [calln,assignn,breakn,inlinen,
  1022. continuen]) then
  1023. Message(cg_e_illegal_expression);
  1024. { specify that we don't use the value returned by the call }
  1025. { Question : can this be also improtant
  1026. for inlinen ??
  1027. it is used for :
  1028. - dispose of temp stack space
  1029. - dispose on FPU stack }
  1030. if p^.treetype=calln then
  1031. p^.return_value_used:=false;
  1032. code:=p;
  1033. end;
  1034. end;
  1035. ready:
  1036. if assigned(code) then
  1037. set_tree_filepos(code,filepos);
  1038. statement:=code;
  1039. end;
  1040. function block(islibrary : boolean) : ptree;
  1041. var
  1042. funcretsym : pfuncretsym;
  1043. storepos : tfileposinfo;
  1044. begin
  1045. if procinfo^.retdef<>pdef(voiddef) then
  1046. begin
  1047. { if the current is a function aktprocsym is non nil }
  1048. { and there is a local symtable set }
  1049. storepos:=tokenpos;
  1050. tokenpos:=aktprocsym^.fileinfo;
  1051. funcretsym:=new(pfuncretsym,init(aktprocsym^.name,procinfo));
  1052. { insert in local symtable }
  1053. symtablestack^.insert(funcretsym);
  1054. tokenpos:=storepos;
  1055. if ret_in_acc(procinfo^.retdef) or (procinfo^.retdef^.deftype=floatdef) then
  1056. procinfo^.retoffset:=-funcretsym^.address;
  1057. procinfo^.funcretsym:=funcretsym;
  1058. { insert result also if support is on }
  1059. if (m_result in aktmodeswitches) then
  1060. begin
  1061. procinfo^.resultfuncretsym:=new(pfuncretsym,init('RESULT',procinfo));
  1062. symtablestack^.insert(procinfo^.resultfuncretsym);
  1063. end;
  1064. end;
  1065. read_declarations(islibrary);
  1066. { temporary space is set, while the BEGIN of the procedure }
  1067. if (symtablestack^.symtabletype=localsymtable) then
  1068. procinfo^.firsttemp := -symtablestack^.datasize
  1069. else procinfo^.firsttemp := 0;
  1070. { space for the return value }
  1071. { !!!!! this means that we can not set the return value
  1072. in a subfunction !!!!! }
  1073. { because we don't know yet where the address is }
  1074. if procinfo^.retdef<>pdef(voiddef) then
  1075. begin
  1076. if ret_in_acc(procinfo^.retdef) or (procinfo^.retdef^.deftype=floatdef) then
  1077. { if (procinfo^.retdef^.deftype=orddef) or
  1078. (procinfo^.retdef^.deftype=pointerdef) or
  1079. (procinfo^.retdef^.deftype=enumdef) or
  1080. (procinfo^.retdef^.deftype=procvardef) or
  1081. (procinfo^.retdef^.deftype=floatdef) or
  1082. (
  1083. (procinfo^.retdef^.deftype=setdef) and
  1084. (psetdef(procinfo^.retdef)^.settype=smallset)
  1085. ) then }
  1086. begin
  1087. { the space has been set in the local symtable }
  1088. procinfo^.retoffset:=-funcretsym^.address;
  1089. if ((procinfo^.flags and pi_operator)<>0) and
  1090. assigned(opsym) then
  1091. {opsym^.address:=procinfo^.call_offset; is wrong PM }
  1092. opsym^.address:=-procinfo^.retoffset;
  1093. { eax is modified by a function }
  1094. {$ifndef newcg}
  1095. {$ifdef i386}
  1096. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  1097. if is_64bitint(procinfo^.retdef) then
  1098. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  1099. {$endif}
  1100. {$ifdef m68k}
  1101. usedinproc:=usedinproc or ($800 shr word(R_D0));
  1102. if is_64bitint(procinfo^.retdef) then
  1103. usedinproc:=usedinproc or ($800 shr byte(R_D1))
  1104. {$endif}
  1105. {$endif newcg}
  1106. end;
  1107. end;
  1108. {Unit initialization?.}
  1109. if (lexlevel=unit_init_level) and (current_module^.is_unit) then
  1110. if (token=_END) then
  1111. begin
  1112. consume(_END);
  1113. block:=nil;
  1114. end
  1115. else
  1116. begin
  1117. if token=_INITIALIZATION then
  1118. begin
  1119. current_module^.flags:=current_module^.flags or uf_init;
  1120. block:=statement_block(_INITIALIZATION);
  1121. end
  1122. else if (token=_FINALIZATION) then
  1123. begin
  1124. if (current_module^.flags and uf_finalize)<>0 then
  1125. block:=statement_block(_FINALIZATION)
  1126. else
  1127. begin
  1128. block:=nil;
  1129. exit;
  1130. end;
  1131. end
  1132. else
  1133. begin
  1134. current_module^.flags:=current_module^.flags or uf_init;
  1135. block:=statement_block(_BEGIN);
  1136. end;
  1137. end
  1138. else
  1139. block:=statement_block(_BEGIN);
  1140. end;
  1141. function assembler_block : ptree;
  1142. begin
  1143. read_declarations(false);
  1144. { temporary space is set, while the BEGIN of the procedure }
  1145. if symtablestack^.symtabletype=localsymtable then
  1146. procinfo^.firsttemp := -symtablestack^.datasize
  1147. else
  1148. procinfo^.firsttemp := 0;
  1149. { assembler code does not allocate }
  1150. { space for the return value }
  1151. if procinfo^.retdef<>pdef(voiddef) then
  1152. begin
  1153. if ret_in_acc(procinfo^.retdef) then
  1154. begin
  1155. { in assembler code the result should be directly in %eax
  1156. procinfo^.retoffset:=procinfo^.firsttemp-procinfo^.retdef^.size;
  1157. procinfo^.firsttemp:=procinfo^.retoffset; }
  1158. {$ifndef newcg}
  1159. {$ifdef i386}
  1160. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  1161. {$endif}
  1162. {$ifdef m68k}
  1163. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1164. {$endif}
  1165. {$endif newcg}
  1166. end
  1167. {
  1168. else if not is_fpu(procinfo^.retdef) then
  1169. should we allow assembler functions of big elements ?
  1170. YES (FK)!!
  1171. Message(parser_e_asm_incomp_with_function_return);
  1172. }
  1173. end;
  1174. { set the framepointer to esp for assembler functions }
  1175. { but only if the are no local variables }
  1176. { added no parameter also (PM) }
  1177. { disable for methods, because self pointer is expected }
  1178. { at -8(%ebp) (JM) }
  1179. if not(assigned(procinfo^._class)) and
  1180. (po_assembler in aktprocsym^.definition^.procoptions) and
  1181. (aktprocsym^.definition^.localst^.datasize=0) and
  1182. (aktprocsym^.definition^.parast^.datasize=0) and
  1183. not(ret_in_param(aktprocsym^.definition^.retdef)) then
  1184. begin
  1185. procinfo^.framepointer:=stack_pointer;
  1186. { set the right value for parameters }
  1187. dec(aktprocsym^.definition^.parast^.address_fixup,target_os.size_of_pointer);
  1188. dec(procinfo^.call_offset,target_os.size_of_pointer);
  1189. end;
  1190. { force the asm statement }
  1191. if token<>_ASM then
  1192. consume(_ASM);
  1193. procinfo^.Flags := procinfo^.Flags Or pi_is_assembler;
  1194. assembler_block:=_asm_statement;
  1195. { becuase the END is already read we need to get the
  1196. last_endtoken_filepos here (PFV) }
  1197. last_endtoken_filepos:=tokenpos;
  1198. end;
  1199. end.
  1200. {
  1201. $Log$
  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. }