pstatmnt.pas 55 KB

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