pstatmnt.pas 57 KB

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