ncon.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. {
  2. $Id$
  3. Copyright (c) 2000 by Florian Klaempfl
  4. Type checking and register allocation for constants
  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 ncon;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. globtype,node,aasm,cpuinfo,symconst,symtable;
  23. type
  24. trealconstnode = class(tnode)
  25. value_real : bestreal;
  26. lab_real : pasmlabel;
  27. constructor create(v : bestreal;def : pdef);virtual;
  28. function getcopy : tnode;override;
  29. function pass_1 : tnode;override;
  30. end;
  31. tfixconstnode = class(tnode)
  32. value_fix: longint;
  33. constructor create(v : longint;def : pdef);virtual;
  34. function getcopy : tnode;override;
  35. function pass_1 : tnode;override;
  36. end;
  37. tordconstnode = class(tnode)
  38. value : TConstExprInt;
  39. constructor create(v : tconstexprint;def : pdef);virtual;
  40. function getcopy : tnode;override;
  41. function pass_1 : tnode;override;
  42. end;
  43. tpointerconstnode = class(tnode)
  44. value : TPointerOrd;
  45. constructor create(v : tpointerord;def : pdef);virtual;
  46. function getcopy : tnode;override;
  47. function pass_1 : tnode;override;
  48. end;
  49. tstringconstnode = class(tnode)
  50. value_str : pchar;
  51. len : longint;
  52. lab_str : pasmlabel;
  53. stringtype : tstringtype;
  54. constructor createstr(const s : string;st:tstringtype);virtual;
  55. constructor createpchar(s : pchar;l : longint);virtual;
  56. destructor destroy;override;
  57. function getcopy : tnode;override;
  58. function pass_1 : tnode;override;
  59. function getpcharcopy : pchar;
  60. end;
  61. tsetconstnode = class(tunarynode)
  62. value_set : pconstset;
  63. lab_set : pasmlabel;
  64. constructor create(s : pconstset;settype : psetdef);virtual;
  65. destructor destroy;override;
  66. function getcopy : tnode;override;
  67. function pass_1 : tnode;override;
  68. end;
  69. tnilnode = class(tnode)
  70. constructor create;virtual;
  71. function pass_1 : tnode;override;
  72. end;
  73. var
  74. crealconstnode : class of trealconstnode;
  75. cfixconstnode : class of tfixconstnode;
  76. cordconstnode : class of tordconstnode;
  77. cpointerconstnode : class of tpointerconstnode;
  78. cstringconstnode : class of tstringconstnode;
  79. csetconstnode : class of tsetconstnode;
  80. cnilnode : class of tnilnode;
  81. function genordinalconstnode(v : TConstExprInt;def : pdef) : tordconstnode;
  82. { same as genordinalconstnode, but the resulttype }
  83. { is determines automatically }
  84. function genintconstnode(v : TConstExprInt) : tordconstnode;
  85. function genpointerconstnode(v : tpointerord;def : pdef) : tpointerconstnode;
  86. function genenumnode(v : penumsym) : tordconstnode;
  87. function genfixconstnode(v : longint;def : pdef) : tfixconstnode;
  88. function genrealconstnode(v : bestreal;def : pdef) : trealconstnode;
  89. { allow pchar or string for defining a pchar node }
  90. function genstringconstnode(const s : string;st:tstringtype) : tstringconstnode;
  91. { length is required for ansistrings }
  92. function genpcharconstnode(s : pchar;length : longint) : tstringconstnode;
  93. function gensetconstnode(s : pconstset;settype : psetdef) : tsetconstnode;
  94. { some helper routines }
  95. function get_ordinal_value(p : tnode) : longint;
  96. function is_constnode(p : tnode) : boolean;
  97. function is_constintnode(p : tnode) : boolean;
  98. function is_constcharnode(p : tnode) : boolean;
  99. function is_constrealnode(p : tnode) : boolean;
  100. function is_constboolnode(p : tnode) : boolean;
  101. function is_constresourcestringnode(p : tnode) : boolean;
  102. function str_length(p : tnode) : longint;
  103. function is_emptyset(p : tnode):boolean;
  104. function genconstsymtree(p : pconstsym) : tnode;
  105. implementation
  106. uses
  107. cutils,cobjects,verbose,globals,systems,
  108. types,hcodegen,pass_1,cpubase,nld;
  109. function genordinalconstnode(v : tconstexprint;def : pdef) : tordconstnode;
  110. begin
  111. genordinalconstnode:=cordconstnode.create(v,def);
  112. end;
  113. function genintconstnode(v : TConstExprInt) : tordconstnode;
  114. var
  115. i : TConstExprInt;
  116. begin
  117. { we need to bootstrap this code, so it's a little bit messy }
  118. i:=2147483647;
  119. if (v<=i) and (v>=-i-1) then
  120. genintconstnode:=genordinalconstnode(v,s32bitdef)
  121. else
  122. genintconstnode:=genordinalconstnode(v,cs64bitdef);
  123. end;
  124. function genpointerconstnode(v : tpointerord;def : pdef) : tpointerconstnode;
  125. begin
  126. genpointerconstnode:=cpointerconstnode.create(v,def);
  127. end;
  128. function genenumnode(v : penumsym) : tordconstnode;
  129. begin
  130. genenumnode:=cordconstnode.create(v^.value,v^.definition);
  131. end;
  132. function gensetconstnode(s : pconstset;settype : psetdef) : tsetconstnode;
  133. begin
  134. gensetconstnode:=csetconstnode.create(s,settype);
  135. end;
  136. function genrealconstnode(v : bestreal;def : pdef) : trealconstnode;
  137. begin
  138. genrealconstnode:=crealconstnode.create(v,def);
  139. end;
  140. function genfixconstnode(v : longint;def : pdef) : tfixconstnode;
  141. begin
  142. genfixconstnode:=cfixconstnode.create(v,def);
  143. end;
  144. function genstringconstnode(const s : string;st:tstringtype) : tstringconstnode;
  145. begin
  146. genstringconstnode:=cstringconstnode.createstr(s,st);
  147. end;
  148. function genpcharconstnode(s : pchar;length : longint) : tstringconstnode;
  149. begin
  150. genpcharconstnode:=cstringconstnode.createpchar(s,length);
  151. end;
  152. function get_ordinal_value(p : tnode) : longint;
  153. begin
  154. if p.nodetype=ordconstn then
  155. get_ordinal_value:=tordconstnode(p).value
  156. else
  157. begin
  158. Message(type_e_ordinal_expr_expected);
  159. get_ordinal_value:=0;
  160. end;
  161. end;
  162. function is_constnode(p : tnode) : boolean;
  163. begin
  164. is_constnode:=(p.nodetype in [ordconstn,realconstn,stringconstn,fixconstn,setconstn]);
  165. end;
  166. function is_constintnode(p : tnode) : boolean;
  167. begin
  168. is_constintnode:=(p.nodetype=ordconstn) and is_integer(p.resulttype);
  169. end;
  170. function is_constcharnode(p : tnode) : boolean;
  171. begin
  172. is_constcharnode:=(p.nodetype=ordconstn) and is_char(p.resulttype);
  173. end;
  174. function is_constrealnode(p : tnode) : boolean;
  175. begin
  176. is_constrealnode:=(p.nodetype=realconstn);
  177. end;
  178. function is_constboolnode(p : tnode) : boolean;
  179. begin
  180. is_constboolnode:=(p.nodetype=ordconstn) and is_boolean(p.resulttype);
  181. end;
  182. function is_constresourcestringnode(p : tnode) : boolean;
  183. begin
  184. is_constresourcestringnode:=(p.nodetype=loadn) and
  185. (tloadnode(p).symtableentry^.typ=constsym) and
  186. (pconstsym(tloadnode(p).symtableentry)^.consttyp=constresourcestring);
  187. end;
  188. function str_length(p : tnode) : longint;
  189. begin
  190. str_length:=tstringconstnode(p).len;
  191. end;
  192. function is_emptyset(p : tnode):boolean;
  193. var
  194. i : longint;
  195. begin
  196. i:=0;
  197. if p.nodetype=setconstn then
  198. begin
  199. while (i<32) and (tsetconstnode(p).value_set^[i]=0) do
  200. inc(i);
  201. end;
  202. is_emptyset:=(i=32);
  203. end;
  204. function genconstsymtree(p : pconstsym) : tnode;
  205. var
  206. p1 : tnode;
  207. len : longint;
  208. pc : pchar;
  209. begin
  210. p1:=nil;
  211. case p^.consttyp of
  212. constint :
  213. p1:=genordinalconstnode(p^.value,s32bitdef);
  214. conststring :
  215. begin
  216. len:=p^.len;
  217. if not(cs_ansistrings in aktlocalswitches) and (len>255) then
  218. len:=255;
  219. getmem(pc,len+1);
  220. move(pchar(tpointerord(p^.value))^,pc^,len);
  221. pc[len]:=#0;
  222. p1:=genpcharconstnode(pc,len);
  223. end;
  224. constchar :
  225. p1:=genordinalconstnode(p^.value,cchardef);
  226. constreal :
  227. p1:=genrealconstnode(pbestreal(tpointerord(p^.value))^,bestrealdef^);
  228. constbool :
  229. p1:=genordinalconstnode(p^.value,booldef);
  230. constset :
  231. p1:=gensetconstnode(pconstset(tpointerord(p^.value)),psetdef(p^.consttype.def));
  232. constord :
  233. p1:=genordinalconstnode(p^.value,p^.consttype.def);
  234. constpointer :
  235. p1:=genpointerconstnode(p^.value,p^.consttype.def);
  236. constnil :
  237. p1:=cnilnode.create;
  238. constresourcestring:
  239. begin
  240. p1:=genloadnode(pvarsym(p),pvarsym(p)^.owner);
  241. p1.resulttype:=cansistringdef;
  242. end;
  243. end;
  244. genconstsymtree:=p1;
  245. end;
  246. {*****************************************************************************
  247. TREALCONSTNODE
  248. *****************************************************************************}
  249. constructor trealconstnode.create(v : bestreal;def : pdef);
  250. begin
  251. inherited create(realconstn);
  252. resulttype:=def;
  253. value_real:=v;
  254. lab_real:=nil;
  255. end;
  256. function trealconstnode.getcopy : tnode;
  257. var
  258. n : trealconstnode;
  259. begin
  260. n:=trealconstnode(inherited getcopy);
  261. n.value_real:=value_real;
  262. n.lab_real:=lab_real;
  263. getcopy:=n;
  264. end;
  265. function trealconstnode.pass_1 : tnode;
  266. begin
  267. pass_1:=nil;
  268. if (value_real=1.0) or (value_real=0.0) then
  269. begin
  270. location.loc:=LOC_FPU;
  271. registersfpu:=1;
  272. end
  273. else
  274. location.loc:=LOC_MEM;
  275. end;
  276. {*****************************************************************************
  277. TFIXCONSTNODE
  278. *****************************************************************************}
  279. constructor tfixconstnode.create(v : longint;def : pdef);
  280. begin
  281. inherited create(fixconstn);
  282. resulttype:=def;
  283. value_fix:=v;
  284. end;
  285. function tfixconstnode.getcopy : tnode;
  286. var
  287. n : tfixconstnode;
  288. begin
  289. n:=tfixconstnode(inherited getcopy);
  290. n.value_fix:=value_fix;
  291. getcopy:=n;
  292. end;
  293. function tfixconstnode.pass_1 : tnode;
  294. begin
  295. pass_1:=nil;
  296. location.loc:=LOC_MEM;
  297. end;
  298. {*****************************************************************************
  299. TORDCONSTNODE
  300. *****************************************************************************}
  301. constructor tordconstnode.create(v : tconstexprint;def : pdef);
  302. begin
  303. inherited create(ordconstn);
  304. value:=v;
  305. resulttype:=def;
  306. {$ifdef NEWST}
  307. if typeof(resulttype^)=typeof(Torddef) then
  308. testrange(resulttype,value);
  309. {$else NEWST}
  310. if resulttype^.deftype=orddef then
  311. testrange(resulttype,value);
  312. {$endif ELSE}
  313. end;
  314. function tordconstnode.getcopy : tnode;
  315. var
  316. n : tordconstnode;
  317. begin
  318. n:=tordconstnode(inherited getcopy);
  319. n.value:=value;
  320. getcopy:=n;
  321. end;
  322. function tordconstnode.pass_1 : tnode;
  323. begin
  324. pass_1:=nil;
  325. location.loc:=LOC_MEM;
  326. end;
  327. {*****************************************************************************
  328. TPOINTERCONSTNODE
  329. *****************************************************************************}
  330. constructor tpointerconstnode.create(v : tpointerord;def : pdef);
  331. begin
  332. inherited create(pointerconstn);
  333. value:=v;
  334. resulttype:=def;
  335. end;
  336. function tpointerconstnode.getcopy : tnode;
  337. var
  338. n : tpointerconstnode;
  339. begin
  340. n:=tpointerconstnode(inherited getcopy);
  341. n.value:=value;
  342. getcopy:=n;
  343. end;
  344. function tpointerconstnode.pass_1 : tnode;
  345. begin
  346. pass_1:=nil;
  347. location.loc:=LOC_MEM;
  348. end;
  349. {*****************************************************************************
  350. TSTRINGCONSTNODE
  351. *****************************************************************************}
  352. constructor tstringconstnode.createstr(const s : string;st:tstringtype);
  353. var
  354. l : longint;
  355. begin
  356. inherited create(stringconstn);
  357. l:=length(s);
  358. len:=l;
  359. { stringdup write even past a #0 }
  360. getmem(value_str,l+1);
  361. move(s[1],value_str^,l);
  362. value_str[l]:=#0;
  363. lab_str:=nil;
  364. if st=st_default then
  365. begin
  366. if cs_ansistrings in aktlocalswitches then
  367. stringtype:=st_ansistring
  368. else
  369. stringtype:=st_shortstring;
  370. end
  371. else
  372. stringtype:=st;
  373. case stringtype of
  374. st_shortstring :
  375. resulttype:=cshortstringdef;
  376. st_ansistring :
  377. resulttype:=cansistringdef;
  378. else
  379. internalerror(44990099);
  380. end;
  381. end;
  382. constructor tstringconstnode.createpchar(s : pchar;l : longint);
  383. begin
  384. inherited create(stringconstn);
  385. len:=l;
  386. if (cs_ansistrings in aktlocalswitches) or
  387. (len>255) then
  388. begin
  389. stringtype:=st_ansistring;
  390. resulttype:=cansistringdef;
  391. end
  392. else
  393. begin
  394. stringtype:=st_shortstring;
  395. resulttype:=cshortstringdef;
  396. end;
  397. value_str:=s;
  398. lab_str:=nil;
  399. end;
  400. destructor tstringconstnode.destroy;
  401. begin
  402. ansistringdispose(value_str,len);
  403. inherited destroy;
  404. end;
  405. function tstringconstnode.getcopy : tnode;
  406. var
  407. n : tstringconstnode;
  408. begin
  409. n:=tstringconstnode(inherited getcopy);
  410. n.stringtype:=stringtype;
  411. n.len:=len;
  412. n.value_str:=getpcharcopy;
  413. n.lab_str:=lab_str;
  414. getcopy:=n;
  415. end;
  416. function tstringconstnode.pass_1 : tnode;
  417. begin
  418. pass_1:=nil;
  419. case stringtype of
  420. st_shortstring :
  421. resulttype:=cshortstringdef;
  422. st_ansistring :
  423. resulttype:=cansistringdef;
  424. st_widestring :
  425. resulttype:=cwidestringdef;
  426. st_longstring :
  427. resulttype:=clongstringdef;
  428. end;
  429. location.loc:=LOC_MEM;
  430. end;
  431. function tstringconstnode.getpcharcopy : pchar;
  432. var
  433. pc : pchar;
  434. begin
  435. pc:=nil;
  436. getmem(pc,len+1);
  437. if pc=nil then
  438. Message(general_f_no_memory_left);
  439. move(value_str^,pc^,len+1);
  440. getpcharcopy:=pc;
  441. end;
  442. {*****************************************************************************
  443. TSETCONSTNODE
  444. *****************************************************************************}
  445. constructor tsetconstnode.create(s : pconstset;settype : psetdef);
  446. begin
  447. inherited create(setconstn,nil);
  448. resulttype:=settype;
  449. if assigned(s) then
  450. begin
  451. new(value_set);
  452. value_set^:=s^;
  453. end
  454. else
  455. value_set:=nil;
  456. end;
  457. destructor tsetconstnode.destroy;
  458. begin
  459. if assigned(value_set) then
  460. dispose(value_set);
  461. inherited destroy;
  462. end;
  463. function tsetconstnode.getcopy : tnode;
  464. var
  465. n : tsetconstnode;
  466. begin
  467. n:=tsetconstnode(inherited getcopy);
  468. if assigned(value_set) then
  469. begin
  470. new(n.value_set);
  471. n.value_set^:=value_set^
  472. end
  473. else
  474. n.value_set:=nil;
  475. n.lab_set:=lab_set;
  476. getcopy:=n;
  477. end;
  478. function tsetconstnode.pass_1 : tnode;
  479. begin
  480. pass_1:=nil;
  481. location.loc:=LOC_MEM;
  482. end;
  483. {*****************************************************************************
  484. TNILNODE
  485. *****************************************************************************}
  486. constructor tnilnode.create;
  487. begin
  488. inherited create(niln);
  489. end;
  490. function tnilnode.pass_1 : tnode;
  491. begin
  492. pass_1:=nil;
  493. resulttype:=voidpointerdef;
  494. location.loc:=LOC_MEM;
  495. end;
  496. begin
  497. crealconstnode:=trealconstnode;
  498. cfixconstnode:=tfixconstnode;
  499. cordconstnode:=tordconstnode;
  500. cpointerconstnode:=tpointerconstnode;
  501. cstringconstnode:=tstringconstnode;
  502. csetconstnode:=tsetconstnode;
  503. cnilnode:=tnilnode;
  504. end.
  505. {
  506. $Log$
  507. Revision 1.9 2000-10-14 21:52:55 peter
  508. * fixed memory leaks
  509. Revision 1.8 2000/10/14 10:14:50 peter
  510. * moehrendorf oct 2000 rewrite
  511. Revision 1.7 2000/09/28 19:49:52 florian
  512. *** empty log message ***
  513. Revision 1.6 2000/09/27 20:25:44 florian
  514. * more stuff fixed
  515. Revision 1.5 2000/09/27 18:14:31 florian
  516. * fixed a lot of syntax errors in the n*.pas stuff
  517. Revision 1.4 2000/09/26 14:59:34 florian
  518. * more conversion work done
  519. Revision 1.3 2000/09/24 21:15:34 florian
  520. * some errors fix to get more stuff compilable
  521. Revision 1.2 2000/09/24 15:06:19 peter
  522. * use defines.inc
  523. Revision 1.1 2000/09/22 21:44:48 florian
  524. + initial revision
  525. }