pstatmnt.pas 55 KB

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