ncon.pas 16 KB

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