ncon.pas 18 KB

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