pstatmnt.pas 55 KB

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