pstatmnt.pas 57 KB

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