pstatmnt.pas 59 KB

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