pstatmnt.pas 58 KB

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