pstatmnt.pas 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644
  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) or is_64bitint(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 in_except_block then
  590. Message(parser_e_exit_with_argument_not__possible);
  591. if procinfo.retdef=pdef(voiddef) then
  592. Message(parser_e_void_function)
  593. else
  594. procinfo.funcret_is_valid:=true;
  595. end
  596. else
  597. p:=nil;
  598. p:=gensinglenode(exitn,p);
  599. p^.resulttype:=procinfo.retdef;
  600. exit_statement:=p;
  601. end;
  602. function _asm_statement : ptree;
  603. var
  604. asmstat : ptree;
  605. Marker : Pai;
  606. begin
  607. Inside_asm_statement:=true;
  608. case aktasmmode of
  609. asmmode_none : ; { just be there to allow to a compile without
  610. any assembler readers }
  611. {$ifdef i386}
  612. {$ifndef NoRA386Att}
  613. asmmode_i386_att:
  614. asmstat:=ra386att.assemble;
  615. {$endif NoRA386Att}
  616. {$ifndef NoRA386Int}
  617. asmmode_i386_intel:
  618. asmstat:=ra386int.assemble;
  619. {$endif NoRA386Int}
  620. {$ifndef NoRA386Dir}
  621. asmmode_i386_direct:
  622. begin
  623. if not target_asm.allowdirect then
  624. Message(parser_f_direct_assembler_not_allowed);
  625. if (aktprocsym^.definition^.options and poinline)<>0 then
  626. Begin
  627. Message1(parser_w_not_supported_for_inline,'direct asm');
  628. Message(parser_w_inlining_disabled);
  629. aktprocsym^.definition^.options:= aktprocsym^.definition^.options and not poinline;
  630. End;
  631. asmstat:=ra386dir.assemble;
  632. end;
  633. {$endif NoRA386Dir}
  634. {$endif}
  635. {$ifdef m68k}
  636. {$ifndef NoRA68kMot}
  637. asmmode_m68k_mot:
  638. asmstat:=ra68kmot.assemble;
  639. {$endif NoRA68kMot}
  640. {$endif}
  641. else
  642. Message(parser_f_assembler_reader_not_supported);
  643. end;
  644. { Read first the _ASM statement }
  645. consume(_ASM);
  646. { END is read }
  647. if try_to_consume(LECKKLAMMER) then
  648. begin
  649. { it's possible to specify the modified registers }
  650. asmstat^.object_preserved:=true;
  651. if token<>RECKKLAMMER then
  652. repeat
  653. { uppercase, because it's a CSTRING }
  654. uppervar(pattern);
  655. {$ifdef i386}
  656. if pattern='EAX' then
  657. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  658. else if pattern='EBX' then
  659. usedinproc:=usedinproc or ($80 shr byte(R_EBX))
  660. else if pattern='ECX' then
  661. usedinproc:=usedinproc or ($80 shr byte(R_ECX))
  662. else if pattern='EDX' then
  663. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  664. else if pattern='ESI' then
  665. begin
  666. usedinproc:=usedinproc or ($80 shr byte(R_ESI));
  667. asmstat^.object_preserved:=false;
  668. end
  669. else if pattern='EDI' then
  670. usedinproc:=usedinproc or ($80 shr byte(R_EDI))
  671. {$endif i386}
  672. {$ifdef m68k}
  673. if pattern='D0' then
  674. usedinproc:=usedinproc or ($800 shr word(R_D0))
  675. else if pattern='D1' then
  676. usedinproc:=usedinproc or ($800 shr word(R_D1))
  677. else if pattern='D6' then
  678. usedinproc:=usedinproc or ($800 shr word(R_D6))
  679. else if pattern='A0' then
  680. usedinproc:=usedinproc or ($800 shr word(R_A0))
  681. else if pattern='A1' then
  682. usedinproc:=usedinproc or ($800 shr word(R_A1))
  683. {$endif m68k}
  684. else consume(RECKKLAMMER);
  685. consume(CSTRING);
  686. if not try_to_consume(COMMA) then
  687. break;
  688. until false;
  689. consume(RECKKLAMMER);
  690. end
  691. else usedinproc:=$ff;
  692. { mark the start and the end of the assembler block for the optimizer }
  693. If Assigned(AsmStat^.p_asm) Then
  694. Begin
  695. Marker := New(Pai_Marker, Init(AsmBlockStart));
  696. AsmStat^.p_asm^.Insert(Marker);
  697. Marker := New(Pai_Marker, Init(AsmBlockEnd));
  698. AsmStat^.p_asm^.Concat(Marker);
  699. End;
  700. Inside_asm_statement:=false;
  701. _asm_statement:=asmstat;
  702. end;
  703. function new_dispose_statement : ptree;
  704. var
  705. p,p2 : ptree;
  706. ht : ttoken;
  707. again : boolean; { dummy for do_proc_call }
  708. destrukname : stringid;
  709. sym : psym;
  710. classh : pobjectdef;
  711. pd,pd2 : pdef;
  712. store_valid : boolean;
  713. tt : ttreetyp;
  714. begin
  715. ht:=token;
  716. if try_to_consume(_NEW) then
  717. tt:=hnewn
  718. else
  719. begin
  720. consume(_DISPOSE);
  721. tt:=hdisposen;
  722. end;
  723. consume(LKLAMMER);
  724. { displaced here to avoid warnings in BP mode (PM) }
  725. Store_valid := Must_be_valid;
  726. if tt=hnewn then
  727. Must_be_valid := False
  728. else
  729. Must_be_valid:=true;
  730. p:=comp_expr(true);
  731. { calc return type }
  732. cleartempgen;
  733. do_firstpass(p);
  734. Must_be_valid := Store_valid;
  735. {var o:Pobject;
  736. begin
  737. new(o,init); (*Also a valid new statement*)
  738. end;}
  739. if try_to_consume(COMMA) then
  740. begin
  741. { extended syntax of new and dispose }
  742. { function styled new is handled in factor }
  743. { destructors have no parameters }
  744. destrukname:=pattern;
  745. consume(ID);
  746. pd:=p^.resulttype;
  747. pd2:=pd;
  748. if (p^.resulttype = nil) or (pd^.deftype<>pointerdef) then
  749. begin
  750. Message(type_e_pointer_type_expected);
  751. p:=factor(false);
  752. consume(RKLAMMER);
  753. new_dispose_statement:=genzeronode(errorn);
  754. exit;
  755. end;
  756. { first parameter must be an object or class }
  757. if ppointerdef(pd)^.definition^.deftype<>objectdef then
  758. begin
  759. Message(parser_e_pointer_to_class_expected);
  760. new_dispose_statement:=factor(false);
  761. consume_all_until(RKLAMMER);
  762. consume(RKLAMMER);
  763. exit;
  764. end;
  765. { check, if the first parameter is a pointer to a _class_ }
  766. classh:=pobjectdef(ppointerdef(pd)^.definition);
  767. if (classh^.options and oo_is_class)<>0 then
  768. begin
  769. Message(parser_e_no_new_or_dispose_for_classes);
  770. new_dispose_statement:=factor(false);
  771. { while token<>RKLAMMER do
  772. consume(token); }
  773. consume_all_until(RKLAMMER);
  774. consume(RKLAMMER);
  775. exit;
  776. end;
  777. { search cons-/destructor, also in parent classes }
  778. sym:=search_class_member(classh,pattern);
  779. { the second parameter of new/dispose must be a call }
  780. { to a cons-/destructor }
  781. if (not assigned(sym)) or (sym^.typ<>procsym) then
  782. begin
  783. Message(parser_e_expr_have_to_be_destructor_call);
  784. new_dispose_statement:=genzeronode(errorn);
  785. end
  786. else
  787. begin
  788. p2:=gensinglenode(tt,p);
  789. if ht=_NEW then
  790. begin
  791. { Constructors can take parameters.}
  792. p2^.resulttype:=ppointerdef(pd)^.definition;
  793. do_member_read(false,sym,p2,pd,again);
  794. end
  795. else
  796. { destructors can't.}
  797. p2:=genmethodcallnode(pprocsym(sym),srsymtable,p2);
  798. { we need the real called method }
  799. cleartempgen;
  800. do_firstpass(p2);
  801. if not codegenerror then
  802. begin
  803. if (ht=_NEW) and ((p2^.procdefinition^.options and poconstructor)=0) then
  804. Message(parser_e_expr_have_to_be_constructor_call);
  805. if (ht=_DISPOSE) and ((p2^.procdefinition^.options and podestructor)=0) then
  806. Message(parser_e_expr_have_to_be_destructor_call);
  807. if ht=_NEW then
  808. begin
  809. p2:=gennode(assignn,getcopy(p),gensinglenode(newn,p2));
  810. p2^.right^.resulttype:=pd2;
  811. end;
  812. end;
  813. new_dispose_statement:=p2;
  814. end;
  815. end
  816. else
  817. begin
  818. if (p^.resulttype=nil) or (p^.resulttype^.deftype<>pointerdef) then
  819. Begin
  820. Message(type_e_pointer_type_expected);
  821. new_dispose_statement:=genzeronode(errorn);
  822. end
  823. else
  824. begin
  825. if (ppointerdef(p^.resulttype)^.definition^.deftype=objectdef) and
  826. ((pobjectdef(ppointerdef(p^.resulttype)^.definition)^.options and oo_hasvmt) <> 0) then
  827. Message(parser_w_use_extended_syntax_for_objects);
  828. if (ppointerdef(p^.resulttype)^.definition^.deftype=orddef) and
  829. (porddef(ppointerdef(p^.resulttype)^.definition)^.typ=uvoid) then
  830. if (m_tp in aktmodeswitches) or
  831. (m_delphi in aktmodeswitches) then
  832. Message(parser_w_no_new_dispose_on_void_pointers)
  833. else
  834. Message(parser_e_no_new_dispose_on_void_pointers);
  835. case ht of
  836. _NEW : new_dispose_statement:=gensinglenode(simplenewn,p);
  837. _DISPOSE : new_dispose_statement:=gensinglenode(simpledisposen,p);
  838. end;
  839. end;
  840. end;
  841. consume(RKLAMMER);
  842. end;
  843. function statement_block(starttoken : ttoken) : ptree;
  844. var
  845. first,last : ptree;
  846. filepos : tfileposinfo;
  847. begin
  848. first:=nil;
  849. filepos:=tokenpos;
  850. consume(starttoken);
  851. inc(statement_level);
  852. while not(token in [_END,_FINALIZATION]) do
  853. begin
  854. if first=nil then
  855. begin
  856. last:=gennode(statementn,nil,statement);
  857. first:=last;
  858. end
  859. else
  860. begin
  861. last^.left:=gennode(statementn,nil,statement);
  862. last:=last^.left;
  863. end;
  864. if (token in [_END,_FINALIZATION]) then
  865. break
  866. else
  867. begin
  868. { if no semicolon, then error and go on }
  869. if token<>SEMICOLON then
  870. begin
  871. consume(SEMICOLON);
  872. consume_all_until(SEMICOLON);
  873. end;
  874. consume(SEMICOLON);
  875. end;
  876. emptystats;
  877. end;
  878. { don't consume the finalization token, it is consumed when
  879. reading the finalization block, but allow it only after
  880. an initalization ! }
  881. if (starttoken<>_INITIALIZATION) or (token<>_FINALIZATION) then
  882. consume(_END);
  883. dec(statement_level);
  884. last:=gensinglenode(blockn,first);
  885. set_tree_filepos(last,filepos);
  886. statement_block:=last;
  887. end;
  888. function statement : ptree;
  889. var
  890. p : ptree;
  891. code : ptree;
  892. labelnr : pasmlabel;
  893. filepos : tfileposinfo;
  894. label
  895. ready;
  896. begin
  897. filepos:=tokenpos;
  898. case token of
  899. _GOTO : begin
  900. if not(cs_support_goto in aktmoduleswitches)then
  901. Message(sym_e_goto_and_label_not_supported);
  902. consume(_GOTO);
  903. if (token<>INTCONST) and (token<>ID) then
  904. begin
  905. Message(sym_e_label_not_found);
  906. code:=genzeronode(errorn);
  907. end
  908. else
  909. begin
  910. getsym(pattern,true);
  911. consume(token);
  912. if srsym^.typ<>labelsym then
  913. begin
  914. Message(sym_e_id_is_no_label_id);
  915. code:=genzeronode(errorn);
  916. end
  917. else
  918. code:=genlabelnode(goton,
  919. plabelsym(srsym)^.lab);
  920. end;
  921. end;
  922. _BEGIN : code:=statement_block(_BEGIN);
  923. _IF : code:=if_statement;
  924. _CASE : code:=case_statement;
  925. _REPEAT : code:=repeat_statement;
  926. _WHILE : code:=while_statement;
  927. _FOR : code:=for_statement;
  928. _NEW,_DISPOSE : code:=new_dispose_statement;
  929. _WITH : code:=with_statement;
  930. _TRY : code:=try_statement;
  931. _RAISE : code:=raise_statement;
  932. { semicolons,else until and end are ignored }
  933. SEMICOLON,
  934. _ELSE,
  935. _UNTIL,
  936. _END:
  937. code:=genzeronode(niln);
  938. _FAIL : begin
  939. { internalerror(100); }
  940. if (aktprocsym^.definition^.options and poconstructor)=0 then
  941. Message(parser_e_fail_only_in_constructor);
  942. consume(_FAIL);
  943. code:=genzeronode(failn);
  944. end;
  945. _EXIT : code:=exit_statement;
  946. _ASM : begin
  947. code:=_asm_statement;
  948. end;
  949. _EOF : begin
  950. Message(scan_f_end_of_file);
  951. end;
  952. else
  953. begin
  954. if (token=INTCONST) or
  955. ((token=ID) and not((m_result in aktmodeswitches) and (idtoken=_RESULT))) then
  956. begin
  957. getsym(pattern,true);
  958. lastsymknown:=true;
  959. lastsrsym:=srsym;
  960. { it is NOT necessarily the owner
  961. it can be a withsymtable !!! }
  962. lastsrsymtable:=srsymtable;
  963. if assigned(srsym) and (srsym^.typ=labelsym) then
  964. begin
  965. consume(token);
  966. consume(COLON);
  967. if plabelsym(srsym)^.defined then
  968. Message(sym_e_label_already_defined);
  969. plabelsym(srsym)^.defined:=true;
  970. { statement modifies srsym }
  971. labelnr:=plabelsym(srsym)^.lab;
  972. lastsymknown:=false;
  973. { the pointer to the following instruction }
  974. { isn't a very clean way }
  975. {$ifdef tp}
  976. code:=gensinglenode(labeln,statement);
  977. {$else}
  978. code:=gensinglenode(labeln,statement());
  979. {$endif}
  980. code^.labelnr:=labelnr;
  981. { sorry, but there is a jump the easiest way }
  982. goto ready;
  983. end;
  984. end;
  985. p:=expr;
  986. if not(p^.treetype in [calln,assignn,breakn,inlinen,
  987. continuen]) then
  988. Message(cg_e_illegal_expression);
  989. { specify that we don't use the value returned by the call }
  990. { Question : can this be also improtant
  991. for inlinen ??
  992. it is used for :
  993. - dispose of temp stack space
  994. - dispose on FPU stack }
  995. if p^.treetype=calln then
  996. p^.return_value_used:=false;
  997. code:=p;
  998. end;
  999. end;
  1000. ready:
  1001. if assigned(code) then
  1002. set_tree_filepos(code,filepos);
  1003. statement:=code;
  1004. end;
  1005. function block(islibrary : boolean) : ptree;
  1006. var
  1007. funcretsym : pfuncretsym;
  1008. storepos : tfileposinfo;
  1009. begin
  1010. if procinfo.retdef<>pdef(voiddef) then
  1011. begin
  1012. { if the current is a function aktprocsym is non nil }
  1013. { and there is a local symtable set }
  1014. storepos:=tokenpos;
  1015. tokenpos:=aktprocsym^.fileinfo;
  1016. funcretsym:=new(pfuncretsym,init(aktprocsym^.name,@procinfo));
  1017. { insert in local symtable }
  1018. symtablestack^.insert(funcretsym);
  1019. tokenpos:=storepos;
  1020. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  1021. procinfo.retoffset:=-funcretsym^.address;
  1022. procinfo.funcretsym:=funcretsym;
  1023. end;
  1024. read_declarations(islibrary);
  1025. { temporary space is set, while the BEGIN of the procedure }
  1026. if (symtablestack^.symtabletype=localsymtable) then
  1027. procinfo.firsttemp := -symtablestack^.datasize
  1028. else procinfo.firsttemp := 0;
  1029. { space for the return value }
  1030. { !!!!! this means that we can not set the return value
  1031. in a subfunction !!!!! }
  1032. { because we don't know yet where the address is }
  1033. if procinfo.retdef<>pdef(voiddef) then
  1034. begin
  1035. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  1036. { if (procinfo.retdef^.deftype=orddef) or
  1037. (procinfo.retdef^.deftype=pointerdef) or
  1038. (procinfo.retdef^.deftype=enumdef) or
  1039. (procinfo.retdef^.deftype=procvardef) or
  1040. (procinfo.retdef^.deftype=floatdef) or
  1041. (
  1042. (procinfo.retdef^.deftype=setdef) and
  1043. (psetdef(procinfo.retdef)^.settype=smallset)
  1044. ) then }
  1045. begin
  1046. { the space has been set in the local symtable }
  1047. procinfo.retoffset:=-funcretsym^.address;
  1048. if ((procinfo.flags and pi_operator)<>0) and
  1049. assigned(opsym) then
  1050. {opsym^.address:=procinfo.call_offset; is wrong PM }
  1051. opsym^.address:=-procinfo.retoffset;
  1052. { eax is modified by a function }
  1053. {$ifdef i386}
  1054. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  1055. if is_64bitint(procinfo.retdef) then
  1056. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  1057. {$endif}
  1058. {$ifdef m68k}
  1059. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1060. if is_64bitint(procinfo.retdef) then
  1061. usedinproc:=usedinproc or ($800 shr byte(R_D1))
  1062. {$endif}
  1063. end;
  1064. end;
  1065. {Unit initialization?.}
  1066. if (lexlevel=unit_init_level) and (current_module^.is_unit) then
  1067. if (token=_END) then
  1068. begin
  1069. consume(_END);
  1070. block:=nil;
  1071. end
  1072. else
  1073. begin
  1074. if token=_INITIALIZATION then
  1075. begin
  1076. current_module^.flags:=current_module^.flags or uf_init;
  1077. block:=statement_block(_INITIALIZATION);
  1078. end
  1079. else if (token=_FINALIZATION) then
  1080. begin
  1081. if (current_module^.flags and uf_finalize)<>0 then
  1082. block:=statement_block(_FINALIZATION)
  1083. else
  1084. begin
  1085. block:=nil;
  1086. exit;
  1087. end;
  1088. end
  1089. else
  1090. begin
  1091. current_module^.flags:=current_module^.flags or uf_init;
  1092. block:=statement_block(_BEGIN);
  1093. end;
  1094. end
  1095. else
  1096. block:=statement_block(_BEGIN);
  1097. end;
  1098. function assembler_block : ptree;
  1099. begin
  1100. read_declarations(false);
  1101. { temporary space is set, while the BEGIN of the procedure }
  1102. if symtablestack^.symtabletype=localsymtable then
  1103. procinfo.firsttemp := -symtablestack^.datasize
  1104. else
  1105. procinfo.firsttemp := 0;
  1106. { assembler code does not allocate }
  1107. { space for the return value }
  1108. if procinfo.retdef<>pdef(voiddef) then
  1109. begin
  1110. if ret_in_acc(procinfo.retdef) then
  1111. begin
  1112. { in assembler code the result should be directly in %eax
  1113. procinfo.retoffset:=procinfo.firsttemp-procinfo.retdef^.size;
  1114. procinfo.firsttemp:=procinfo.retoffset; }
  1115. {$ifdef i386}
  1116. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  1117. {$endif}
  1118. {$ifdef m68k}
  1119. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1120. {$endif}
  1121. end
  1122. {
  1123. else if not is_fpu(procinfo.retdef) then
  1124. should we allow assembler functions of big elements ?
  1125. YES (FK)!!
  1126. Message(parser_e_asm_incomp_with_function_return);
  1127. }
  1128. end;
  1129. { set the framepointer to esp for assembler functions }
  1130. { but only if the are no local variables }
  1131. { added no parameter also (PM) }
  1132. if ((aktprocsym^.definition^.options and poassembler)<>0) and
  1133. (aktprocsym^.definition^.localst^.datasize=0) and
  1134. (aktprocsym^.definition^.parast^.datasize=0) and
  1135. not(ret_in_param(aktprocsym^.definition^.retdef)) then
  1136. begin
  1137. procinfo.framepointer:=stack_pointer;
  1138. { set the right value for parameters }
  1139. dec(aktprocsym^.definition^.parast^.address_fixup,target_os.size_of_pointer);
  1140. dec(procinfo.call_offset,target_os.size_of_pointer);
  1141. end;
  1142. { force the asm statement }
  1143. if token<>_ASM then
  1144. consume(_ASM);
  1145. Procinfo.Flags := ProcInfo.Flags Or pi_is_assembler;
  1146. assembler_block:=_asm_statement;
  1147. { becuase the END is already read we need to get the
  1148. last_endtoken_filepos here (PFV) }
  1149. last_endtoken_filepos:=tokenpos;
  1150. end;
  1151. end.
  1152. {
  1153. $Log$
  1154. Revision 1.92 1999-07-26 09:42:14 florian
  1155. * bugs 494-496 fixed
  1156. Revision 1.91 1999/06/30 22:16:22 florian
  1157. * use of is_ordinal checked: often a qword/int64 isn't allowed (case/for ...)
  1158. * small qword problems fixed
  1159. Revision 1.90 1999/06/22 16:24:43 pierre
  1160. * local browser stuff corrected
  1161. Revision 1.89 1999/06/17 13:19:54 pierre
  1162. * merged from 0_99_12 branch
  1163. Revision 1.88.2.1 1999/06/17 12:51:46 pierre
  1164. * changed is_assignment_overloaded into
  1165. function assignment_overloaded : pprocdef
  1166. to allow overloading of assignment with only different result type
  1167. Revision 1.88 1999/06/15 13:19:46 pierre
  1168. * better uninitialized var tests for TP mode
  1169. Revision 1.87 1999/05/27 19:44:50 peter
  1170. * removed oldasm
  1171. * plabel -> pasmlabel
  1172. * -a switches to source writing automaticly
  1173. * assembler readers OOPed
  1174. * asmsymbol automaticly external
  1175. * jumptables and other label fixes for asm readers
  1176. Revision 1.86 1999/05/21 13:55:08 peter
  1177. * NEWLAB for label as symbol
  1178. Revision 1.85 1999/05/17 23:51:40 peter
  1179. * with temp vars now use a reference with a persistant temp instead
  1180. of setting datasize
  1181. Revision 1.84 1999/05/13 21:59:38 peter
  1182. * removed oldppu code
  1183. * warning if objpas is loaded from uses
  1184. * first things for new deref writing
  1185. Revision 1.83 1999/05/05 22:21:58 peter
  1186. * updated messages
  1187. Revision 1.82 1999/05/01 13:24:35 peter
  1188. * merged nasm compiler
  1189. * old asm moved to oldasm/
  1190. Revision 1.81 1999/04/26 13:31:42 peter
  1191. * release storenumber,double_checksum
  1192. Revision 1.80 1999/04/21 09:43:48 peter
  1193. * storenumber works
  1194. * fixed some typos in double_checksum
  1195. + incompatible types type1 and type2 message (with storenumber)
  1196. Revision 1.79 1999/04/16 12:14:49 pierre
  1197. * void pointer accepted with warning in tp and delphi mode
  1198. Revision 1.78 1999/04/15 12:58:14 pierre
  1199. * fix for bug0234
  1200. Revision 1.77 1999/04/15 09:01:33 peter
  1201. * fixed set loading
  1202. * object inheritance support for browser
  1203. Revision 1.76 1999/04/14 18:41:25 daniel
  1204. * Better use of routines in pbase and symtable. 4k code removed.
  1205. Revision 1.75 1999/04/14 09:14:53 peter
  1206. * first things to store the symbol/def number in the ppu
  1207. Revision 1.74 1999/04/09 12:22:06 pierre
  1208. * bug found by Peter for DirectWith code fixed
  1209. Revision 1.73 1999/04/06 11:21:57 peter
  1210. * more use of ttoken
  1211. Revision 1.72 1999/03/31 13:55:15 peter
  1212. * assembler inlining working for ag386bin
  1213. Revision 1.71 1999/03/10 11:23:29 pierre
  1214. * typecheck for exit(value) : resulttype was not set
  1215. Revision 1.70 1999/03/04 13:55:45 pierre
  1216. * some m68k fixes (still not compilable !)
  1217. * new(tobj) does not give warning if tobj has no VMT !
  1218. Revision 1.69 1999/03/02 02:56:15 peter
  1219. + stabs support for binary writers
  1220. * more fixes and missing updates from the previous commit :(
  1221. Revision 1.68 1999/02/26 00:48:23 peter
  1222. * assembler writers fixed for ag386bin
  1223. Revision 1.67 1999/02/22 13:07:01 pierre
  1224. + -b and -bl options work !
  1225. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1226. is not enabled when quitting global section
  1227. * local vars and procedures are not yet stored into PPU
  1228. Revision 1.66 1999/02/22 02:15:31 peter
  1229. * updates for ag386bin
  1230. Revision 1.65 1999/02/15 13:13:15 pierre
  1231. * fix for bug0216
  1232. Revision 1.64 1999/02/11 09:46:26 pierre
  1233. * fix for normal method calls inside static methods :
  1234. WARNING there were both parser and codegen errors !!
  1235. added static_call boolean to calln tree
  1236. Revision 1.63 1999/02/09 15:45:47 florian
  1237. + complex results for assembler functions, fixes bug0155
  1238. Revision 1.62 1999/01/27 13:06:57 pierre
  1239. * memory leak in case optimization fixed
  1240. Revision 1.61 1999/01/25 22:49:09 peter
  1241. * more fixes for the on bug with unknown id
  1242. Revision 1.60 1999/01/23 23:29:38 florian
  1243. * first running version of the new code generator
  1244. * when compiling exceptions under Linux fixed
  1245. Revision 1.59 1999/01/21 16:41:02 pierre
  1246. * fix for constructor inside with statements
  1247. Revision 1.58 1999/01/05 08:20:07 florian
  1248. * mainly problem with invalid case ranges fixed (reported by Jonas)
  1249. Revision 1.57 1998/12/29 18:48:15 jonas
  1250. + optimize pascal code surrounding assembler blocks
  1251. Revision 1.56 1998/12/23 22:52:56 peter
  1252. * fixed new(x) crash if x contains an error
  1253. Revision 1.55 1998/12/16 12:30:59 jonas
  1254. * released CaseRange
  1255. Revision 1.54 1998/12/15 22:32:24 jonas
  1256. + convert consecutive case labels to a single range (-dCaseRange)
  1257. Revision 1.53 1998/12/15 11:52:18 peter
  1258. * fixed dup release of statement label in case
  1259. Revision 1.52 1998/12/11 00:03:37 peter
  1260. + globtype,tokens,version unit splitted from globals
  1261. Revision 1.51 1998/12/10 09:47:24 florian
  1262. + basic operations with int64/qord (compiler with -dint64)
  1263. + rtti of enumerations extended: names are now written
  1264. Revision 1.50 1998/11/13 15:40:25 pierre
  1265. + added -Se in Makefile cvstest target
  1266. + lexlevel cleanup
  1267. normal_function_level main_program_level and unit_init_level defined
  1268. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  1269. (test added in code !)
  1270. * -Un option was wrong
  1271. * _FAIL and _SELF only keyword inside
  1272. constructors and methods respectively
  1273. Revision 1.49 1998/11/12 12:55:17 pierre
  1274. * fix for bug0176 and bug0177
  1275. Revision 1.48 1998/11/05 23:43:24 peter
  1276. * fixed assembler directive and then not an ASM statement
  1277. Revision 1.47 1998/10/30 16:20:22 peter
  1278. * fixed dispose(destructor) crash when destructor didn't exists
  1279. Revision 1.46 1998/10/20 08:06:53 pierre
  1280. * several memory corruptions due to double freemem solved
  1281. => never use p^.loc.location:=p^.left^.loc.location;
  1282. + finally I added now by default
  1283. that ra386dir translates global and unit symbols
  1284. + added a first field in tsymtable and
  1285. a nextsym field in tsym
  1286. (this allows to obtain ordered type info for
  1287. records and objects in gdb !)
  1288. Revision 1.45 1998/10/19 08:55:01 pierre
  1289. * wrong stabs info corrected once again !!
  1290. + variable vmt offset with vmt field only if required
  1291. implemented now !!!
  1292. Revision 1.44 1998/10/13 13:10:27 peter
  1293. * new style for m68k/i386 infos and enums
  1294. Revision 1.43 1998/10/08 13:46:22 peter
  1295. * added eof message
  1296. * fixed unit init section parsing with finalize
  1297. Revision 1.42 1998/09/26 17:45:38 peter
  1298. + idtoken and only one token table
  1299. Revision 1.41 1998/09/24 23:49:15 peter
  1300. + aktmodeswitches
  1301. Revision 1.40 1998/09/23 21:53:04 florian
  1302. * the following doesn't work: on texception do, was a parser error, fixed
  1303. Revision 1.39 1998/09/21 10:26:07 peter
  1304. * merged fix
  1305. Revision 1.38.2.1 1998/09/21 10:24:43 peter
  1306. * fixed error recovery with with
  1307. Revision 1.38 1998/09/04 08:42:04 peter
  1308. * updated some error messages
  1309. Revision 1.37 1998/08/21 14:08:52 pierre
  1310. + TEST_FUNCRET now default (old code removed)
  1311. works also for m68k (at least compiles)
  1312. Revision 1.36 1998/08/20 21:36:41 peter
  1313. * fixed 'with object do' bug
  1314. Revision 1.35 1998/08/20 09:26:42 pierre
  1315. + funcret setting in underproc testing
  1316. compile with _dTEST_FUNCRET
  1317. Revision 1.34 1998/08/17 10:10:09 peter
  1318. - removed OLDPPU
  1319. Revision 1.33 1998/08/12 19:39:30 peter
  1320. * fixed some crashes
  1321. Revision 1.32 1998/08/10 14:50:17 peter
  1322. + localswitches, moduleswitches, globalswitches splitting
  1323. Revision 1.31 1998/08/02 16:41:59 florian
  1324. * on o : tobject do should also work now, the exceptsymtable shouldn't be
  1325. disposed by dellexlevel
  1326. Revision 1.30 1998/07/30 16:07:10 florian
  1327. * try ... expect <statement> end; works now
  1328. Revision 1.29 1998/07/30 13:30:37 florian
  1329. * final implemenation of exception support, maybe it needs
  1330. some fixes :)
  1331. Revision 1.28 1998/07/30 11:18:18 florian
  1332. + first implementation of try ... except on .. do end;
  1333. * limitiation of 65535 bytes parameters for cdecl removed
  1334. Revision 1.27 1998/07/28 21:52:55 florian
  1335. + implementation of raise and try..finally
  1336. + some misc. exception stuff
  1337. Revision 1.26 1998/07/27 21:57:14 florian
  1338. * fix to allow tv like stream registration:
  1339. @tmenu.load doesn't work if load had parameters or if load was only
  1340. declared in an anchestor class of tmenu
  1341. Revision 1.25 1998/07/14 21:46:53 peter
  1342. * updated messages file
  1343. Revision 1.24 1998/07/10 10:48:42 peter
  1344. * fixed realnumber scanning
  1345. * [] after asmblock was not uppercased anymore
  1346. Revision 1.23 1998/06/25 08:48:18 florian
  1347. * first version of rtti support
  1348. Revision 1.22 1998/06/24 14:48:36 peter
  1349. * ifdef newppu -> ifndef oldppu
  1350. Revision 1.21 1998/06/24 14:06:34 peter
  1351. * fixed the name changes
  1352. Revision 1.20 1998/06/23 14:00:16 peter
  1353. * renamed RA* units
  1354. Revision 1.19 1998/06/08 22:59:50 peter
  1355. * smartlinking works for win32
  1356. * some defines to exclude some compiler parts
  1357. Revision 1.18 1998/06/05 14:37:35 pierre
  1358. * fixes for inline for operators
  1359. * inline procedure more correctly restricted
  1360. Revision 1.17 1998/06/04 09:55:43 pierre
  1361. * demangled name of procsym reworked to become independant of the mangling scheme
  1362. Revision 1.16 1998/06/02 17:03:04 pierre
  1363. * with node corrected for objects
  1364. * small bugs for SUPPORT_MMX fixed
  1365. Revision 1.15 1998/05/30 14:31:06 peter
  1366. + $ASMMODE
  1367. Revision 1.14 1998/05/29 09:58:14 pierre
  1368. * OPR_REGISTER for 1 arg was missing in ratti386.pas
  1369. (probably a merging problem)
  1370. * errors at start of line were lost
  1371. Revision 1.13 1998/05/28 17:26:50 peter
  1372. * fixed -R switch, it didn't work after my previous akt/init patch
  1373. * fixed bugs 110,130,136
  1374. Revision 1.12 1998/05/21 19:33:33 peter
  1375. + better procedure directive handling and only one table
  1376. Revision 1.11 1998/05/20 09:42:35 pierre
  1377. + UseTokenInfo now default
  1378. * unit in interface uses and implementation uses gives error now
  1379. * only one error for unknown symbol (uses lastsymknown boolean)
  1380. the problem came from the label code !
  1381. + first inlined procedures and function work
  1382. (warning there might be allowed cases were the result is still wrong !!)
  1383. * UseBrower updated gives a global list of all position of all used symbols
  1384. with switch -gb
  1385. Revision 1.10 1998/05/11 13:07:56 peter
  1386. + $ifdef NEWPPU for the new ppuformat
  1387. + $define GDB not longer required
  1388. * removed all warnings and stripped some log comments
  1389. * no findfirst/findnext anymore to remove smartlink *.o files
  1390. Revision 1.9 1998/05/06 08:38:46 pierre
  1391. * better position info with UseTokenInfo
  1392. UseTokenInfo greatly simplified
  1393. + added check for changed tree after first time firstpass
  1394. (if we could remove all the cases were it happen
  1395. we could skip all firstpass if firstpasscount > 1)
  1396. Only with ExtDebug
  1397. Revision 1.8 1998/05/05 12:05:42 florian
  1398. * problems with properties fixed
  1399. * crash fixed: i:=l when i and l are undefined, was a problem with
  1400. implementation of private/protected
  1401. Revision 1.7 1998/05/01 16:38:46 florian
  1402. * handling of private and protected fixed
  1403. + change_keywords_to_tp implemented to remove
  1404. keywords which aren't supported by tp
  1405. * break and continue are now symbols of the system unit
  1406. + widestring, longstring and ansistring type released
  1407. Revision 1.6 1998/04/30 15:59:42 pierre
  1408. * GDB works again better :
  1409. correct type info in one pass
  1410. + UseTokenInfo for better source position
  1411. * fixed one remaining bug in scanner for line counts
  1412. * several little fixes
  1413. Revision 1.5 1998/04/29 10:33:59 pierre
  1414. + added some code for ansistring (not complete nor working yet)
  1415. * corrected operator overloading
  1416. * corrected nasm output
  1417. + started inline procedures
  1418. + added starstarn : use ** for exponentiation (^ gave problems)
  1419. + started UseTokenInfo cond to get accurate positions
  1420. Revision 1.4 1998/04/08 16:58:05 pierre
  1421. * several bugfixes
  1422. ADD ADC and AND are also sign extended
  1423. nasm output OK (program still crashes at end
  1424. and creates wrong assembler files !!)
  1425. procsym types sym in tdef removed !!
  1426. }