pstatmnt.pas 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619
  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 then
  1043. {opsym^.address:=procinfo.call_offset; is wrong PM }
  1044. opsym^.address:=-procinfo.retoffset;
  1045. { eax is modified by a function }
  1046. {$ifdef i386}
  1047. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  1048. if is_64bitint(procinfo.retdef) then
  1049. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  1050. {$endif}
  1051. {$ifdef m68k}
  1052. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1053. if is_64bitint(procinfo.retdef) then
  1054. usedinproc:=usedinproc or ($800 shr byte(R_D1))
  1055. {$endif}
  1056. end;
  1057. end;
  1058. {Unit initialization?.}
  1059. if (lexlevel=unit_init_level) and (current_module^.is_unit) then
  1060. if (token=_END) then
  1061. begin
  1062. consume(_END);
  1063. block:=nil;
  1064. end
  1065. else
  1066. begin
  1067. if token=_INITIALIZATION then
  1068. begin
  1069. current_module^.flags:=current_module^.flags or uf_init;
  1070. block:=statement_block(_INITIALIZATION);
  1071. end
  1072. else if (token=_FINALIZATION) then
  1073. begin
  1074. if (current_module^.flags and uf_finalize)<>0 then
  1075. block:=statement_block(_FINALIZATION)
  1076. else
  1077. begin
  1078. block:=nil;
  1079. exit;
  1080. end;
  1081. end
  1082. else
  1083. begin
  1084. current_module^.flags:=current_module^.flags or uf_init;
  1085. block:=statement_block(_BEGIN);
  1086. end;
  1087. end
  1088. else
  1089. block:=statement_block(_BEGIN);
  1090. end;
  1091. function assembler_block : ptree;
  1092. begin
  1093. read_declarations(false);
  1094. { temporary space is set, while the BEGIN of the procedure }
  1095. if symtablestack^.symtabletype=localsymtable then
  1096. procinfo.firsttemp := -symtablestack^.datasize
  1097. else
  1098. procinfo.firsttemp := 0;
  1099. { assembler code does not allocate }
  1100. { space for the return value }
  1101. if procinfo.retdef<>pdef(voiddef) then
  1102. begin
  1103. if ret_in_acc(procinfo.retdef) then
  1104. begin
  1105. { in assembler code the result should be directly in %eax
  1106. procinfo.retoffset:=procinfo.firsttemp-procinfo.retdef^.size;
  1107. procinfo.firsttemp:=procinfo.retoffset; }
  1108. {$ifdef i386}
  1109. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  1110. {$endif}
  1111. {$ifdef m68k}
  1112. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1113. {$endif}
  1114. end
  1115. {
  1116. else if not is_fpu(procinfo.retdef) then
  1117. should we allow assembler functions of big elements ?
  1118. YES (FK)!!
  1119. Message(parser_e_asm_incomp_with_function_return);
  1120. }
  1121. end;
  1122. { set the framepointer to esp for assembler functions }
  1123. { but only if the are no local variables }
  1124. { added no parameter also (PM) }
  1125. if ((aktprocsym^.definition^.options and poassembler)<>0) and
  1126. (aktprocsym^.definition^.localst^.datasize=0) and
  1127. (aktprocsym^.definition^.parast^.datasize=0) and
  1128. not(ret_in_param(aktprocsym^.definition^.retdef)) then
  1129. begin
  1130. procinfo.framepointer:=stack_pointer;
  1131. { set the right value for parameters }
  1132. dec(aktprocsym^.definition^.parast^.address_fixup,target_os.size_of_pointer);
  1133. dec(procinfo.call_offset,target_os.size_of_pointer);
  1134. end;
  1135. { force the asm statement }
  1136. if token<>_ASM then
  1137. consume(_ASM);
  1138. Procinfo.Flags := ProcInfo.Flags Or pi_is_assembler;
  1139. assembler_block:=_asm_statement;
  1140. { becuase the END is already read we need to get the
  1141. last_endtoken_filepos here (PFV) }
  1142. last_endtoken_filepos:=tokenpos;
  1143. end;
  1144. end.
  1145. {
  1146. $Log$
  1147. Revision 1.88 1999-06-15 13:19:46 pierre
  1148. * better uninitialized var tests for TP mode
  1149. Revision 1.87 1999/05/27 19:44:50 peter
  1150. * removed oldasm
  1151. * plabel -> pasmlabel
  1152. * -a switches to source writing automaticly
  1153. * assembler readers OOPed
  1154. * asmsymbol automaticly external
  1155. * jumptables and other label fixes for asm readers
  1156. Revision 1.86 1999/05/21 13:55:08 peter
  1157. * NEWLAB for label as symbol
  1158. Revision 1.85 1999/05/17 23:51:40 peter
  1159. * with temp vars now use a reference with a persistant temp instead
  1160. of setting datasize
  1161. Revision 1.84 1999/05/13 21:59:38 peter
  1162. * removed oldppu code
  1163. * warning if objpas is loaded from uses
  1164. * first things for new deref writing
  1165. Revision 1.83 1999/05/05 22:21:58 peter
  1166. * updated messages
  1167. Revision 1.82 1999/05/01 13:24:35 peter
  1168. * merged nasm compiler
  1169. * old asm moved to oldasm/
  1170. Revision 1.81 1999/04/26 13:31:42 peter
  1171. * release storenumber,double_checksum
  1172. Revision 1.80 1999/04/21 09:43:48 peter
  1173. * storenumber works
  1174. * fixed some typos in double_checksum
  1175. + incompatible types type1 and type2 message (with storenumber)
  1176. Revision 1.79 1999/04/16 12:14:49 pierre
  1177. * void pointer accepted with warning in tp and delphi mode
  1178. Revision 1.78 1999/04/15 12:58:14 pierre
  1179. * fix for bug0234
  1180. Revision 1.77 1999/04/15 09:01:33 peter
  1181. * fixed set loading
  1182. * object inheritance support for browser
  1183. Revision 1.76 1999/04/14 18:41:25 daniel
  1184. * Better use of routines in pbase and symtable. 4k code removed.
  1185. Revision 1.75 1999/04/14 09:14:53 peter
  1186. * first things to store the symbol/def number in the ppu
  1187. Revision 1.74 1999/04/09 12:22:06 pierre
  1188. * bug found by Peter for DirectWith code fixed
  1189. Revision 1.73 1999/04/06 11:21:57 peter
  1190. * more use of ttoken
  1191. Revision 1.72 1999/03/31 13:55:15 peter
  1192. * assembler inlining working for ag386bin
  1193. Revision 1.71 1999/03/10 11:23:29 pierre
  1194. * typecheck for exit(value) : resulttype was not set
  1195. Revision 1.70 1999/03/04 13:55:45 pierre
  1196. * some m68k fixes (still not compilable !)
  1197. * new(tobj) does not give warning if tobj has no VMT !
  1198. Revision 1.69 1999/03/02 02:56:15 peter
  1199. + stabs support for binary writers
  1200. * more fixes and missing updates from the previous commit :(
  1201. Revision 1.68 1999/02/26 00:48:23 peter
  1202. * assembler writers fixed for ag386bin
  1203. Revision 1.67 1999/02/22 13:07:01 pierre
  1204. + -b and -bl options work !
  1205. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1206. is not enabled when quitting global section
  1207. * local vars and procedures are not yet stored into PPU
  1208. Revision 1.66 1999/02/22 02:15:31 peter
  1209. * updates for ag386bin
  1210. Revision 1.65 1999/02/15 13:13:15 pierre
  1211. * fix for bug0216
  1212. Revision 1.64 1999/02/11 09:46:26 pierre
  1213. * fix for normal method calls inside static methods :
  1214. WARNING there were both parser and codegen errors !!
  1215. added static_call boolean to calln tree
  1216. Revision 1.63 1999/02/09 15:45:47 florian
  1217. + complex results for assembler functions, fixes bug0155
  1218. Revision 1.62 1999/01/27 13:06:57 pierre
  1219. * memory leak in case optimization fixed
  1220. Revision 1.61 1999/01/25 22:49:09 peter
  1221. * more fixes for the on bug with unknown id
  1222. Revision 1.60 1999/01/23 23:29:38 florian
  1223. * first running version of the new code generator
  1224. * when compiling exceptions under Linux fixed
  1225. Revision 1.59 1999/01/21 16:41:02 pierre
  1226. * fix for constructor inside with statements
  1227. Revision 1.58 1999/01/05 08:20:07 florian
  1228. * mainly problem with invalid case ranges fixed (reported by Jonas)
  1229. Revision 1.57 1998/12/29 18:48:15 jonas
  1230. + optimize pascal code surrounding assembler blocks
  1231. Revision 1.56 1998/12/23 22:52:56 peter
  1232. * fixed new(x) crash if x contains an error
  1233. Revision 1.55 1998/12/16 12:30:59 jonas
  1234. * released CaseRange
  1235. Revision 1.54 1998/12/15 22:32:24 jonas
  1236. + convert consecutive case labels to a single range (-dCaseRange)
  1237. Revision 1.53 1998/12/15 11:52:18 peter
  1238. * fixed dup release of statement label in case
  1239. Revision 1.52 1998/12/11 00:03:37 peter
  1240. + globtype,tokens,version unit splitted from globals
  1241. Revision 1.51 1998/12/10 09:47:24 florian
  1242. + basic operations with int64/qord (compiler with -dint64)
  1243. + rtti of enumerations extended: names are now written
  1244. Revision 1.50 1998/11/13 15:40:25 pierre
  1245. + added -Se in Makefile cvstest target
  1246. + lexlevel cleanup
  1247. normal_function_level main_program_level and unit_init_level defined
  1248. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  1249. (test added in code !)
  1250. * -Un option was wrong
  1251. * _FAIL and _SELF only keyword inside
  1252. constructors and methods respectively
  1253. Revision 1.49 1998/11/12 12:55:17 pierre
  1254. * fix for bug0176 and bug0177
  1255. Revision 1.48 1998/11/05 23:43:24 peter
  1256. * fixed assembler directive and then not an ASM statement
  1257. Revision 1.47 1998/10/30 16:20:22 peter
  1258. * fixed dispose(destructor) crash when destructor didn't exists
  1259. Revision 1.46 1998/10/20 08:06:53 pierre
  1260. * several memory corruptions due to double freemem solved
  1261. => never use p^.loc.location:=p^.left^.loc.location;
  1262. + finally I added now by default
  1263. that ra386dir translates global and unit symbols
  1264. + added a first field in tsymtable and
  1265. a nextsym field in tsym
  1266. (this allows to obtain ordered type info for
  1267. records and objects in gdb !)
  1268. Revision 1.45 1998/10/19 08:55:01 pierre
  1269. * wrong stabs info corrected once again !!
  1270. + variable vmt offset with vmt field only if required
  1271. implemented now !!!
  1272. Revision 1.44 1998/10/13 13:10:27 peter
  1273. * new style for m68k/i386 infos and enums
  1274. Revision 1.43 1998/10/08 13:46:22 peter
  1275. * added eof message
  1276. * fixed unit init section parsing with finalize
  1277. Revision 1.42 1998/09/26 17:45:38 peter
  1278. + idtoken and only one token table
  1279. Revision 1.41 1998/09/24 23:49:15 peter
  1280. + aktmodeswitches
  1281. Revision 1.40 1998/09/23 21:53:04 florian
  1282. * the following doesn't work: on texception do, was a parser error, fixed
  1283. Revision 1.39 1998/09/21 10:26:07 peter
  1284. * merged fix
  1285. Revision 1.38.2.1 1998/09/21 10:24:43 peter
  1286. * fixed error recovery with with
  1287. Revision 1.38 1998/09/04 08:42:04 peter
  1288. * updated some error messages
  1289. Revision 1.37 1998/08/21 14:08:52 pierre
  1290. + TEST_FUNCRET now default (old code removed)
  1291. works also for m68k (at least compiles)
  1292. Revision 1.36 1998/08/20 21:36:41 peter
  1293. * fixed 'with object do' bug
  1294. Revision 1.35 1998/08/20 09:26:42 pierre
  1295. + funcret setting in underproc testing
  1296. compile with _dTEST_FUNCRET
  1297. Revision 1.34 1998/08/17 10:10:09 peter
  1298. - removed OLDPPU
  1299. Revision 1.33 1998/08/12 19:39:30 peter
  1300. * fixed some crashes
  1301. Revision 1.32 1998/08/10 14:50:17 peter
  1302. + localswitches, moduleswitches, globalswitches splitting
  1303. Revision 1.31 1998/08/02 16:41:59 florian
  1304. * on o : tobject do should also work now, the exceptsymtable shouldn't be
  1305. disposed by dellexlevel
  1306. Revision 1.30 1998/07/30 16:07:10 florian
  1307. * try ... expect <statement> end; works now
  1308. Revision 1.29 1998/07/30 13:30:37 florian
  1309. * final implemenation of exception support, maybe it needs
  1310. some fixes :)
  1311. Revision 1.28 1998/07/30 11:18:18 florian
  1312. + first implementation of try ... except on .. do end;
  1313. * limitiation of 65535 bytes parameters for cdecl removed
  1314. Revision 1.27 1998/07/28 21:52:55 florian
  1315. + implementation of raise and try..finally
  1316. + some misc. exception stuff
  1317. Revision 1.26 1998/07/27 21:57:14 florian
  1318. * fix to allow tv like stream registration:
  1319. @tmenu.load doesn't work if load had parameters or if load was only
  1320. declared in an anchestor class of tmenu
  1321. Revision 1.25 1998/07/14 21:46:53 peter
  1322. * updated messages file
  1323. Revision 1.24 1998/07/10 10:48:42 peter
  1324. * fixed realnumber scanning
  1325. * [] after asmblock was not uppercased anymore
  1326. Revision 1.23 1998/06/25 08:48:18 florian
  1327. * first version of rtti support
  1328. Revision 1.22 1998/06/24 14:48:36 peter
  1329. * ifdef newppu -> ifndef oldppu
  1330. Revision 1.21 1998/06/24 14:06:34 peter
  1331. * fixed the name changes
  1332. Revision 1.20 1998/06/23 14:00:16 peter
  1333. * renamed RA* units
  1334. Revision 1.19 1998/06/08 22:59:50 peter
  1335. * smartlinking works for win32
  1336. * some defines to exclude some compiler parts
  1337. Revision 1.18 1998/06/05 14:37:35 pierre
  1338. * fixes for inline for operators
  1339. * inline procedure more correctly restricted
  1340. Revision 1.17 1998/06/04 09:55:43 pierre
  1341. * demangled name of procsym reworked to become independant of the mangling scheme
  1342. Revision 1.16 1998/06/02 17:03:04 pierre
  1343. * with node corrected for objects
  1344. * small bugs for SUPPORT_MMX fixed
  1345. Revision 1.15 1998/05/30 14:31:06 peter
  1346. + $ASMMODE
  1347. Revision 1.14 1998/05/29 09:58:14 pierre
  1348. * OPR_REGISTER for 1 arg was missing in ratti386.pas
  1349. (probably a merging problem)
  1350. * errors at start of line were lost
  1351. Revision 1.13 1998/05/28 17:26:50 peter
  1352. * fixed -R switch, it didn't work after my previous akt/init patch
  1353. * fixed bugs 110,130,136
  1354. Revision 1.12 1998/05/21 19:33:33 peter
  1355. + better procedure directive handling and only one table
  1356. Revision 1.11 1998/05/20 09:42:35 pierre
  1357. + UseTokenInfo now default
  1358. * unit in interface uses and implementation uses gives error now
  1359. * only one error for unknown symbol (uses lastsymknown boolean)
  1360. the problem came from the label code !
  1361. + first inlined procedures and function work
  1362. (warning there might be allowed cases were the result is still wrong !!)
  1363. * UseBrower updated gives a global list of all position of all used symbols
  1364. with switch -gb
  1365. Revision 1.10 1998/05/11 13:07:56 peter
  1366. + $ifdef NEWPPU for the new ppuformat
  1367. + $define GDB not longer required
  1368. * removed all warnings and stripped some log comments
  1369. * no findfirst/findnext anymore to remove smartlink *.o files
  1370. Revision 1.9 1998/05/06 08:38:46 pierre
  1371. * better position info with UseTokenInfo
  1372. UseTokenInfo greatly simplified
  1373. + added check for changed tree after first time firstpass
  1374. (if we could remove all the cases were it happen
  1375. we could skip all firstpass if firstpasscount > 1)
  1376. Only with ExtDebug
  1377. Revision 1.8 1998/05/05 12:05:42 florian
  1378. * problems with properties fixed
  1379. * crash fixed: i:=l when i and l are undefined, was a problem with
  1380. implementation of private/protected
  1381. Revision 1.7 1998/05/01 16:38:46 florian
  1382. * handling of private and protected fixed
  1383. + change_keywords_to_tp implemented to remove
  1384. keywords which aren't supported by tp
  1385. * break and continue are now symbols of the system unit
  1386. + widestring, longstring and ansistring type released
  1387. Revision 1.6 1998/04/30 15:59:42 pierre
  1388. * GDB works again better :
  1389. correct type info in one pass
  1390. + UseTokenInfo for better source position
  1391. * fixed one remaining bug in scanner for line counts
  1392. * several little fixes
  1393. Revision 1.5 1998/04/29 10:33:59 pierre
  1394. + added some code for ansistring (not complete nor working yet)
  1395. * corrected operator overloading
  1396. * corrected nasm output
  1397. + started inline procedures
  1398. + added starstarn : use ** for exponentiation (^ gave problems)
  1399. + started UseTokenInfo cond to get accurate positions
  1400. Revision 1.4 1998/04/08 16:58:05 pierre
  1401. * several bugfixes
  1402. ADD ADC and AND are also sign extended
  1403. nasm output OK (program still crashes at end
  1404. and creates wrong assembler files !!)
  1405. procsym types sym in tdef removed !!
  1406. }