pstatmnt.pas 48 KB

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