pstatmnt.pas 56 KB

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