tcinl.pas 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Type checking and register allocation for inline nodes
  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 tcinl;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. tree;
  23. procedure firstinline(var p : ptree);
  24. implementation
  25. uses
  26. cobjects,verbose,globals,systems,
  27. globtype,
  28. symconst,symtable,aasm,types,
  29. htypechk,pass_1,
  30. tccal,cpubase
  31. {$ifdef newcg}
  32. ,cgbase
  33. ,tgobj
  34. ,tgcpu
  35. {$else newcg}
  36. ,hcodegen
  37. {$ifdef i386}
  38. ,tgeni386
  39. {$endif}
  40. {$endif newcg}
  41. ;
  42. {*****************************************************************************
  43. FirstInLine
  44. *****************************************************************************}
  45. {$ifdef fpc}
  46. {$maxfpuregisters 0}
  47. {$endif fpc}
  48. procedure firstinline(var p : ptree);
  49. var
  50. vl,vl2 : longint;
  51. vr : bestreal;
  52. p1,hp,hpp : ptree;
  53. {$ifndef NOCOLONCHECK}
  54. frac_para,length_para : ptree;
  55. {$endif ndef NOCOLONCHECK}
  56. extra_register,
  57. isreal,
  58. dowrite,
  59. file_is_typed : boolean;
  60. procedure do_lowhigh(adef : pdef);
  61. var
  62. v : longint;
  63. enum : penumsym;
  64. begin
  65. case Adef^.deftype of
  66. orddef:
  67. begin
  68. if p^.inlinenumber=in_low_x then
  69. v:=porddef(adef)^.low
  70. else
  71. v:=porddef(adef)^.high;
  72. hp:=genordinalconstnode(v,adef);
  73. firstpass(hp);
  74. disposetree(p);
  75. p:=hp;
  76. end;
  77. enumdef:
  78. begin
  79. enum:=Penumdef(Adef)^.firstenum;
  80. if p^.inlinenumber=in_high_x then
  81. while enum^.nextenum<>nil do
  82. enum:=enum^.nextenum;
  83. hp:=genenumnode(enum);
  84. disposetree(p);
  85. p:=hp;
  86. end;
  87. else
  88. internalerror(87);
  89. end;
  90. end;
  91. function getconstrealvalue : bestreal;
  92. begin
  93. case p^.left^.treetype of
  94. ordconstn:
  95. getconstrealvalue:=p^.left^.value;
  96. realconstn:
  97. getconstrealvalue:=p^.left^.value_real;
  98. else
  99. internalerror(309992);
  100. end;
  101. end;
  102. procedure setconstrealvalue(r : bestreal);
  103. var
  104. hp : ptree;
  105. begin
  106. hp:=genrealconstnode(r,bestrealdef^);
  107. disposetree(p);
  108. p:=hp;
  109. firstpass(p);
  110. end;
  111. procedure handleextendedfunction;
  112. begin
  113. p^.location.loc:=LOC_FPU;
  114. p^.resulttype:=s80floatdef;
  115. { redo firstpass for varstate status PM }
  116. set_varstate(p^.left,true);
  117. if (p^.left^.resulttype^.deftype<>floatdef) or
  118. (pfloatdef(p^.left^.resulttype)^.typ<>s80real) then
  119. begin
  120. p^.left:=gentypeconvnode(p^.left,s80floatdef);
  121. firstpass(p^.left);
  122. end;
  123. p^.registers32:=p^.left^.registers32;
  124. p^.registersfpu:=p^.left^.registersfpu;
  125. {$ifdef SUPPORT_MMX}
  126. p^.registersmmx:=p^.left^.registersmmx;
  127. {$endif SUPPORT_MMX}
  128. end;
  129. begin
  130. { if we handle writeln; p^.left contains no valid address }
  131. if assigned(p^.left) then
  132. begin
  133. if p^.left^.treetype=callparan then
  134. firstcallparan(p^.left,nil,false)
  135. else
  136. firstpass(p^.left);
  137. left_right_max(p);
  138. set_location(p^.location,p^.left^.location);
  139. end;
  140. inc(parsing_para_level);
  141. { handle intern constant functions in separate case }
  142. if p^.inlineconst then
  143. begin
  144. hp:=nil;
  145. { no parameters? }
  146. if not assigned(p^.left) then
  147. begin
  148. case p^.inlinenumber of
  149. in_const_pi :
  150. hp:=genrealconstnode(pi,bestrealdef^);
  151. else
  152. internalerror(89);
  153. end;
  154. end
  155. else
  156. { process constant expression with parameter }
  157. begin
  158. vl:=0;
  159. vl2:=0; { second parameter Ex: ptr(vl,vl2) }
  160. vr:=0;
  161. isreal:=false;
  162. case p^.left^.treetype of
  163. realconstn :
  164. begin
  165. isreal:=true;
  166. vr:=p^.left^.value_real;
  167. end;
  168. ordconstn :
  169. vl:=p^.left^.value;
  170. callparan :
  171. begin
  172. { both exists, else it was not generated }
  173. vl:=p^.left^.left^.value;
  174. vl2:=p^.left^.right^.left^.value;
  175. end;
  176. else
  177. CGMessage(cg_e_illegal_expression);
  178. end;
  179. case p^.inlinenumber of
  180. in_const_trunc :
  181. begin
  182. if isreal then
  183. begin
  184. if (vr>=2147483648.0) or (vr<=-2147483649.0) then
  185. begin
  186. CGMessage(parser_e_range_check_error);
  187. hp:=genordinalconstnode(1,s32bitdef)
  188. end
  189. else
  190. hp:=genordinalconstnode(trunc(vr),s32bitdef)
  191. end
  192. else
  193. hp:=genordinalconstnode(trunc(vl),s32bitdef);
  194. end;
  195. in_const_round :
  196. begin
  197. if isreal then
  198. begin
  199. if (vr>=2147483647.5) or (vr<=-2147483648.5) then
  200. begin
  201. CGMessage(parser_e_range_check_error);
  202. hp:=genordinalconstnode(1,s32bitdef)
  203. end
  204. else
  205. hp:=genordinalconstnode(round(vr),s32bitdef)
  206. end
  207. else
  208. hp:=genordinalconstnode(round(vl),s32bitdef);
  209. end;
  210. in_const_frac :
  211. begin
  212. if isreal then
  213. hp:=genrealconstnode(frac(vr),bestrealdef^)
  214. else
  215. hp:=genrealconstnode(frac(vl),bestrealdef^);
  216. end;
  217. in_const_int :
  218. begin
  219. if isreal then
  220. hp:=genrealconstnode(int(vr),bestrealdef^)
  221. else
  222. hp:=genrealconstnode(int(vl),bestrealdef^);
  223. end;
  224. in_const_abs :
  225. begin
  226. if isreal then
  227. hp:=genrealconstnode(abs(vr),bestrealdef^)
  228. else
  229. hp:=genordinalconstnode(abs(vl),p^.left^.resulttype);
  230. end;
  231. in_const_sqr :
  232. begin
  233. if isreal then
  234. hp:=genrealconstnode(sqr(vr),bestrealdef^)
  235. else
  236. hp:=genordinalconstnode(sqr(vl),p^.left^.resulttype);
  237. end;
  238. in_const_odd :
  239. begin
  240. if isreal then
  241. CGMessage1(type_e_integer_expr_expected,p^.left^.resulttype^.typename)
  242. else
  243. hp:=genordinalconstnode(byte(odd(vl)),booldef);
  244. end;
  245. in_const_swap_word :
  246. begin
  247. if isreal then
  248. CGMessage1(type_e_integer_expr_expected,p^.left^.resulttype^.typename)
  249. else
  250. hp:=genordinalconstnode((vl and $ff) shl 8+(vl shr 8),p^.left^.resulttype);
  251. end;
  252. in_const_swap_long :
  253. begin
  254. if isreal then
  255. CGMessage(type_e_mismatch)
  256. else
  257. hp:=genordinalconstnode((vl and $ffff) shl 16+(vl shr 16),p^.left^.resulttype);
  258. end;
  259. in_const_ptr :
  260. begin
  261. if isreal then
  262. CGMessage(type_e_mismatch)
  263. else
  264. hp:=genordinalconstnode((vl2 shl 16) or vl,voidpointerdef);
  265. end;
  266. in_const_sqrt :
  267. begin
  268. if isreal then
  269. begin
  270. if vr<0.0 then
  271. CGMessage(type_e_wrong_math_argument)
  272. else
  273. hp:=genrealconstnode(sqrt(vr),bestrealdef^)
  274. end
  275. else
  276. begin
  277. if vl<0 then
  278. CGMessage(type_e_wrong_math_argument)
  279. else
  280. hp:=genrealconstnode(sqrt(vl),bestrealdef^);
  281. end;
  282. end;
  283. in_const_arctan :
  284. begin
  285. if isreal then
  286. hp:=genrealconstnode(arctan(vr),bestrealdef^)
  287. else
  288. hp:=genrealconstnode(arctan(vl),bestrealdef^);
  289. end;
  290. in_const_cos :
  291. begin
  292. if isreal then
  293. hp:=genrealconstnode(cos(vr),bestrealdef^)
  294. else
  295. hp:=genrealconstnode(cos(vl),bestrealdef^);
  296. end;
  297. in_const_sin :
  298. begin
  299. if isreal then
  300. hp:=genrealconstnode(sin(vr),bestrealdef^)
  301. else
  302. hp:=genrealconstnode(sin(vl),bestrealdef^);
  303. end;
  304. in_const_exp :
  305. begin
  306. if isreal then
  307. hp:=genrealconstnode(exp(vr),bestrealdef^)
  308. else
  309. hp:=genrealconstnode(exp(vl),bestrealdef^);
  310. end;
  311. in_const_ln :
  312. begin
  313. if isreal then
  314. begin
  315. if vr<=0.0 then
  316. CGMessage(type_e_wrong_math_argument)
  317. else
  318. hp:=genrealconstnode(ln(vr),bestrealdef^)
  319. end
  320. else
  321. begin
  322. if vl<=0 then
  323. CGMessage(type_e_wrong_math_argument)
  324. else
  325. hp:=genrealconstnode(ln(vl),bestrealdef^);
  326. end;
  327. end;
  328. else
  329. internalerror(88);
  330. end;
  331. end;
  332. disposetree(p);
  333. if hp=nil then
  334. hp:=genzeronode(errorn);
  335. firstpass(hp);
  336. p:=hp;
  337. end
  338. else
  339. begin
  340. case p^.inlinenumber of
  341. in_lo_qword,
  342. in_hi_qword,
  343. in_lo_long,
  344. in_hi_long,
  345. in_lo_word,
  346. in_hi_word:
  347. begin
  348. set_varstate(p^.left,true);
  349. if p^.registers32<1 then
  350. p^.registers32:=1;
  351. if p^.inlinenumber in [in_lo_word,in_hi_word] then
  352. p^.resulttype:=u8bitdef
  353. else if p^.inlinenumber in [in_lo_qword,in_hi_qword] then
  354. begin
  355. p^.resulttype:=u32bitdef;
  356. if (m_tp in aktmodeswitches) or
  357. (m_delphi in aktmodeswitches) then
  358. CGMessage(type_w_maybe_wrong_hi_lo);
  359. end
  360. else
  361. begin
  362. p^.resulttype:=u16bitdef;
  363. if (m_tp in aktmodeswitches) or
  364. (m_delphi in aktmodeswitches) then
  365. CGMessage(type_w_maybe_wrong_hi_lo);
  366. end;
  367. p^.location.loc:=LOC_REGISTER;
  368. if not is_integer(p^.left^.resulttype) then
  369. CGMessage(type_e_mismatch)
  370. else
  371. begin
  372. if p^.left^.treetype=ordconstn then
  373. begin
  374. case p^.inlinenumber of
  375. in_lo_word : hp:=genordinalconstnode(p^.left^.value and $ff,p^.left^.resulttype);
  376. in_hi_word : hp:=genordinalconstnode(p^.left^.value shr 8,p^.left^.resulttype);
  377. in_lo_long : hp:=genordinalconstnode(p^.left^.value and $ffff,p^.left^.resulttype);
  378. in_hi_long : hp:=genordinalconstnode(p^.left^.value shr 16,p^.left^.resulttype);
  379. in_lo_qword : hp:=genordinalconstnode(p^.left^.value and $ffffffff,p^.left^.resulttype);
  380. in_hi_qword : hp:=genordinalconstnode(p^.left^.value shr 32,p^.left^.resulttype);
  381. end;
  382. disposetree(p);
  383. firstpass(hp);
  384. p:=hp;
  385. end;
  386. end;
  387. end;
  388. in_sizeof_x:
  389. begin
  390. set_varstate(p^.left,false);
  391. if push_high_param(p^.left^.resulttype) then
  392. begin
  393. getsymonlyin(p^.left^.symtable,'high'+pvarsym(p^.left^.symtableentry)^.name);
  394. hp:=gennode(addn,genloadnode(pvarsym(srsym),p^.left^.symtable),
  395. genordinalconstnode(1,s32bitdef));
  396. if (p^.left^.resulttype^.deftype=arraydef) and
  397. (parraydef(p^.left^.resulttype)^.elesize<>1) then
  398. hp:=gennode(muln,hp,genordinalconstnode(parraydef(p^.left^.resulttype)^.elesize,s32bitdef));
  399. disposetree(p);
  400. p:=hp;
  401. firstpass(p);
  402. end;
  403. if p^.registers32<1 then
  404. p^.registers32:=1;
  405. p^.resulttype:=s32bitdef;
  406. p^.location.loc:=LOC_REGISTER;
  407. end;
  408. in_typeof_x:
  409. begin
  410. set_varstate(p^.left,false);
  411. if p^.registers32<1 then
  412. p^.registers32:=1;
  413. p^.location.loc:=LOC_REGISTER;
  414. p^.resulttype:=voidpointerdef;
  415. end;
  416. in_ord_x:
  417. begin
  418. set_varstate(p^.left,true);
  419. if (p^.left^.treetype=ordconstn) then
  420. begin
  421. hp:=genordinalconstnode(p^.left^.value,s32bitdef);
  422. disposetree(p);
  423. p:=hp;
  424. firstpass(p);
  425. end
  426. else
  427. begin
  428. { otherwise you get a crash if you try ord on an expression containing }
  429. { an undeclared variable (JM) }
  430. if not assigned(p^.left^.resulttype) then
  431. exit;
  432. if (p^.left^.resulttype^.deftype=orddef) then
  433. if (porddef(p^.left^.resulttype)^.typ in [uchar,uwidechar,bool8bit]) then
  434. case porddef(p^.left^.resulttype)^.typ of
  435. uchar:
  436. begin
  437. hp:=gentypeconvnode(p^.left,u8bitdef);
  438. putnode(p);
  439. p:=hp;
  440. p^.explizit:=true;
  441. firstpass(p);
  442. end;
  443. uwidechar:
  444. begin
  445. hp:=gentypeconvnode(p^.left,u16bitdef);
  446. putnode(p);
  447. p:=hp;
  448. p^.explizit:=true;
  449. firstpass(p);
  450. end;
  451. bool8bit:
  452. begin
  453. hp:=gentypeconvnode(p^.left,u8bitdef);
  454. putnode(p);
  455. p:=hp;
  456. p^.convtyp:=tc_bool_2_int;
  457. p^.explizit:=true;
  458. firstpass(p);
  459. end
  460. end
  461. { can this happen ? }
  462. else if (porddef(p^.left^.resulttype)^.typ=uvoid) then
  463. CGMessage(type_e_mismatch)
  464. else
  465. { all other orddef need no transformation }
  466. begin
  467. hp:=p^.left;
  468. putnode(p);
  469. p:=hp;
  470. end
  471. else if (p^.left^.resulttype^.deftype=enumdef) then
  472. begin
  473. hp:=gentypeconvnode(p^.left,s32bitdef);
  474. putnode(p);
  475. p:=hp;
  476. p^.explizit:=true;
  477. firstpass(p);
  478. end
  479. else
  480. begin
  481. { can anything else be ord() ?}
  482. CGMessage(type_e_mismatch);
  483. end;
  484. end;
  485. end;
  486. in_chr_byte:
  487. begin
  488. set_varstate(p^.left,true);
  489. hp:=gentypeconvnode(p^.left,cchardef);
  490. putnode(p);
  491. p:=hp;
  492. p^.explizit:=true;
  493. firstpass(p);
  494. end;
  495. in_length_string:
  496. begin
  497. set_varstate(p^.left,true);
  498. if is_ansistring(p^.left^.resulttype) then
  499. p^.resulttype:=s32bitdef
  500. else
  501. p^.resulttype:=u8bitdef;
  502. { we don't need string conversations here }
  503. if (p^.left^.treetype=typeconvn) and
  504. (p^.left^.left^.resulttype^.deftype=stringdef) then
  505. begin
  506. hp:=p^.left^.left;
  507. putnode(p^.left);
  508. p^.left:=hp;
  509. end;
  510. { check the type, must be string or char }
  511. if (p^.left^.resulttype^.deftype<>stringdef) and
  512. (not is_char(p^.left^.resulttype)) then
  513. CGMessage(type_e_mismatch);
  514. { evaluates length of constant strings direct }
  515. if (p^.left^.treetype=stringconstn) then
  516. begin
  517. hp:=genordinalconstnode(p^.left^.length,s32bitdef);
  518. disposetree(p);
  519. firstpass(hp);
  520. p:=hp;
  521. end
  522. { length of char is one allways }
  523. else if is_constcharnode(p^.left) then
  524. begin
  525. hp:=genordinalconstnode(1,s32bitdef);
  526. disposetree(p);
  527. firstpass(hp);
  528. p:=hp;
  529. end;
  530. end;
  531. in_typeinfo_x:
  532. begin
  533. p^.resulttype:=voidpointerdef;
  534. p^.location.loc:=LOC_REGISTER;
  535. p^.registers32:=1;
  536. end;
  537. in_assigned_x:
  538. begin
  539. set_varstate(p^.left,true);
  540. p^.resulttype:=booldef;
  541. p^.location.loc:=LOC_FLAGS;
  542. end;
  543. in_ofs_x,
  544. in_seg_x :
  545. set_varstate(p^.left,false);
  546. in_pred_x,
  547. in_succ_x:
  548. begin
  549. p^.resulttype:=p^.left^.resulttype;
  550. if is_64bitint(p^.resulttype) then
  551. begin
  552. if (p^.registers32<2) then
  553. p^.registers32:=2
  554. end
  555. else
  556. begin
  557. if (p^.registers32<1) then
  558. p^.registers32:=1;
  559. end;
  560. p^.location.loc:=LOC_REGISTER;
  561. set_varstate(p^.left,true);
  562. if not is_ordinal(p^.resulttype) then
  563. CGMessage(type_e_ordinal_expr_expected)
  564. else
  565. begin
  566. if (p^.resulttype^.deftype=enumdef) and
  567. (penumdef(p^.resulttype)^.has_jumps) then
  568. CGMessage(type_e_succ_and_pred_enums_with_assign_not_possible)
  569. else
  570. if p^.left^.treetype=ordconstn then
  571. begin
  572. if p^.inlinenumber=in_succ_x then
  573. hp:=genordinalconstnode(p^.left^.value+1,p^.left^.resulttype)
  574. else
  575. hp:=genordinalconstnode(p^.left^.value-1,p^.left^.resulttype);
  576. disposetree(p);
  577. firstpass(hp);
  578. p:=hp;
  579. end;
  580. end;
  581. end;
  582. in_inc_x,
  583. in_dec_x:
  584. begin
  585. p^.resulttype:=voiddef;
  586. if assigned(p^.left) then
  587. begin
  588. firstcallparan(p^.left,nil,true);
  589. set_varstate(p^.left,true);
  590. if codegenerror then
  591. exit;
  592. { first param must be var }
  593. valid_for_assign(p^.left^.left,false);
  594. { check type }
  595. if (p^.left^.resulttype^.deftype in [enumdef,pointerdef]) or
  596. is_ordinal(p^.left^.resulttype) then
  597. begin
  598. { two paras ? }
  599. if assigned(p^.left^.right) then
  600. begin
  601. { insert a type conversion }
  602. { the second param is always longint }
  603. p^.left^.right^.left:=gentypeconvnode(p^.left^.right^.left,s32bitdef);
  604. { check the type conversion }
  605. firstpass(p^.left^.right^.left);
  606. { need we an additional register ? }
  607. if not(is_constintnode(p^.left^.right^.left)) and
  608. (p^.left^.right^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) and
  609. (p^.left^.right^.left^.registers32<=1) then
  610. inc(p^.registers32);
  611. { do we need an additional register to restore the first parameter? }
  612. if p^.left^.right^.left^.registers32>=p^.registers32 then
  613. inc(p^.registers32);
  614. if assigned(p^.left^.right^.right) then
  615. CGMessage(cg_e_illegal_expression);
  616. end;
  617. end
  618. else
  619. CGMessage(type_e_ordinal_expr_expected);
  620. end
  621. else
  622. CGMessage(type_e_mismatch);
  623. end;
  624. in_read_x,
  625. in_readln_x,
  626. in_write_x,
  627. in_writeln_x :
  628. begin
  629. { needs a call }
  630. procinfo^.flags:=procinfo^.flags or pi_do_call;
  631. p^.resulttype:=voiddef;
  632. { true, if readln needs an extra register }
  633. extra_register:=false;
  634. { we must know if it is a typed file or not }
  635. { but we must first do the firstpass for it }
  636. file_is_typed:=false;
  637. if assigned(p^.left) then
  638. begin
  639. dowrite:=(p^.inlinenumber in [in_write_x,in_writeln_x]);
  640. firstcallparan(p^.left,nil,true);
  641. set_varstate(p^.left,dowrite);
  642. { now we can check }
  643. hp:=p^.left;
  644. while assigned(hp^.right) do
  645. hp:=hp^.right;
  646. { if resulttype is not assigned, then automatically }
  647. { file is not typed. }
  648. if assigned(hp) and assigned(hp^.resulttype) then
  649. Begin
  650. if (hp^.resulttype^.deftype=filedef) then
  651. if (pfiledef(hp^.resulttype)^.filetyp=ft_untyped) then
  652. begin
  653. if (p^.inlinenumber in [in_readln_x,in_writeln_x]) then
  654. CGMessage(type_e_no_readln_writeln_for_typed_file)
  655. else
  656. CGMessage(type_e_no_read_write_for_untyped_file);
  657. end
  658. else if (pfiledef(hp^.resulttype)^.filetyp=ft_typed) then
  659. begin
  660. file_is_typed:=true;
  661. { test the type }
  662. if (p^.inlinenumber in [in_readln_x,in_writeln_x]) then
  663. CGMessage(type_e_no_readln_writeln_for_typed_file);
  664. hpp:=p^.left;
  665. while (hpp<>hp) do
  666. begin
  667. if (hpp^.left^.treetype=typen) then
  668. CGMessage(type_e_cant_read_write_type);
  669. if not is_equal(hpp^.resulttype,pfiledef(hp^.resulttype)^.typedfiletype.def) then
  670. CGMessage(type_e_mismatch);
  671. { generate the high() value for the shortstring }
  672. if ((not dowrite) and is_shortstring(hpp^.left^.resulttype)) or
  673. (is_chararray(hpp^.left^.resulttype)) then
  674. gen_high_tree(hpp,true);
  675. { read(ln) is call by reference (JM) }
  676. if not dowrite then
  677. make_not_regable(hpp^.left);
  678. hpp:=hpp^.right;
  679. end;
  680. end;
  681. end; { endif assigned(hp) }
  682. { insert type conversions for write(ln) }
  683. if (not file_is_typed) then
  684. begin
  685. hp:=p^.left;
  686. while assigned(hp) do
  687. begin
  688. incrementregisterpushed($ff);
  689. if (hp^.left^.treetype=typen) then
  690. CGMessage(type_e_cant_read_write_type);
  691. if assigned(hp^.left^.resulttype) then
  692. begin
  693. isreal:=false;
  694. { support writeln(procvar) }
  695. if (hp^.left^.resulttype^.deftype=procvardef) then
  696. begin
  697. p1:=gencallnode(nil,nil);
  698. p1^.right:=hp^.left;
  699. p1^.resulttype:=pprocvardef(hp^.left^.resulttype)^.rettype.def;
  700. firstpass(p1);
  701. hp^.left:=p1;
  702. end;
  703. case hp^.left^.resulttype^.deftype of
  704. filedef :
  705. begin
  706. { only allowed as first parameter }
  707. if assigned(hp^.right) then
  708. CGMessage(type_e_cant_read_write_type);
  709. end;
  710. stringdef :
  711. begin
  712. { generate the high() value for the shortstring }
  713. if (not dowrite) and
  714. is_shortstring(hp^.left^.resulttype) then
  715. gen_high_tree(hp,true);
  716. end;
  717. pointerdef :
  718. begin
  719. if not is_pchar(hp^.left^.resulttype) then
  720. CGMessage(type_e_cant_read_write_type);
  721. end;
  722. floatdef :
  723. begin
  724. isreal:=true;
  725. end;
  726. orddef :
  727. begin
  728. case porddef(hp^.left^.resulttype)^.typ of
  729. uchar,
  730. u32bit,s32bit,
  731. u64bit,s64bit:
  732. ;
  733. u8bit,s8bit,
  734. u16bit,s16bit :
  735. if dowrite then
  736. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  737. bool8bit,
  738. bool16bit,
  739. bool32bit :
  740. if dowrite then
  741. hp^.left:=gentypeconvnode(hp^.left,booldef)
  742. else
  743. CGMessage(type_e_cant_read_write_type);
  744. else
  745. CGMessage(type_e_cant_read_write_type);
  746. end;
  747. if not(dowrite) and
  748. not(is_64bitint(hp^.left^.resulttype)) then
  749. extra_register:=true;
  750. end;
  751. arraydef :
  752. begin
  753. if is_chararray(hp^.left^.resulttype) then
  754. gen_high_tree(hp,true)
  755. else
  756. CGMessage(type_e_cant_read_write_type);
  757. end;
  758. else
  759. CGMessage(type_e_cant_read_write_type);
  760. end;
  761. { some format options ? }
  762. if hp^.is_colon_para then
  763. begin
  764. if hp^.right^.is_colon_para then
  765. begin
  766. frac_para:=hp;
  767. length_para:=hp^.right;
  768. hp:=hp^.right;
  769. hpp:=hp^.right;
  770. end
  771. else
  772. begin
  773. length_para:=hp;
  774. frac_para:=nil;
  775. hpp:=hp^.right;
  776. end;
  777. { can be nil if you use "write(e:0:6)" while e is undeclared (JM) }
  778. if assigned(hpp^.left^.resulttype) then
  779. isreal:=(hpp^.left^.resulttype^.deftype=floatdef)
  780. else exit;
  781. if (not is_integer(length_para^.left^.resulttype)) then
  782. CGMessage1(type_e_integer_expr_expected,length_para^.left^.resulttype^.typename)
  783. else
  784. length_para^.left:=gentypeconvnode(length_para^.left,s32bitdef);
  785. if assigned(frac_para) then
  786. begin
  787. if isreal then
  788. begin
  789. if (not is_integer(frac_para^.left^.resulttype)) then
  790. CGMessage1(type_e_integer_expr_expected,frac_para^.left^.resulttype^.typename)
  791. else
  792. frac_para^.left:=gentypeconvnode(frac_para^.left,s32bitdef);
  793. end
  794. else
  795. CGMessage(parser_e_illegal_colon_qualifier);
  796. end;
  797. { do the checking for the colon'd arg }
  798. hp:=length_para;
  799. end;
  800. end;
  801. hp:=hp^.right;
  802. end;
  803. end;
  804. { pass all parameters again for the typeconversions }
  805. if codegenerror then
  806. exit;
  807. firstcallparan(p^.left,nil,true);
  808. set_varstate(p^.left,true);
  809. { calc registers }
  810. left_right_max(p);
  811. if extra_register then
  812. inc(p^.registers32);
  813. end;
  814. end;
  815. in_settextbuf_file_x :
  816. begin
  817. { warning here p^.left is the callparannode
  818. not the argument directly }
  819. { p^.left^.left is text var }
  820. { p^.left^.right^.left is the buffer var }
  821. { firstcallparan(p^.left,nil);
  822. already done in firstcalln }
  823. { now we know the type of buffer }
  824. getsymonlyin(systemunit,'SETTEXTBUF');
  825. hp:=gencallnode(pprocsym(srsym),systemunit);
  826. hp^.left:=gencallparanode(
  827. genordinalconstnode(p^.left^.left^.resulttype^.size,s32bitdef),p^.left);
  828. putnode(p);
  829. p:=hp;
  830. firstpass(p);
  831. end;
  832. { the firstpass of the arg has been done in firstcalln ? }
  833. in_reset_typedfile,
  834. in_rewrite_typedfile :
  835. begin
  836. procinfo^.flags:=procinfo^.flags or pi_do_call;
  837. firstpass(p^.left);
  838. set_varstate(p^.left,true);
  839. p^.resulttype:=voiddef;
  840. end;
  841. in_str_x_string :
  842. begin
  843. procinfo^.flags:=procinfo^.flags or pi_do_call;
  844. p^.resulttype:=voiddef;
  845. { check the amount of parameters }
  846. if not(assigned(p^.left)) or
  847. not(assigned(p^.left^.right)) then
  848. begin
  849. CGMessage(parser_e_wrong_parameter_size);
  850. exit;
  851. end;
  852. { first pass just the string for first local use }
  853. hp:=p^.left^.right;
  854. p^.left^.right:=nil;
  855. firstcallparan(p^.left,nil,true);
  856. set_varstate(p^.left,false);
  857. { remove warning when result is passed }
  858. set_funcret_is_valid(p^.left^.left);
  859. p^.left^.right:=hp;
  860. firstcallparan(p^.left^.right,nil,true);
  861. set_varstate(p^.left^.right,true);
  862. hp:=p^.left;
  863. { valid string ? }
  864. if not assigned(hp) or
  865. (hp^.left^.resulttype^.deftype<>stringdef) or
  866. (hp^.right=nil) then
  867. CGMessage(cg_e_illegal_expression);
  868. { we need a var parameter }
  869. valid_for_assign(hp^.left,false);
  870. { generate the high() value for the shortstring }
  871. if is_shortstring(hp^.left^.resulttype) then
  872. gen_high_tree(hp,true);
  873. { !!!! check length of string }
  874. while assigned(hp^.right) do
  875. hp:=hp^.right;
  876. if not assigned(hp^.resulttype) then
  877. exit;
  878. { check and convert the first param }
  879. if (hp^.is_colon_para) or
  880. not assigned(hp^.resulttype) then
  881. CGMessage(cg_e_illegal_expression);
  882. isreal:=false;
  883. case hp^.resulttype^.deftype of
  884. orddef :
  885. begin
  886. case porddef(hp^.left^.resulttype)^.typ of
  887. u32bit,s32bit,
  888. s64bit,u64bit:
  889. ;
  890. u8bit,s8bit,
  891. u16bit,s16bit:
  892. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  893. else
  894. CGMessage(type_e_integer_or_real_expr_expected);
  895. end;
  896. end;
  897. floatdef :
  898. begin
  899. isreal:=true;
  900. end;
  901. else
  902. CGMessage(type_e_integer_or_real_expr_expected);
  903. end;
  904. { some format options ? }
  905. hpp:=p^.left^.right;
  906. if assigned(hpp) and hpp^.is_colon_para then
  907. begin
  908. firstpass(hpp^.left);
  909. set_varstate(hpp^.left,true);
  910. if (not is_integer(hpp^.left^.resulttype)) then
  911. CGMessage1(type_e_integer_expr_expected,hpp^.left^.resulttype^.typename)
  912. else
  913. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  914. hpp:=hpp^.right;
  915. if assigned(hpp) and hpp^.is_colon_para then
  916. begin
  917. if isreal then
  918. begin
  919. if (not is_integer(hpp^.left^.resulttype)) then
  920. CGMessage1(type_e_integer_expr_expected,hpp^.left^.resulttype^.typename)
  921. else
  922. begin
  923. firstpass(hpp^.left);
  924. set_varstate(hpp^.left,true);
  925. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  926. end;
  927. end
  928. else
  929. CGMessage(parser_e_illegal_colon_qualifier);
  930. end;
  931. end;
  932. { pass all parameters again for the typeconversions }
  933. if codegenerror then
  934. exit;
  935. firstcallparan(p^.left,nil,true);
  936. { calc registers }
  937. left_right_max(p);
  938. end;
  939. in_val_x :
  940. begin
  941. procinfo^.flags:=procinfo^.flags or pi_do_call;
  942. p^.resulttype:=voiddef;
  943. { check the amount of parameters }
  944. if not(assigned(p^.left)) or
  945. not(assigned(p^.left^.right)) then
  946. begin
  947. CGMessage(parser_e_wrong_parameter_size);
  948. exit;
  949. end;
  950. If Assigned(p^.left^.right^.right) Then
  951. {there is a "code" parameter}
  952. Begin
  953. { first pass just the code parameter for first local use}
  954. hp := p^.left^.right;
  955. p^.left^.right := nil;
  956. make_not_regable(p^.left^.left);
  957. firstcallparan(p^.left, nil,true);
  958. set_varstate(p^.left,false);
  959. if codegenerror then exit;
  960. p^.left^.right := hp;
  961. {code has to be a var parameter}
  962. if valid_for_assign(p^.left^.left,false) then
  963. begin
  964. if (p^.left^.left^.resulttype^.deftype <> orddef) or
  965. not(porddef(p^.left^.left^.resulttype)^.typ in
  966. [u16bit,s16bit,u32bit,s32bit]) then
  967. CGMessage(type_e_mismatch);
  968. end;
  969. hpp := p^.left^.right
  970. End
  971. Else hpp := p^.left;
  972. {now hpp = the destination value tree}
  973. { first pass just the destination parameter for first local use}
  974. hp:=hpp^.right;
  975. hpp^.right:=nil;
  976. {hpp = destination}
  977. make_not_regable(hpp^.left);
  978. firstcallparan(hpp,nil,true);
  979. set_varstate(hpp,false);
  980. if codegenerror then
  981. exit;
  982. { remove warning when result is passed }
  983. set_funcret_is_valid(hpp^.left);
  984. hpp^.right := hp;
  985. if valid_for_assign(hpp^.left,false) then
  986. begin
  987. If Not((hpp^.left^.resulttype^.deftype = floatdef) or
  988. ((hpp^.left^.resulttype^.deftype = orddef) And
  989. (POrdDef(hpp^.left^.resulttype)^.typ in
  990. [u32bit,s32bit,
  991. u8bit,s8bit,u16bit,s16bit,s64bit,u64bit]))) Then
  992. CGMessage(type_e_mismatch);
  993. end;
  994. {hp = source (String)}
  995. { count_ref := false; WHY ?? }
  996. firstcallparan(hp,nil,true);
  997. set_varstate(hp,true);
  998. if codegenerror then
  999. exit;
  1000. { if not a stringdef then insert a type conv which
  1001. does the other type checking }
  1002. If (hp^.left^.resulttype^.deftype<>stringdef) then
  1003. begin
  1004. hp^.left:=gentypeconvnode(hp^.left,cshortstringdef);
  1005. firstpass(hp);
  1006. end;
  1007. { calc registers }
  1008. left_right_max(p);
  1009. { val doesn't calculate the registers really }
  1010. { correct, we need one register extra (FK) }
  1011. if is_64bitint(hpp^.left^.resulttype) then
  1012. inc(p^.registers32,2)
  1013. else
  1014. inc(p^.registers32,1);
  1015. end;
  1016. in_include_x_y,
  1017. in_exclude_x_y:
  1018. begin
  1019. p^.resulttype:=voiddef;
  1020. if assigned(p^.left) then
  1021. begin
  1022. firstcallparan(p^.left,nil,true);
  1023. set_varstate(p^.left,true);
  1024. p^.registers32:=p^.left^.registers32;
  1025. p^.registersfpu:=p^.left^.registersfpu;
  1026. {$ifdef SUPPORT_MMX}
  1027. p^.registersmmx:=p^.left^.registersmmx;
  1028. {$endif SUPPORT_MMX}
  1029. { remove warning when result is passed }
  1030. set_funcret_is_valid(p^.left^.left);
  1031. { first param must be var }
  1032. valid_for_assign(p^.left^.left,false);
  1033. { check type }
  1034. if assigned(p^.left^.resulttype) and
  1035. (p^.left^.resulttype^.deftype=setdef) then
  1036. begin
  1037. { two paras ? }
  1038. if assigned(p^.left^.right) then
  1039. begin
  1040. { insert a type conversion }
  1041. { to the type of the set elements }
  1042. p^.left^.right^.left:=gentypeconvnode(
  1043. p^.left^.right^.left,
  1044. psetdef(p^.left^.resulttype)^.elementtype.def);
  1045. { check the type conversion }
  1046. firstpass(p^.left^.right^.left);
  1047. { only three parameters are allowed }
  1048. if assigned(p^.left^.right^.right) then
  1049. CGMessage(cg_e_illegal_expression);
  1050. end;
  1051. end
  1052. else
  1053. CGMessage(type_e_mismatch);
  1054. end
  1055. else
  1056. CGMessage(type_e_mismatch);
  1057. end;
  1058. in_low_x,
  1059. in_high_x:
  1060. begin
  1061. set_varstate(p^.left,false);
  1062. { this fixes tests\webtbs\tbug879.pp (FK)
  1063. if p^.left^.treetype in [typen,loadn,subscriptn] then
  1064. begin
  1065. }
  1066. case p^.left^.resulttype^.deftype of
  1067. orddef,enumdef:
  1068. begin
  1069. do_lowhigh(p^.left^.resulttype);
  1070. firstpass(p);
  1071. end;
  1072. setdef:
  1073. begin
  1074. do_lowhigh(Psetdef(p^.left^.resulttype)^.elementtype.def);
  1075. firstpass(p);
  1076. end;
  1077. arraydef:
  1078. begin
  1079. if p^.inlinenumber=in_low_x then
  1080. begin
  1081. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.lowrange,
  1082. Parraydef(p^.left^.resulttype)^.rangetype.def);
  1083. disposetree(p);
  1084. p:=hp;
  1085. firstpass(p);
  1086. end
  1087. else
  1088. begin
  1089. if is_open_array(p^.left^.resulttype) or
  1090. is_array_of_const(p^.left^.resulttype) then
  1091. begin
  1092. getsymonlyin(p^.left^.symtable,'high'+pvarsym(p^.left^.symtableentry)^.name);
  1093. hp:=genloadnode(pvarsym(srsym),p^.left^.symtable);
  1094. disposetree(p);
  1095. p:=hp;
  1096. firstpass(p);
  1097. end
  1098. else
  1099. begin
  1100. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.highrange,
  1101. Parraydef(p^.left^.resulttype)^.rangetype.def);
  1102. disposetree(p);
  1103. p:=hp;
  1104. firstpass(p);
  1105. end;
  1106. end;
  1107. end;
  1108. stringdef:
  1109. begin
  1110. if p^.inlinenumber=in_low_x then
  1111. begin
  1112. hp:=genordinalconstnode(0,u8bitdef);
  1113. disposetree(p);
  1114. p:=hp;
  1115. firstpass(p);
  1116. end
  1117. else
  1118. begin
  1119. if is_open_string(p^.left^.resulttype) then
  1120. begin
  1121. getsymonlyin(p^.left^.symtable,'high'+pvarsym(p^.left^.symtableentry)^.name);
  1122. hp:=genloadnode(pvarsym(srsym),p^.left^.symtable);
  1123. disposetree(p);
  1124. p:=hp;
  1125. firstpass(p);
  1126. end
  1127. else
  1128. begin
  1129. hp:=genordinalconstnode(Pstringdef(p^.left^.resulttype)^.len,u8bitdef);
  1130. disposetree(p);
  1131. p:=hp;
  1132. firstpass(p);
  1133. end;
  1134. end;
  1135. end;
  1136. else
  1137. CGMessage(type_e_mismatch);
  1138. end;
  1139. {
  1140. end
  1141. else
  1142. CGMessage(type_e_varid_or_typeid_expected);
  1143. }
  1144. end;
  1145. in_cos_extended:
  1146. begin
  1147. if p^.left^.treetype in [ordconstn,realconstn] then
  1148. setconstrealvalue(cos(getconstrealvalue))
  1149. else
  1150. handleextendedfunction;
  1151. end;
  1152. in_sin_extended:
  1153. begin
  1154. if p^.left^.treetype in [ordconstn,realconstn] then
  1155. setconstrealvalue(sin(getconstrealvalue))
  1156. else
  1157. handleextendedfunction;
  1158. end;
  1159. in_arctan_extended:
  1160. begin
  1161. if p^.left^.treetype in [ordconstn,realconstn] then
  1162. setconstrealvalue(arctan(getconstrealvalue))
  1163. else
  1164. handleextendedfunction;
  1165. end;
  1166. in_pi:
  1167. if block_type=bt_const then
  1168. setconstrealvalue(pi)
  1169. else
  1170. begin
  1171. p^.location.loc:=LOC_FPU;
  1172. p^.resulttype:=s80floatdef;
  1173. end;
  1174. in_abs_extended:
  1175. begin
  1176. if p^.left^.treetype in [ordconstn,realconstn] then
  1177. setconstrealvalue(abs(getconstrealvalue))
  1178. else
  1179. handleextendedfunction;
  1180. end;
  1181. in_sqr_extended:
  1182. begin
  1183. if p^.left^.treetype in [ordconstn,realconstn] then
  1184. setconstrealvalue(sqr(getconstrealvalue))
  1185. else
  1186. handleextendedfunction;
  1187. end;
  1188. in_sqrt_extended:
  1189. begin
  1190. if p^.left^.treetype in [ordconstn,realconstn] then
  1191. begin
  1192. vr:=getconstrealvalue;
  1193. if vr<0.0 then
  1194. begin
  1195. CGMessage(type_e_wrong_math_argument);
  1196. setconstrealvalue(0);
  1197. end
  1198. else
  1199. setconstrealvalue(sqrt(vr));
  1200. end
  1201. else
  1202. handleextendedfunction;
  1203. end;
  1204. in_ln_extended:
  1205. begin
  1206. if p^.left^.treetype in [ordconstn,realconstn] then
  1207. begin
  1208. vr:=getconstrealvalue;
  1209. if vr<=0.0 then
  1210. begin
  1211. CGMessage(type_e_wrong_math_argument);
  1212. setconstrealvalue(0);
  1213. end
  1214. else
  1215. setconstrealvalue(ln(vr));
  1216. end
  1217. else
  1218. handleextendedfunction;
  1219. end;
  1220. {$ifdef SUPPORT_MMX}
  1221. in_mmx_pcmpeqb..in_mmx_pcmpgtw:
  1222. begin
  1223. end;
  1224. {$endif SUPPORT_MMX}
  1225. in_assert_x_y :
  1226. begin
  1227. p^.resulttype:=voiddef;
  1228. if assigned(p^.left) then
  1229. begin
  1230. firstcallparan(p^.left,nil,true);
  1231. set_varstate(p^.left,true);
  1232. p^.registers32:=p^.left^.registers32;
  1233. p^.registersfpu:=p^.left^.registersfpu;
  1234. {$ifdef SUPPORT_MMX}
  1235. p^.registersmmx:=p^.left^.registersmmx;
  1236. {$endif SUPPORT_MMX}
  1237. { check type }
  1238. if is_boolean(p^.left^.resulttype) then
  1239. begin
  1240. { must always be a string }
  1241. p^.left^.right^.left:=gentypeconvnode(p^.left^.right^.left,cshortstringdef);
  1242. firstpass(p^.left^.right^.left);
  1243. end
  1244. else
  1245. CGMessage(type_e_mismatch);
  1246. end
  1247. else
  1248. CGMessage(type_e_mismatch);
  1249. { We've checked the whole statement for correctness, now we
  1250. can remove it if assertions are off }
  1251. if not(cs_do_assertion in aktlocalswitches) then
  1252. begin
  1253. disposetree(p^.left);
  1254. putnode(p);
  1255. { we need a valid node, so insert a nothingn }
  1256. p:=genzeronode(nothingn);
  1257. end;
  1258. end;
  1259. else
  1260. internalerror(8);
  1261. end;
  1262. end;
  1263. { generate an error if no resulttype is set }
  1264. if not assigned(p^.resulttype) then
  1265. p^.resulttype:=generrordef;
  1266. dec(parsing_para_level);
  1267. end;
  1268. {$ifdef fpc}
  1269. {$maxfpuregisters default}
  1270. {$endif fpc}
  1271. end.
  1272. {
  1273. $Log$
  1274. Revision 1.7 2000-09-24 21:19:53 peter
  1275. * delphi compile fixes
  1276. Revision 1.6 2000/08/24 13:12:38 jonas
  1277. * fixed crash when using include/exclude with undeclared variable as
  1278. first parameter (merged from fixes branch)
  1279. Revision 1.5 2000/08/16 13:06:07 florian
  1280. + support of 64 bit integer constants
  1281. Revision 1.4 2000/08/01 14:07:49 jonas
  1282. * fixed crash when passing undeclared identifiers to str() (merged from
  1283. fixes branch)
  1284. Revision 1.3 2000/07/22 11:53:26 sg
  1285. * Added WideChar support to inlined 'ord' function
  1286. Revision 1.2 2000/07/13 11:32:52 michael
  1287. + removed logs
  1288. }