pstatmnt.pas 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
  1. {
  2. $Id$
  3. Copyright (c) 1998 by Florian Klaempfl
  4. Does the parsing of the statements
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit pstatmnt;
  19. interface
  20. uses tree;
  21. var
  22. { true, if we are in a except block }
  23. in_except_block : boolean;
  24. { reads a block }
  25. function block(islibrary : boolean) : ptree;
  26. { reads an assembler block }
  27. function assembler_block : ptree;
  28. implementation
  29. uses
  30. globtype,systems,tokens,
  31. strings,cobjects,globals,files,verbose,
  32. symtable,aasm,pass_1,types,scanner,hcodegen,ppu
  33. ,pbase,pexpr,pdecl
  34. {$ifdef i386}
  35. ,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. p:=comp_expr(true);
  723. { calc return type }
  724. cleartempgen;
  725. Store_valid := Must_be_valid;
  726. Must_be_valid := False;
  727. do_firstpass(p);
  728. Must_be_valid := Store_valid;
  729. {var o:Pobject;
  730. begin
  731. new(o,init); (*Also a valid new statement*)
  732. end;}
  733. if try_to_consume(COMMA) then
  734. begin
  735. { extended syntax of new and dispose }
  736. { function styled new is handled in factor }
  737. { destructors have no parameters }
  738. destrukname:=pattern;
  739. consume(ID);
  740. pd:=p^.resulttype;
  741. pd2:=pd;
  742. if (p^.resulttype = nil) or (pd^.deftype<>pointerdef) then
  743. begin
  744. Message(type_e_pointer_type_expected);
  745. p:=factor(false);
  746. consume(RKLAMMER);
  747. new_dispose_statement:=genzeronode(errorn);
  748. exit;
  749. end;
  750. { first parameter must be an object or class }
  751. if ppointerdef(pd)^.definition^.deftype<>objectdef then
  752. begin
  753. Message(parser_e_pointer_to_class_expected);
  754. new_dispose_statement:=factor(false);
  755. consume_all_until(RKLAMMER);
  756. consume(RKLAMMER);
  757. exit;
  758. end;
  759. { check, if the first parameter is a pointer to a _class_ }
  760. classh:=pobjectdef(ppointerdef(pd)^.definition);
  761. if (classh^.options and oo_is_class)<>0 then
  762. begin
  763. Message(parser_e_no_new_or_dispose_for_classes);
  764. new_dispose_statement:=factor(false);
  765. { while token<>RKLAMMER do
  766. consume(token); }
  767. consume_all_until(RKLAMMER);
  768. consume(RKLAMMER);
  769. exit;
  770. end;
  771. { search cons-/destructor, also in parent classes }
  772. sym:=search_class_member(classh,pattern);
  773. { the second parameter of new/dispose must be a call }
  774. { to a cons-/destructor }
  775. if (not assigned(sym)) or (sym^.typ<>procsym) then
  776. begin
  777. Message(parser_e_expr_have_to_be_destructor_call);
  778. new_dispose_statement:=genzeronode(errorn);
  779. end
  780. else
  781. begin
  782. p2:=gensinglenode(tt,p);
  783. if ht=_NEW then
  784. begin
  785. { Constructors can take parameters.}
  786. p2^.resulttype:=ppointerdef(pd)^.definition;
  787. do_member_read(false,sym,p2,pd,again);
  788. end
  789. else
  790. { destructors can't.}
  791. p2:=genmethodcallnode(pprocsym(sym),srsymtable,p2);
  792. { we need the real called method }
  793. cleartempgen;
  794. do_firstpass(p2);
  795. if not codegenerror then
  796. begin
  797. if (ht=_NEW) and ((p2^.procdefinition^.options and poconstructor)=0) then
  798. Message(parser_e_expr_have_to_be_constructor_call);
  799. if (ht=_DISPOSE) and ((p2^.procdefinition^.options and podestructor)=0) then
  800. Message(parser_e_expr_have_to_be_destructor_call);
  801. if ht=_NEW then
  802. begin
  803. p2:=gennode(assignn,getcopy(p),gensinglenode(newn,p2));
  804. p2^.right^.resulttype:=pd2;
  805. end;
  806. end;
  807. new_dispose_statement:=p2;
  808. end;
  809. end
  810. else
  811. begin
  812. if (p^.resulttype=nil) or (p^.resulttype^.deftype<>pointerdef) then
  813. Begin
  814. Message(type_e_pointer_type_expected);
  815. new_dispose_statement:=genzeronode(errorn);
  816. end
  817. else
  818. begin
  819. if (ppointerdef(p^.resulttype)^.definition^.deftype=objectdef) and
  820. ((pobjectdef(ppointerdef(p^.resulttype)^.definition)^.options and oo_hasvmt) <> 0) then
  821. Message(parser_w_use_extended_syntax_for_objects);
  822. if (ppointerdef(p^.resulttype)^.definition^.deftype=orddef) and
  823. (porddef(ppointerdef(p^.resulttype)^.definition)^.typ=uvoid) then
  824. if (m_tp in aktmodeswitches) or
  825. (m_delphi in aktmodeswitches) then
  826. Message(parser_w_no_new_dispose_on_void_pointers)
  827. else
  828. Message(parser_e_no_new_dispose_on_void_pointers);
  829. case ht of
  830. _NEW : new_dispose_statement:=gensinglenode(simplenewn,p);
  831. _DISPOSE : new_dispose_statement:=gensinglenode(simpledisposen,p);
  832. end;
  833. end;
  834. end;
  835. consume(RKLAMMER);
  836. end;
  837. function statement_block(starttoken : ttoken) : ptree;
  838. var
  839. first,last : ptree;
  840. filepos : tfileposinfo;
  841. begin
  842. first:=nil;
  843. filepos:=tokenpos;
  844. consume(starttoken);
  845. inc(statement_level);
  846. while not(token in [_END,_FINALIZATION]) do
  847. begin
  848. if first=nil then
  849. begin
  850. last:=gennode(statementn,nil,statement);
  851. first:=last;
  852. end
  853. else
  854. begin
  855. last^.left:=gennode(statementn,nil,statement);
  856. last:=last^.left;
  857. end;
  858. if (token in [_END,_FINALIZATION]) then
  859. break
  860. else
  861. begin
  862. { if no semicolon, then error and go on }
  863. if token<>SEMICOLON then
  864. begin
  865. consume(SEMICOLON);
  866. consume_all_until(SEMICOLON);
  867. end;
  868. consume(SEMICOLON);
  869. end;
  870. emptystats;
  871. end;
  872. { don't consume the finalization token, it is consumed when
  873. reading the finalization block, but allow it only after
  874. an initalization ! }
  875. if (starttoken<>_INITIALIZATION) or (token<>_FINALIZATION) then
  876. consume(_END);
  877. dec(statement_level);
  878. last:=gensinglenode(blockn,first);
  879. set_tree_filepos(last,filepos);
  880. statement_block:=last;
  881. end;
  882. function statement : ptree;
  883. var
  884. p : ptree;
  885. code : ptree;
  886. labelnr : pasmlabel;
  887. filepos : tfileposinfo;
  888. label
  889. ready;
  890. begin
  891. filepos:=tokenpos;
  892. case token of
  893. _GOTO : begin
  894. if not(cs_support_goto in aktmoduleswitches)then
  895. Message(sym_e_goto_and_label_not_supported);
  896. consume(_GOTO);
  897. if (token<>INTCONST) and (token<>ID) then
  898. begin
  899. Message(sym_e_label_not_found);
  900. code:=genzeronode(errorn);
  901. end
  902. else
  903. begin
  904. getsym(pattern,true);
  905. consume(token);
  906. if srsym^.typ<>labelsym then
  907. begin
  908. Message(sym_e_id_is_no_label_id);
  909. code:=genzeronode(errorn);
  910. end
  911. else
  912. code:=genlabelnode(goton,
  913. plabelsym(srsym)^.lab);
  914. end;
  915. end;
  916. _BEGIN : code:=statement_block(_BEGIN);
  917. _IF : code:=if_statement;
  918. _CASE : code:=case_statement;
  919. _REPEAT : code:=repeat_statement;
  920. _WHILE : code:=while_statement;
  921. _FOR : code:=for_statement;
  922. _NEW,_DISPOSE : code:=new_dispose_statement;
  923. _WITH : code:=with_statement;
  924. _TRY : code:=try_statement;
  925. _RAISE : code:=raise_statement;
  926. { semicolons,else until and end are ignored }
  927. SEMICOLON,
  928. _ELSE,
  929. _UNTIL,
  930. _END:
  931. code:=genzeronode(niln);
  932. _FAIL : begin
  933. { internalerror(100); }
  934. if (aktprocsym^.definition^.options and poconstructor)=0 then
  935. Message(parser_e_fail_only_in_constructor);
  936. consume(_FAIL);
  937. code:=genzeronode(failn);
  938. end;
  939. _EXIT : code:=exit_statement;
  940. _ASM : begin
  941. code:=_asm_statement;
  942. end;
  943. _EOF : begin
  944. Message(scan_f_end_of_file);
  945. end;
  946. else
  947. begin
  948. if (token=INTCONST) or
  949. ((token=ID) and not((m_result in aktmodeswitches) and (idtoken=_RESULT))) then
  950. begin
  951. getsym(pattern,true);
  952. lastsymknown:=true;
  953. lastsrsym:=srsym;
  954. { it is NOT necessarily the owner
  955. it can be a withsymtable !!! }
  956. lastsrsymtable:=srsymtable;
  957. if assigned(srsym) and (srsym^.typ=labelsym) then
  958. begin
  959. consume(token);
  960. consume(COLON);
  961. if plabelsym(srsym)^.defined then
  962. Message(sym_e_label_already_defined);
  963. plabelsym(srsym)^.defined:=true;
  964. { statement modifies srsym }
  965. labelnr:=plabelsym(srsym)^.lab;
  966. lastsymknown:=false;
  967. { the pointer to the following instruction }
  968. { isn't a very clean way }
  969. {$ifdef tp}
  970. code:=gensinglenode(labeln,statement);
  971. {$else}
  972. code:=gensinglenode(labeln,statement());
  973. {$endif}
  974. code^.labelnr:=labelnr;
  975. { sorry, but there is a jump the easiest way }
  976. goto ready;
  977. end;
  978. end;
  979. p:=expr;
  980. if not(p^.treetype in [calln,assignn,breakn,inlinen,
  981. continuen]) then
  982. Message(cg_e_illegal_expression);
  983. { specify that we don't use the value returned by the call }
  984. { Question : can this be also improtant
  985. for inlinen ??
  986. it is used for :
  987. - dispose of temp stack space
  988. - dispose on FPU stack }
  989. if p^.treetype=calln then
  990. p^.return_value_used:=false;
  991. code:=p;
  992. end;
  993. end;
  994. ready:
  995. if assigned(code) then
  996. set_tree_filepos(code,filepos);
  997. statement:=code;
  998. end;
  999. function block(islibrary : boolean) : ptree;
  1000. var
  1001. funcretsym : pfuncretsym;
  1002. begin
  1003. if procinfo.retdef<>pdef(voiddef) then
  1004. begin
  1005. { if the current is a function aktprocsym is non nil }
  1006. { and there is a local symtable set }
  1007. funcretsym:=new(pfuncretsym,init(aktprocsym^.name,@procinfo));
  1008. { insert in local symtable }
  1009. symtablestack^.insert(funcretsym);
  1010. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  1011. procinfo.retoffset:=-funcretsym^.address;
  1012. procinfo.funcretsym:=funcretsym;
  1013. end;
  1014. read_declarations(islibrary);
  1015. { temporary space is set, while the BEGIN of the procedure }
  1016. if (symtablestack^.symtabletype=localsymtable) then
  1017. procinfo.firsttemp := -symtablestack^.datasize
  1018. else procinfo.firsttemp := 0;
  1019. { space for the return value }
  1020. { !!!!! this means that we can not set the return value
  1021. in a subfunction !!!!! }
  1022. { because we don't know yet where the address is }
  1023. if procinfo.retdef<>pdef(voiddef) then
  1024. begin
  1025. if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
  1026. { if (procinfo.retdef^.deftype=orddef) or
  1027. (procinfo.retdef^.deftype=pointerdef) or
  1028. (procinfo.retdef^.deftype=enumdef) or
  1029. (procinfo.retdef^.deftype=procvardef) or
  1030. (procinfo.retdef^.deftype=floatdef) or
  1031. (
  1032. (procinfo.retdef^.deftype=setdef) and
  1033. (psetdef(procinfo.retdef)^.settype=smallset)
  1034. ) then }
  1035. begin
  1036. { the space has been set in the local symtable }
  1037. procinfo.retoffset:=-funcretsym^.address;
  1038. if (procinfo.flags and pi_operator)<>0 then
  1039. {opsym^.address:=procinfo.call_offset; is wrong PM }
  1040. opsym^.address:=-procinfo.retoffset;
  1041. { eax is modified by a function }
  1042. {$ifdef i386}
  1043. usedinproc:=usedinproc or ($80 shr byte(R_EAX));
  1044. if is_64bitint(procinfo.retdef) then
  1045. usedinproc:=usedinproc or ($80 shr byte(R_EDX))
  1046. {$endif}
  1047. {$ifdef m68k}
  1048. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1049. if is_64bitint(procinfo.retdef) then
  1050. usedinproc:=usedinproc or ($800 shr byte(R_D1))
  1051. {$endif}
  1052. end;
  1053. end;
  1054. {Unit initialization?.}
  1055. if (lexlevel=unit_init_level) and (current_module^.is_unit) then
  1056. if (token=_END) then
  1057. begin
  1058. consume(_END);
  1059. block:=nil;
  1060. end
  1061. else
  1062. begin
  1063. if token=_INITIALIZATION then
  1064. begin
  1065. current_module^.flags:=current_module^.flags or uf_init;
  1066. block:=statement_block(_INITIALIZATION);
  1067. end
  1068. else if (token=_FINALIZATION) then
  1069. begin
  1070. if (current_module^.flags and uf_finalize)<>0 then
  1071. block:=statement_block(_FINALIZATION)
  1072. else
  1073. begin
  1074. block:=nil;
  1075. exit;
  1076. end;
  1077. end
  1078. else
  1079. begin
  1080. current_module^.flags:=current_module^.flags or uf_init;
  1081. block:=statement_block(_BEGIN);
  1082. end;
  1083. end
  1084. else
  1085. block:=statement_block(_BEGIN);
  1086. end;
  1087. function assembler_block : ptree;
  1088. begin
  1089. read_declarations(false);
  1090. { temporary space is set, while the BEGIN of the procedure }
  1091. if symtablestack^.symtabletype=localsymtable then
  1092. procinfo.firsttemp := -symtablestack^.datasize
  1093. else
  1094. procinfo.firsttemp := 0;
  1095. { assembler code does not allocate }
  1096. { space for the return value }
  1097. if procinfo.retdef<>pdef(voiddef) then
  1098. begin
  1099. if ret_in_acc(procinfo.retdef) then
  1100. begin
  1101. { in assembler code the result should be directly in %eax
  1102. procinfo.retoffset:=procinfo.firsttemp-procinfo.retdef^.size;
  1103. procinfo.firsttemp:=procinfo.retoffset; }
  1104. {$ifdef i386}
  1105. usedinproc:=usedinproc or ($80 shr byte(R_EAX))
  1106. {$endif}
  1107. {$ifdef m68k}
  1108. usedinproc:=usedinproc or ($800 shr word(R_D0))
  1109. {$endif}
  1110. end
  1111. {
  1112. else if not is_fpu(procinfo.retdef) then
  1113. should we allow assembler functions of big elements ?
  1114. YES (FK)!!
  1115. Message(parser_e_asm_incomp_with_function_return);
  1116. }
  1117. end;
  1118. { set the framepointer to esp for assembler functions }
  1119. { but only if the are no local variables }
  1120. { added no parameter also (PM) }
  1121. if ((aktprocsym^.definition^.options and poassembler)<>0) and
  1122. (aktprocsym^.definition^.localst^.datasize=0) and
  1123. (aktprocsym^.definition^.parast^.datasize=0) and
  1124. not(ret_in_param(aktprocsym^.definition^.retdef)) then
  1125. begin
  1126. procinfo.framepointer:=stack_pointer;
  1127. { set the right value for parameters }
  1128. dec(aktprocsym^.definition^.parast^.address_fixup,target_os.size_of_pointer);
  1129. dec(procinfo.call_offset,target_os.size_of_pointer);
  1130. end;
  1131. { force the asm statement }
  1132. if token<>_ASM then
  1133. consume(_ASM);
  1134. Procinfo.Flags := ProcInfo.Flags Or pi_is_assembler;
  1135. assembler_block:=_asm_statement;
  1136. { becuase the END is already read we need to get the
  1137. last_endtoken_filepos here (PFV) }
  1138. last_endtoken_filepos:=tokenpos;
  1139. end;
  1140. end.
  1141. {
  1142. $Log$
  1143. Revision 1.87 1999-05-27 19:44:50 peter
  1144. * removed oldasm
  1145. * plabel -> pasmlabel
  1146. * -a switches to source writing automaticly
  1147. * assembler readers OOPed
  1148. * asmsymbol automaticly external
  1149. * jumptables and other label fixes for asm readers
  1150. Revision 1.86 1999/05/21 13:55:08 peter
  1151. * NEWLAB for label as symbol
  1152. Revision 1.85 1999/05/17 23:51:40 peter
  1153. * with temp vars now use a reference with a persistant temp instead
  1154. of setting datasize
  1155. Revision 1.84 1999/05/13 21:59:38 peter
  1156. * removed oldppu code
  1157. * warning if objpas is loaded from uses
  1158. * first things for new deref writing
  1159. Revision 1.83 1999/05/05 22:21:58 peter
  1160. * updated messages
  1161. Revision 1.82 1999/05/01 13:24:35 peter
  1162. * merged nasm compiler
  1163. * old asm moved to oldasm/
  1164. Revision 1.81 1999/04/26 13:31:42 peter
  1165. * release storenumber,double_checksum
  1166. Revision 1.80 1999/04/21 09:43:48 peter
  1167. * storenumber works
  1168. * fixed some typos in double_checksum
  1169. + incompatible types type1 and type2 message (with storenumber)
  1170. Revision 1.79 1999/04/16 12:14:49 pierre
  1171. * void pointer accepted with warning in tp and delphi mode
  1172. Revision 1.78 1999/04/15 12:58:14 pierre
  1173. * fix for bug0234
  1174. Revision 1.77 1999/04/15 09:01:33 peter
  1175. * fixed set loading
  1176. * object inheritance support for browser
  1177. Revision 1.76 1999/04/14 18:41:25 daniel
  1178. * Better use of routines in pbase and symtable. 4k code removed.
  1179. Revision 1.75 1999/04/14 09:14:53 peter
  1180. * first things to store the symbol/def number in the ppu
  1181. Revision 1.74 1999/04/09 12:22:06 pierre
  1182. * bug found by Peter for DirectWith code fixed
  1183. Revision 1.73 1999/04/06 11:21:57 peter
  1184. * more use of ttoken
  1185. Revision 1.72 1999/03/31 13:55:15 peter
  1186. * assembler inlining working for ag386bin
  1187. Revision 1.71 1999/03/10 11:23:29 pierre
  1188. * typecheck for exit(value) : resulttype was not set
  1189. Revision 1.70 1999/03/04 13:55:45 pierre
  1190. * some m68k fixes (still not compilable !)
  1191. * new(tobj) does not give warning if tobj has no VMT !
  1192. Revision 1.69 1999/03/02 02:56:15 peter
  1193. + stabs support for binary writers
  1194. * more fixes and missing updates from the previous commit :(
  1195. Revision 1.68 1999/02/26 00:48:23 peter
  1196. * assembler writers fixed for ag386bin
  1197. Revision 1.67 1999/02/22 13:07:01 pierre
  1198. + -b and -bl options work !
  1199. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  1200. is not enabled when quitting global section
  1201. * local vars and procedures are not yet stored into PPU
  1202. Revision 1.66 1999/02/22 02:15:31 peter
  1203. * updates for ag386bin
  1204. Revision 1.65 1999/02/15 13:13:15 pierre
  1205. * fix for bug0216
  1206. Revision 1.64 1999/02/11 09:46:26 pierre
  1207. * fix for normal method calls inside static methods :
  1208. WARNING there were both parser and codegen errors !!
  1209. added static_call boolean to calln tree
  1210. Revision 1.63 1999/02/09 15:45:47 florian
  1211. + complex results for assembler functions, fixes bug0155
  1212. Revision 1.62 1999/01/27 13:06:57 pierre
  1213. * memory leak in case optimization fixed
  1214. Revision 1.61 1999/01/25 22:49:09 peter
  1215. * more fixes for the on bug with unknown id
  1216. Revision 1.60 1999/01/23 23:29:38 florian
  1217. * first running version of the new code generator
  1218. * when compiling exceptions under Linux fixed
  1219. Revision 1.59 1999/01/21 16:41:02 pierre
  1220. * fix for constructor inside with statements
  1221. Revision 1.58 1999/01/05 08:20:07 florian
  1222. * mainly problem with invalid case ranges fixed (reported by Jonas)
  1223. Revision 1.57 1998/12/29 18:48:15 jonas
  1224. + optimize pascal code surrounding assembler blocks
  1225. Revision 1.56 1998/12/23 22:52:56 peter
  1226. * fixed new(x) crash if x contains an error
  1227. Revision 1.55 1998/12/16 12:30:59 jonas
  1228. * released CaseRange
  1229. Revision 1.54 1998/12/15 22:32:24 jonas
  1230. + convert consecutive case labels to a single range (-dCaseRange)
  1231. Revision 1.53 1998/12/15 11:52:18 peter
  1232. * fixed dup release of statement label in case
  1233. Revision 1.52 1998/12/11 00:03:37 peter
  1234. + globtype,tokens,version unit splitted from globals
  1235. Revision 1.51 1998/12/10 09:47:24 florian
  1236. + basic operations with int64/qord (compiler with -dint64)
  1237. + rtti of enumerations extended: names are now written
  1238. Revision 1.50 1998/11/13 15:40:25 pierre
  1239. + added -Se in Makefile cvstest target
  1240. + lexlevel cleanup
  1241. normal_function_level main_program_level and unit_init_level defined
  1242. * tins_cache grown to A_EMMS (gave range check error in asm readers)
  1243. (test added in code !)
  1244. * -Un option was wrong
  1245. * _FAIL and _SELF only keyword inside
  1246. constructors and methods respectively
  1247. Revision 1.49 1998/11/12 12:55:17 pierre
  1248. * fix for bug0176 and bug0177
  1249. Revision 1.48 1998/11/05 23:43:24 peter
  1250. * fixed assembler directive and then not an ASM statement
  1251. Revision 1.47 1998/10/30 16:20:22 peter
  1252. * fixed dispose(destructor) crash when destructor didn't exists
  1253. Revision 1.46 1998/10/20 08:06:53 pierre
  1254. * several memory corruptions due to double freemem solved
  1255. => never use p^.loc.location:=p^.left^.loc.location;
  1256. + finally I added now by default
  1257. that ra386dir translates global and unit symbols
  1258. + added a first field in tsymtable and
  1259. a nextsym field in tsym
  1260. (this allows to obtain ordered type info for
  1261. records and objects in gdb !)
  1262. Revision 1.45 1998/10/19 08:55:01 pierre
  1263. * wrong stabs info corrected once again !!
  1264. + variable vmt offset with vmt field only if required
  1265. implemented now !!!
  1266. Revision 1.44 1998/10/13 13:10:27 peter
  1267. * new style for m68k/i386 infos and enums
  1268. Revision 1.43 1998/10/08 13:46:22 peter
  1269. * added eof message
  1270. * fixed unit init section parsing with finalize
  1271. Revision 1.42 1998/09/26 17:45:38 peter
  1272. + idtoken and only one token table
  1273. Revision 1.41 1998/09/24 23:49:15 peter
  1274. + aktmodeswitches
  1275. Revision 1.40 1998/09/23 21:53:04 florian
  1276. * the following doesn't work: on texception do, was a parser error, fixed
  1277. Revision 1.39 1998/09/21 10:26:07 peter
  1278. * merged fix
  1279. Revision 1.38.2.1 1998/09/21 10:24:43 peter
  1280. * fixed error recovery with with
  1281. Revision 1.38 1998/09/04 08:42:04 peter
  1282. * updated some error messages
  1283. Revision 1.37 1998/08/21 14:08:52 pierre
  1284. + TEST_FUNCRET now default (old code removed)
  1285. works also for m68k (at least compiles)
  1286. Revision 1.36 1998/08/20 21:36:41 peter
  1287. * fixed 'with object do' bug
  1288. Revision 1.35 1998/08/20 09:26:42 pierre
  1289. + funcret setting in underproc testing
  1290. compile with _dTEST_FUNCRET
  1291. Revision 1.34 1998/08/17 10:10:09 peter
  1292. - removed OLDPPU
  1293. Revision 1.33 1998/08/12 19:39:30 peter
  1294. * fixed some crashes
  1295. Revision 1.32 1998/08/10 14:50:17 peter
  1296. + localswitches, moduleswitches, globalswitches splitting
  1297. Revision 1.31 1998/08/02 16:41:59 florian
  1298. * on o : tobject do should also work now, the exceptsymtable shouldn't be
  1299. disposed by dellexlevel
  1300. Revision 1.30 1998/07/30 16:07:10 florian
  1301. * try ... expect <statement> end; works now
  1302. Revision 1.29 1998/07/30 13:30:37 florian
  1303. * final implemenation of exception support, maybe it needs
  1304. some fixes :)
  1305. Revision 1.28 1998/07/30 11:18:18 florian
  1306. + first implementation of try ... except on .. do end;
  1307. * limitiation of 65535 bytes parameters for cdecl removed
  1308. Revision 1.27 1998/07/28 21:52:55 florian
  1309. + implementation of raise and try..finally
  1310. + some misc. exception stuff
  1311. Revision 1.26 1998/07/27 21:57:14 florian
  1312. * fix to allow tv like stream registration:
  1313. @tmenu.load doesn't work if load had parameters or if load was only
  1314. declared in an anchestor class of tmenu
  1315. Revision 1.25 1998/07/14 21:46:53 peter
  1316. * updated messages file
  1317. Revision 1.24 1998/07/10 10:48:42 peter
  1318. * fixed realnumber scanning
  1319. * [] after asmblock was not uppercased anymore
  1320. Revision 1.23 1998/06/25 08:48:18 florian
  1321. * first version of rtti support
  1322. Revision 1.22 1998/06/24 14:48:36 peter
  1323. * ifdef newppu -> ifndef oldppu
  1324. Revision 1.21 1998/06/24 14:06:34 peter
  1325. * fixed the name changes
  1326. Revision 1.20 1998/06/23 14:00:16 peter
  1327. * renamed RA* units
  1328. Revision 1.19 1998/06/08 22:59:50 peter
  1329. * smartlinking works for win32
  1330. * some defines to exclude some compiler parts
  1331. Revision 1.18 1998/06/05 14:37:35 pierre
  1332. * fixes for inline for operators
  1333. * inline procedure more correctly restricted
  1334. Revision 1.17 1998/06/04 09:55:43 pierre
  1335. * demangled name of procsym reworked to become independant of the mangling scheme
  1336. Revision 1.16 1998/06/02 17:03:04 pierre
  1337. * with node corrected for objects
  1338. * small bugs for SUPPORT_MMX fixed
  1339. Revision 1.15 1998/05/30 14:31:06 peter
  1340. + $ASMMODE
  1341. Revision 1.14 1998/05/29 09:58:14 pierre
  1342. * OPR_REGISTER for 1 arg was missing in ratti386.pas
  1343. (probably a merging problem)
  1344. * errors at start of line were lost
  1345. Revision 1.13 1998/05/28 17:26:50 peter
  1346. * fixed -R switch, it didn't work after my previous akt/init patch
  1347. * fixed bugs 110,130,136
  1348. Revision 1.12 1998/05/21 19:33:33 peter
  1349. + better procedure directive handling and only one table
  1350. Revision 1.11 1998/05/20 09:42:35 pierre
  1351. + UseTokenInfo now default
  1352. * unit in interface uses and implementation uses gives error now
  1353. * only one error for unknown symbol (uses lastsymknown boolean)
  1354. the problem came from the label code !
  1355. + first inlined procedures and function work
  1356. (warning there might be allowed cases were the result is still wrong !!)
  1357. * UseBrower updated gives a global list of all position of all used symbols
  1358. with switch -gb
  1359. Revision 1.10 1998/05/11 13:07:56 peter
  1360. + $ifdef NEWPPU for the new ppuformat
  1361. + $define GDB not longer required
  1362. * removed all warnings and stripped some log comments
  1363. * no findfirst/findnext anymore to remove smartlink *.o files
  1364. Revision 1.9 1998/05/06 08:38:46 pierre
  1365. * better position info with UseTokenInfo
  1366. UseTokenInfo greatly simplified
  1367. + added check for changed tree after first time firstpass
  1368. (if we could remove all the cases were it happen
  1369. we could skip all firstpass if firstpasscount > 1)
  1370. Only with ExtDebug
  1371. Revision 1.8 1998/05/05 12:05:42 florian
  1372. * problems with properties fixed
  1373. * crash fixed: i:=l when i and l are undefined, was a problem with
  1374. implementation of private/protected
  1375. Revision 1.7 1998/05/01 16:38:46 florian
  1376. * handling of private and protected fixed
  1377. + change_keywords_to_tp implemented to remove
  1378. keywords which aren't supported by tp
  1379. * break and continue are now symbols of the system unit
  1380. + widestring, longstring and ansistring type released
  1381. Revision 1.6 1998/04/30 15:59:42 pierre
  1382. * GDB works again better :
  1383. correct type info in one pass
  1384. + UseTokenInfo for better source position
  1385. * fixed one remaining bug in scanner for line counts
  1386. * several little fixes
  1387. Revision 1.5 1998/04/29 10:33:59 pierre
  1388. + added some code for ansistring (not complete nor working yet)
  1389. * corrected operator overloading
  1390. * corrected nasm output
  1391. + started inline procedures
  1392. + added starstarn : use ** for exponentiation (^ gave problems)
  1393. + started UseTokenInfo cond to get accurate positions
  1394. Revision 1.4 1998/04/08 16:58:05 pierre
  1395. * several bugfixes
  1396. ADD ADC and AND are also sign extended
  1397. nasm output OK (program still crashes at end
  1398. and creates wrong assembler files !!)
  1399. procsym types sym in tdef removed !!
  1400. }