pstatmnt.pas 56 KB

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