pexpr.pas 98 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Does parsing of expression for Free Pascal
  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 pexpr;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. symtype,
  23. node,
  24. globals,
  25. cpuinfo;
  26. { reads a whole expression }
  27. function expr : tnode;
  28. { reads an expression without assignements and .. }
  29. function comp_expr(accept_equal : boolean):tnode;
  30. { reads a single factor }
  31. function factor(getaddr : boolean) : tnode;
  32. procedure string_dec(var t: ttype);
  33. function parse_paras(__colon,in_prop_paras : boolean) : tnode;
  34. { the ID token has to be consumed before calling this function }
  35. procedure do_member_read(getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callnflags:tnodeflags);
  36. {$ifdef int64funcresok}
  37. function get_intconst:TConstExprInt;
  38. {$else int64funcresok}
  39. function get_intconst:longint;
  40. {$endif int64funcresok}
  41. function get_stringconst:string;
  42. implementation
  43. uses
  44. {$ifdef delphi}
  45. SysUtils,
  46. {$endif}
  47. { common }
  48. cutils,
  49. { global }
  50. globtype,tokens,verbose,
  51. systems,widestr,
  52. { symtable }
  53. symconst,symbase,symdef,symsym,symtable,defutil,defcmp,
  54. { pass 1 }
  55. pass_1,htypechk,
  56. nutils,nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,
  57. { parser }
  58. scanner,
  59. pbase,pinline,
  60. { codegen }
  61. cgbase
  62. ;
  63. { sub_expr(opmultiply) is need to get -1 ** 4 to be
  64. read as - (1**4) and not (-1)**4 PM }
  65. type
  66. Toperator_precedence=(opcompare,opaddition,opmultiply,oppower);
  67. const
  68. highest_precedence = oppower;
  69. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;forward;
  70. const
  71. { true, if the inherited call is anonymous }
  72. anon_inherited : boolean = false;
  73. procedure string_dec(var t: ttype);
  74. { reads a string type with optional length }
  75. { and returns a pointer to the string }
  76. { definition }
  77. var
  78. p : tnode;
  79. begin
  80. t:=cshortstringtype;
  81. consume(_STRING);
  82. if token=_LECKKLAMMER then
  83. begin
  84. consume(_LECKKLAMMER);
  85. p:=comp_expr(true);
  86. if not is_constintnode(p) then
  87. begin
  88. Message(cg_e_illegal_expression);
  89. { error recovery }
  90. consume(_RECKKLAMMER);
  91. end
  92. else
  93. begin
  94. if (tordconstnode(p).value<=0) then
  95. begin
  96. Message(parser_e_invalid_string_size);
  97. tordconstnode(p).value:=255;
  98. end;
  99. consume(_RECKKLAMMER);
  100. if tordconstnode(p).value>255 then
  101. begin
  102. { longstring is currently unsupported (CEC)! }
  103. { t.setdef(tstringdef.createlong(tordconstnode(p).value))}
  104. Message(parser_e_invalid_string_size);
  105. tordconstnode(p).value:=255;
  106. t.setdef(tstringdef.createshort(tordconstnode(p).value));
  107. end
  108. else
  109. if tordconstnode(p).value<>255 then
  110. t.setdef(tstringdef.createshort(tordconstnode(p).value));
  111. end;
  112. p.free;
  113. end
  114. else
  115. begin
  116. if cs_ansistrings in aktlocalswitches then
  117. t:=cansistringtype
  118. else
  119. t:=cshortstringtype;
  120. end;
  121. end;
  122. function parse_paras(__colon,in_prop_paras : boolean) : tnode;
  123. var
  124. p1,p2 : tnode;
  125. end_of_paras : ttoken;
  126. prev_in_args : boolean;
  127. old_allow_array_constructor : boolean;
  128. begin
  129. if in_prop_paras then
  130. end_of_paras:=_RECKKLAMMER
  131. else
  132. end_of_paras:=_RKLAMMER;
  133. if token=end_of_paras then
  134. begin
  135. parse_paras:=nil;
  136. exit;
  137. end;
  138. { save old values }
  139. prev_in_args:=in_args;
  140. old_allow_array_constructor:=allow_array_constructor;
  141. { set para parsing values }
  142. in_args:=true;
  143. inc(parsing_para_level);
  144. allow_array_constructor:=true;
  145. p2:=nil;
  146. while true do
  147. begin
  148. p1:=comp_expr(true);
  149. p2:=ccallparanode.create(p1,p2);
  150. { it's for the str(l:5,s); }
  151. if __colon and (token=_COLON) then
  152. begin
  153. consume(_COLON);
  154. p1:=comp_expr(true);
  155. p2:=ccallparanode.create(p1,p2);
  156. include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
  157. if token=_COLON then
  158. begin
  159. consume(_COLON);
  160. p1:=comp_expr(true);
  161. p2:=ccallparanode.create(p1,p2);
  162. include(tcallparanode(p2).callparaflags,cpf_is_colon_para);
  163. end
  164. end;
  165. if token=_COMMA then
  166. consume(_COMMA)
  167. else
  168. break;
  169. end;
  170. allow_array_constructor:=old_allow_array_constructor;
  171. dec(parsing_para_level);
  172. in_args:=prev_in_args;
  173. parse_paras:=p2;
  174. end;
  175. procedure check_tp_procvar(var p : tnode);
  176. var
  177. hp,
  178. p1 : tnode;
  179. begin
  180. if (m_tp_procvar in aktmodeswitches) and
  181. (token<>_ASSIGNMENT) and
  182. (not got_addrn) and
  183. (block_type=bt_general) then
  184. begin
  185. { ignore vecn,subscriptn }
  186. hp:=p;
  187. repeat
  188. case hp.nodetype of
  189. vecn :
  190. hp:=tvecnode(hp).left;
  191. subscriptn :
  192. hp:=tsubscriptnode(hp).left;
  193. else
  194. break;
  195. end;
  196. until false;
  197. if (hp.nodetype=loadn) then
  198. begin
  199. { get the resulttype of p }
  200. do_resulttypepass(p);
  201. { convert the procvar load to a call:
  202. - not expecting a procvar
  203. - the procvar does not get arguments, when it
  204. requires arguments the callnode will fail
  205. Note: When arguments were passed there was no loadn }
  206. if (getprocvardef=nil) and
  207. (p.resulttype.def.deftype=procvardef) and
  208. (tprocvardef(p.resulttype.def).minparacount=0) then
  209. begin
  210. p1:=ccallnode.create_procvar(nil,p);
  211. resulttypepass(p1);
  212. p:=p1;
  213. end;
  214. end;
  215. end;
  216. end;
  217. function statement_syssym(l : longint) : tnode;
  218. var
  219. p1,p2,paras : tnode;
  220. err,
  221. prev_in_args : boolean;
  222. begin
  223. prev_in_args:=in_args;
  224. case l of
  225. in_new_x :
  226. begin
  227. if afterassignment or in_args then
  228. statement_syssym:=new_function
  229. else
  230. statement_syssym:=new_dispose_statement(true);
  231. end;
  232. in_dispose_x :
  233. begin
  234. statement_syssym:=new_dispose_statement(false);
  235. end;
  236. in_ord_x :
  237. begin
  238. consume(_LKLAMMER);
  239. in_args:=true;
  240. p1:=comp_expr(true);
  241. consume(_RKLAMMER);
  242. p1:=geninlinenode(in_ord_x,false,p1);
  243. statement_syssym := p1;
  244. end;
  245. in_exit :
  246. begin
  247. if try_to_consume(_LKLAMMER) then
  248. begin
  249. p1:=comp_expr(true);
  250. consume(_RKLAMMER);
  251. if (block_type=bt_except) then
  252. Message(parser_e_exit_with_argument_not__possible);
  253. if (not assigned(current_procinfo) or
  254. is_void(current_procinfo.procdef.rettype.def)) then
  255. Message(parser_e_void_function);
  256. end
  257. else
  258. p1:=nil;
  259. statement_syssym:=cexitnode.create(p1);
  260. end;
  261. in_break :
  262. begin
  263. statement_syssym:=cbreaknode.create;
  264. end;
  265. in_continue :
  266. begin
  267. statement_syssym:=ccontinuenode.create;
  268. end;
  269. in_typeof_x :
  270. begin
  271. consume(_LKLAMMER);
  272. in_args:=true;
  273. p1:=comp_expr(true);
  274. consume(_RKLAMMER);
  275. if p1.nodetype=typen then
  276. ttypenode(p1).allowed:=true;
  277. if (p1.resulttype.def.deftype = objectdef) then
  278. statement_syssym:=geninlinenode(in_typeof_x,false,p1)
  279. else
  280. begin
  281. Message(parser_e_class_id_expected);
  282. p1.destroy;
  283. statement_syssym:=cerrornode.create;
  284. end;
  285. end;
  286. in_sizeof_x :
  287. begin
  288. consume(_LKLAMMER);
  289. in_args:=true;
  290. p1:=comp_expr(true);
  291. consume(_RKLAMMER);
  292. if (p1.nodetype<>typen) and
  293. (
  294. (is_object(p1.resulttype.def) and
  295. (oo_has_constructor in tobjectdef(p1.resulttype.def).objectoptions)) or
  296. is_open_array(p1.resulttype.def) or
  297. is_open_string(p1.resulttype.def)
  298. ) then
  299. statement_syssym:=geninlinenode(in_sizeof_x,false,p1)
  300. else
  301. begin
  302. statement_syssym:=cordconstnode.create(p1.resulttype.def.size,s32bittype,true);
  303. { p1 not needed !}
  304. p1.destroy;
  305. end;
  306. end;
  307. in_typeinfo_x :
  308. begin
  309. consume(_LKLAMMER);
  310. in_args:=true;
  311. p1:=comp_expr(true);
  312. if p1.nodetype=typen then
  313. ttypenode(p1).allowed:=true
  314. else
  315. begin
  316. p1.destroy;
  317. p1:=cerrornode.create;
  318. Message(parser_e_illegal_parameter_list);
  319. end;
  320. consume(_RKLAMMER);
  321. p2:=ccallparanode.create(p1,nil);
  322. p2:=geninlinenode(in_typeinfo_x,false,p2);
  323. statement_syssym:=p2;
  324. end;
  325. in_assigned_x :
  326. begin
  327. err:=false;
  328. consume(_LKLAMMER);
  329. in_args:=true;
  330. p1:=comp_expr(true);
  331. if not codegenerror then
  332. begin
  333. { With tp procvars we allways need to load a
  334. procvar when it is passed }
  335. if (m_tp_procvar in aktmodeswitches) and
  336. (p1.nodetype=calln) then
  337. load_procvar_from_calln(p1);
  338. case p1.resulttype.def.deftype of
  339. pointerdef,
  340. procvardef,
  341. classrefdef : ;
  342. objectdef :
  343. if not is_class_or_interface(p1.resulttype.def) then
  344. begin
  345. Message(parser_e_illegal_parameter_list);
  346. err:=true;
  347. end;
  348. else
  349. begin
  350. Message(parser_e_illegal_parameter_list);
  351. err:=true;
  352. end;
  353. end;
  354. end
  355. else
  356. err:=true;
  357. if not err then
  358. begin
  359. p2:=ccallparanode.create(p1,nil);
  360. p2:=geninlinenode(in_assigned_x,false,p2);
  361. end
  362. else
  363. begin
  364. p1.free;
  365. p2:=cerrornode.create;
  366. end;
  367. consume(_RKLAMMER);
  368. statement_syssym:=p2;
  369. end;
  370. in_addr_x :
  371. begin
  372. consume(_LKLAMMER);
  373. in_args:=true;
  374. p1:=comp_expr(true);
  375. p1:=caddrnode.create(p1);
  376. consume(_RKLAMMER);
  377. statement_syssym:=p1;
  378. end;
  379. in_ofs_x :
  380. begin
  381. consume(_LKLAMMER);
  382. in_args:=true;
  383. p1:=comp_expr(true);
  384. p1:=caddrnode.create(p1);
  385. do_resulttypepass(p1);
  386. { Ofs() returns a cardinal, not a pointer }
  387. p1.resulttype:=u32bittype;
  388. consume(_RKLAMMER);
  389. statement_syssym:=p1;
  390. end;
  391. in_seg_x :
  392. begin
  393. consume(_LKLAMMER);
  394. in_args:=true;
  395. p1:=comp_expr(true);
  396. p1:=geninlinenode(in_seg_x,false,p1);
  397. consume(_RKLAMMER);
  398. statement_syssym:=p1;
  399. end;
  400. in_high_x,
  401. in_low_x :
  402. begin
  403. consume(_LKLAMMER);
  404. in_args:=true;
  405. p1:=comp_expr(true);
  406. p2:=geninlinenode(l,false,p1);
  407. consume(_RKLAMMER);
  408. statement_syssym:=p2;
  409. end;
  410. in_succ_x,
  411. in_pred_x :
  412. begin
  413. consume(_LKLAMMER);
  414. in_args:=true;
  415. p1:=comp_expr(true);
  416. p2:=geninlinenode(l,false,p1);
  417. consume(_RKLAMMER);
  418. statement_syssym:=p2;
  419. end;
  420. in_inc_x,
  421. in_dec_x :
  422. begin
  423. consume(_LKLAMMER);
  424. in_args:=true;
  425. p1:=comp_expr(true);
  426. if token=_COMMA then
  427. begin
  428. consume(_COMMA);
  429. p2:=ccallparanode.create(comp_expr(true),nil);
  430. end
  431. else
  432. p2:=nil;
  433. p2:=ccallparanode.create(p1,p2);
  434. statement_syssym:=geninlinenode(l,false,p2);
  435. consume(_RKLAMMER);
  436. end;
  437. in_finalize_x:
  438. begin
  439. statement_syssym:=inline_finalize;
  440. end;
  441. in_copy_x:
  442. begin
  443. statement_syssym:=inline_copy;
  444. end;
  445. in_concat_x :
  446. begin
  447. consume(_LKLAMMER);
  448. in_args:=true;
  449. p2:=nil;
  450. while true do
  451. begin
  452. p1:=comp_expr(true);
  453. set_varstate(p1,true);
  454. if not((p1.resulttype.def.deftype=stringdef) or
  455. ((p1.resulttype.def.deftype=orddef) and
  456. (torddef(p1.resulttype.def).typ=uchar))) then
  457. Message(parser_e_illegal_parameter_list);
  458. if p2<>nil then
  459. p2:=caddnode.create(addn,p2,p1)
  460. else
  461. p2:=p1;
  462. if token=_COMMA then
  463. consume(_COMMA)
  464. else
  465. break;
  466. end;
  467. consume(_RKLAMMER);
  468. statement_syssym:=p2;
  469. end;
  470. in_read_x,
  471. in_readln_x :
  472. begin
  473. if token=_LKLAMMER then
  474. begin
  475. consume(_LKLAMMER);
  476. paras:=parse_paras(false,false);
  477. consume(_RKLAMMER);
  478. end
  479. else
  480. paras:=nil;
  481. p1:=geninlinenode(l,false,paras);
  482. statement_syssym := p1;
  483. end;
  484. in_setlength_x:
  485. begin
  486. statement_syssym := inline_setlength;
  487. end;
  488. in_length_x:
  489. begin
  490. consume(_LKLAMMER);
  491. in_args:=true;
  492. p1:=comp_expr(true);
  493. p2:=geninlinenode(l,false,p1);
  494. consume(_RKLAMMER);
  495. statement_syssym:=p2;
  496. end;
  497. in_write_x,
  498. in_writeln_x :
  499. begin
  500. if token=_LKLAMMER then
  501. begin
  502. consume(_LKLAMMER);
  503. paras:=parse_paras(true,false);
  504. consume(_RKLAMMER);
  505. end
  506. else
  507. paras:=nil;
  508. p1 := geninlinenode(l,false,paras);
  509. statement_syssym := p1;
  510. end;
  511. in_str_x_string :
  512. begin
  513. consume(_LKLAMMER);
  514. paras:=parse_paras(true,false);
  515. consume(_RKLAMMER);
  516. p1 := geninlinenode(l,false,paras);
  517. statement_syssym := p1;
  518. end;
  519. in_val_x:
  520. Begin
  521. consume(_LKLAMMER);
  522. in_args := true;
  523. p1:= ccallparanode.create(comp_expr(true), nil);
  524. consume(_COMMA);
  525. p2 := ccallparanode.create(comp_expr(true),p1);
  526. if (token = _COMMA) then
  527. Begin
  528. consume(_COMMA);
  529. p2 := ccallparanode.create(comp_expr(true),p2)
  530. End;
  531. consume(_RKLAMMER);
  532. p2 := geninlinenode(l,false,p2);
  533. statement_syssym := p2;
  534. End;
  535. in_include_x_y,
  536. in_exclude_x_y :
  537. begin
  538. consume(_LKLAMMER);
  539. in_args:=true;
  540. p1:=comp_expr(true);
  541. consume(_COMMA);
  542. p2:=comp_expr(true);
  543. statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,nil)));
  544. consume(_RKLAMMER);
  545. end;
  546. in_assert_x_y :
  547. begin
  548. consume(_LKLAMMER);
  549. in_args:=true;
  550. p1:=comp_expr(true);
  551. if token=_COMMA then
  552. begin
  553. consume(_COMMA);
  554. p2:=comp_expr(true);
  555. end
  556. else
  557. begin
  558. { then insert an empty string }
  559. p2:=cstringconstnode.createstr('',st_default);
  560. end;
  561. statement_syssym:=geninlinenode(l,false,ccallparanode.create(p1,ccallparanode.create(p2,nil)));
  562. consume(_RKLAMMER);
  563. end;
  564. else
  565. internalerror(15);
  566. end;
  567. in_args:=prev_in_args;
  568. end;
  569. function maybe_load_methodpointer(st:tsymtable;var p1:tnode):boolean;
  570. begin
  571. maybe_load_methodpointer:=false;
  572. if not assigned(p1) then
  573. begin
  574. case st.symtabletype of
  575. withsymtable :
  576. begin
  577. if (st.defowner.deftype=objectdef) then
  578. p1:=tnode(twithsymtable(st).withrefnode).getcopy;
  579. end;
  580. objectsymtable :
  581. begin
  582. p1:=load_self_node;
  583. { We are calling a member }
  584. maybe_load_methodpointer:=true;
  585. end;
  586. end;
  587. end;
  588. end;
  589. { reads the parameter for a subroutine call }
  590. procedure do_proc_call(sym:tsym;st:tsymtable;getaddr:boolean;var again : boolean;var p1:tnode);
  591. var
  592. membercall,
  593. prevafterassn : boolean;
  594. vs : tvarsym;
  595. para,p2 : tnode;
  596. currpara : tparaitem;
  597. aprocdef : tprocdef;
  598. begin
  599. prevafterassn:=afterassignment;
  600. afterassignment:=false;
  601. membercall:=false;
  602. aprocdef:=nil;
  603. { when it is a call to a member we need to load the
  604. methodpointer first }
  605. membercall:=maybe_load_methodpointer(st,p1);
  606. { When we are expecting a procvar we also need
  607. to get the address in some cases }
  608. if assigned(getprocvardef) then
  609. begin
  610. if (block_type=bt_const) or
  611. getaddr then
  612. begin
  613. aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
  614. getaddr:=true;
  615. end
  616. else
  617. if (m_tp_procvar in aktmodeswitches) then
  618. begin
  619. aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
  620. if assigned(aprocdef) then
  621. getaddr:=true;
  622. end;
  623. end;
  624. { only need to get the address of the procedure? }
  625. if getaddr then
  626. begin
  627. { Retrieve info which procvar to call. For tp_procvar the
  628. aprocdef is already loaded above so we can reuse it }
  629. if not assigned(aprocdef) and
  630. assigned(getprocvardef) then
  631. aprocdef:=Tprocsym(sym).search_procdef_byprocvardef(getprocvardef);
  632. { generate a methodcallnode or proccallnode }
  633. { we shouldn't convert things like @tcollection.load }
  634. p2:=cloadnode.create_procvar(sym,aprocdef,st);
  635. if assigned(p1) then
  636. begin
  637. if (p1.nodetype<>typen) then
  638. tloadnode(p2).set_mp(p1)
  639. else
  640. p1.free;
  641. end;
  642. p1:=p2;
  643. { no postfix operators }
  644. again:=false;
  645. end
  646. else
  647. begin
  648. para:=nil;
  649. if anon_inherited then
  650. begin
  651. if not assigned(current_procinfo) then
  652. internalerror(200305054);
  653. currpara:=tparaitem(current_procinfo.procdef.para.first);
  654. while assigned(currpara) do
  655. begin
  656. if not currpara.is_hidden then
  657. begin
  658. vs:=tvarsym(currpara.parasym);
  659. { if there is a localcopy then use that }
  660. if assigned(vs.localvarsym) then
  661. vs:=vs.localvarsym;
  662. para:=ccallparanode.create(cloadnode.create(vs,vs.owner),para);
  663. end;
  664. currpara:=tparaitem(currpara.next);
  665. end;
  666. end
  667. else
  668. begin
  669. if try_to_consume(_LKLAMMER) then
  670. begin
  671. para:=parse_paras(false,false);
  672. consume(_RKLAMMER);
  673. end;
  674. end;
  675. p1:=ccallnode.create(para,tprocsym(sym),st,p1);
  676. { indicate if this call was generated by a member and
  677. no explicit self is used, this is needed to determine
  678. how to handle a destructor call (PFV) }
  679. if membercall then
  680. include(p1.flags,nf_member_call);
  681. end;
  682. afterassignment:=prevafterassn;
  683. end;
  684. procedure handle_procvar(pv : tprocvardef;var p2 : tnode);
  685. var
  686. hp,hp2 : tnode;
  687. hpp : ^tnode;
  688. currprocdef : tprocdef;
  689. begin
  690. if not assigned(pv) then
  691. internalerror(200301121);
  692. if (m_tp_procvar in aktmodeswitches) then
  693. begin
  694. hp:=p2;
  695. hpp:=@p2;
  696. while assigned(hp) and
  697. (hp.nodetype=typeconvn) do
  698. begin
  699. hp:=ttypeconvnode(hp).left;
  700. { save orignal address of the old tree so we can replace the node }
  701. hpp:=@hp;
  702. end;
  703. if (hp.nodetype=calln) and
  704. { a procvar can't have parameters! }
  705. not assigned(tcallnode(hp).left) then
  706. begin
  707. currprocdef:=tcallnode(hp).symtableprocentry.search_procdef_byprocvardef(pv);
  708. if assigned(currprocdef) then
  709. begin
  710. hp2:=cloadnode.create_procvar(tprocsym(tcallnode(hp).symtableprocentry),currprocdef,tcallnode(hp).symtableproc);
  711. if (po_methodpointer in pv.procoptions) then
  712. tloadnode(hp2).set_mp(tnode(tcallnode(hp).methodpointer).getcopy);
  713. hp.destroy;
  714. { replace the old callnode with the new loadnode }
  715. hpp^:=hp2;
  716. end;
  717. end;
  718. end;
  719. end;
  720. { the following procedure handles the access to a property symbol }
  721. procedure handle_propertysym(sym : tsym;st : tsymtable;var p1 : tnode; getaddr: boolean);
  722. procedure symlist_to_node(var p1:tnode;pl:tsymlist);
  723. var
  724. plist : psymlistitem;
  725. begin
  726. plist:=pl.firstsym;
  727. while assigned(plist) do
  728. begin
  729. case plist^.sltype of
  730. sl_load :
  731. begin
  732. { p1 can already contain the loadnode of
  733. the class variable. When there is no tree yet we
  734. may need to load it for with or objects }
  735. if not assigned(p1) then
  736. begin
  737. case st.symtabletype of
  738. withsymtable :
  739. p1:=tnode(twithsymtable(st).withrefnode).getcopy;
  740. objectsymtable :
  741. p1:=load_self_node;
  742. end;
  743. end;
  744. if assigned(p1) then
  745. p1:=csubscriptnode.create(plist^.sym,p1)
  746. else
  747. p1:=cloadnode.create(plist^.sym,st);
  748. end;
  749. sl_subscript :
  750. p1:=csubscriptnode.create(plist^.sym,p1);
  751. sl_vec :
  752. p1:=cvecnode.create(p1,cordconstnode.create(plist^.value,s32bittype,true));
  753. else
  754. internalerror(200110205);
  755. end;
  756. plist:=plist^.next;
  757. end;
  758. include(p1.flags,nf_isproperty);
  759. end;
  760. var
  761. paras : tnode;
  762. p2 : tnode;
  763. membercall : boolean;
  764. begin
  765. paras:=nil;
  766. { property parameters? read them only if the property really }
  767. { has parameters }
  768. if (ppo_hasparameters in tpropertysym(sym).propoptions) then
  769. begin
  770. if token=_LECKKLAMMER then
  771. begin
  772. consume(_LECKKLAMMER);
  773. paras:=parse_paras(false,true);
  774. consume(_RECKKLAMMER);
  775. end;
  776. end;
  777. { indexed property }
  778. if (ppo_indexed in tpropertysym(sym).propoptions) then
  779. begin
  780. p2:=cordconstnode.create(tpropertysym(sym).index,tpropertysym(sym).indextype,true);
  781. paras:=ccallparanode.create(p2,paras);
  782. end;
  783. { we need only a write property if a := follows }
  784. { if not(afterassignment) and not(in_args) then }
  785. if token=_ASSIGNMENT then
  786. begin
  787. { write property: }
  788. if not tpropertysym(sym).writeaccess.empty then
  789. begin
  790. case tpropertysym(sym).writeaccess.firstsym^.sym.typ of
  791. procsym :
  792. begin
  793. { generate the method call }
  794. membercall:=maybe_load_methodpointer(st,p1);
  795. p1:=ccallnode.create(paras,
  796. tprocsym(tpropertysym(sym).writeaccess.firstsym^.sym),st,p1);
  797. if membercall then
  798. include(tcallnode(p1).flags,nf_member_call);
  799. paras:=nil;
  800. consume(_ASSIGNMENT);
  801. { read the expression }
  802. if tpropertysym(sym).proptype.def.deftype=procvardef then
  803. getprocvardef:=tprocvardef(tpropertysym(sym).proptype.def);
  804. p2:=comp_expr(true);
  805. if assigned(getprocvardef) then
  806. handle_procvar(getprocvardef,p2);
  807. tcallnode(p1).left:=ccallparanode.create(p2,tcallnode(p1).left);
  808. include(tcallnode(p1).flags,nf_isproperty);
  809. getprocvardef:=nil;
  810. end;
  811. varsym :
  812. begin
  813. { generate access code }
  814. symlist_to_node(p1,tpropertysym(sym).writeaccess);
  815. consume(_ASSIGNMENT);
  816. { read the expression }
  817. p2:=comp_expr(true);
  818. p1:=cassignmentnode.create(p1,p2);
  819. end
  820. else
  821. begin
  822. p1:=cerrornode.create;
  823. Message(parser_e_no_procedure_to_access_property);
  824. end;
  825. end;
  826. end
  827. else
  828. begin
  829. p1:=cerrornode.create;
  830. Message(parser_e_no_procedure_to_access_property);
  831. end;
  832. end
  833. else
  834. begin
  835. { read property: }
  836. if not tpropertysym(sym).readaccess.empty then
  837. begin
  838. case tpropertysym(sym).readaccess.firstsym^.sym.typ of
  839. varsym :
  840. begin
  841. { generate access code }
  842. symlist_to_node(p1,tpropertysym(sym).readaccess);
  843. end;
  844. procsym :
  845. begin
  846. { generate the method call }
  847. membercall:=maybe_load_methodpointer(st,p1);
  848. p1:=ccallnode.create(paras,tprocsym(tpropertysym(sym).readaccess.firstsym^.sym),st,p1);
  849. if membercall then
  850. include(tcallnode(p1).flags,nf_member_call);
  851. paras:=nil;
  852. include(p1.flags,nf_isproperty);
  853. end
  854. else
  855. begin
  856. p1:=cerrornode.create;
  857. Message(type_e_mismatch);
  858. end;
  859. end;
  860. end
  861. else
  862. begin
  863. { error, no function to read property }
  864. p1:=cerrornode.create;
  865. Message(parser_e_no_procedure_to_access_property);
  866. end;
  867. end;
  868. { release paras if not used }
  869. if assigned(paras) then
  870. paras.free;
  871. end;
  872. { the ID token has to be consumed before calling this function }
  873. procedure do_member_read(getaddr : boolean;sym : tsym;var p1 : tnode;var again : boolean;callnflags:tnodeflags);
  874. var
  875. static_name : string;
  876. isclassref : boolean;
  877. srsymtable : tsymtable;
  878. {$ifdef CHECKINHERITEDRESULT}
  879. newstatement : tstatementnode;
  880. newblock : tblocknode;
  881. {$endif CHECKINHERITEDRESULT}
  882. begin
  883. if sym=nil then
  884. begin
  885. { pattern is still valid unless
  886. there is another ID just after the ID of sym }
  887. Message1(sym_e_id_no_member,pattern);
  888. p1.free;
  889. p1:=cerrornode.create;
  890. { try to clean up }
  891. again:=false;
  892. end
  893. else
  894. begin
  895. if assigned(p1) then
  896. begin
  897. if not assigned(p1.resulttype.def) then
  898. do_resulttypepass(p1);
  899. isclassref:=(p1.resulttype.def.deftype=classrefdef);
  900. end
  901. else
  902. isclassref:=false;
  903. { we assume, that only procsyms and varsyms are in an object }
  904. { symbol table, for classes, properties are allowed }
  905. case sym.typ of
  906. procsym:
  907. begin
  908. do_proc_call(sym,sym.owner,
  909. (getaddr and not(token in [_CARET,_POINT])),
  910. again,p1);
  911. { add provided flags }
  912. if (p1.nodetype=calln) then
  913. p1.flags:=p1.flags+callnflags;
  914. { we need to know which procedure is called }
  915. do_resulttypepass(p1);
  916. { now we know the method that is called }
  917. if (p1.nodetype=calln) and
  918. assigned(tcallnode(p1).procdefinition) then
  919. begin
  920. { calling using classref? }
  921. if isclassref and
  922. not(po_classmethod in tcallnode(p1).procdefinition.procoptions) and
  923. not(tcallnode(p1).procdefinition.proctypeoption=potype_constructor) then
  924. Message(parser_e_only_class_methods_via_class_ref);
  925. {$ifdef CHECKINHERITEDRESULT}
  926. { when calling inherited constructor we need to check the return value }
  927. if (nf_inherited in callnflags) and
  928. (tcallnode(p1).procdefinition.proctypeoption=potype_constructor) then
  929. begin
  930. {
  931. For Classes:
  932. self:=inherited constructor
  933. if self=nil then
  934. exit
  935. For objects:
  936. if inherited constructor=false then
  937. begin
  938. self:=nil;
  939. exit;
  940. end;
  941. }
  942. if is_class(tprocdef(tcallnode(p1).procdefinition)._class) then
  943. begin
  944. newblock:=internalstatements(newstatement,true);
  945. addstatement(newstatement,cassignmentnode.create(
  946. ctypeconvnode.create(
  947. load_self_pointer_node,
  948. voidpointertype),
  949. ctypeconvnode.create(
  950. p1,
  951. voidpointertype)));
  952. addstatement(newstatement,cifnode.create(
  953. caddnode.create(equaln,
  954. load_self_pointer_node,
  955. cnilnode.create),
  956. cexitnode.create(nil),
  957. nil));
  958. p1:=newblock;
  959. end
  960. else
  961. if is_object(tprocdef(tcallnode(p1).procdefinition)._class) then
  962. begin
  963. newblock:=internalstatements(newstatement,true);
  964. addstatement(newstatement,call_fail_node);
  965. addstatement(newstatement,cexitnode.create(nil));
  966. p1:=cifnode.create(
  967. caddnode.create(equaln,
  968. cordconstnode.create(0,booltype,false),
  969. p1),
  970. newblock,
  971. nil);
  972. end
  973. else
  974. internalerror(200305133);
  975. end;
  976. {$endif CHECKINHERITEDRESULT}
  977. do_resulttypepass(p1);
  978. end;
  979. end;
  980. varsym:
  981. begin
  982. if (sp_static in sym.symoptions) then
  983. begin
  984. static_name:=lower(sym.owner.name^)+'_'+sym.name;
  985. searchsym(static_name,sym,srsymtable);
  986. check_hints(sym);
  987. p1.free;
  988. p1:=cloadnode.create(sym,srsymtable);
  989. end
  990. else
  991. begin
  992. if isclassref then
  993. Message(parser_e_only_class_methods_via_class_ref);
  994. p1:=csubscriptnode.create(sym,p1);
  995. end;
  996. end;
  997. propertysym:
  998. begin
  999. if isclassref then
  1000. Message(parser_e_only_class_methods_via_class_ref);
  1001. handle_propertysym(sym,sym.owner,p1,getaddr);
  1002. end;
  1003. else internalerror(16);
  1004. end;
  1005. end;
  1006. end;
  1007. {****************************************************************************
  1008. Factor
  1009. ****************************************************************************}
  1010. {$ifdef fpc}
  1011. {$maxfpuregisters 0}
  1012. {$endif fpc}
  1013. function factor(getaddr : boolean) : tnode;
  1014. {---------------------------------------------
  1015. Factor_read_id
  1016. ---------------------------------------------}
  1017. procedure factor_read_id(var p1:tnode;var again:boolean);
  1018. var
  1019. pc : pchar;
  1020. len : longint;
  1021. srsym : tsym;
  1022. possible_error : boolean;
  1023. srsymtable : tsymtable;
  1024. storesymtablestack : tsymtable;
  1025. htype : ttype;
  1026. static_name : string;
  1027. begin
  1028. { allow post fix operators }
  1029. again:=true;
  1030. consume_sym(srsym,srsymtable);
  1031. { Access to funcret or need to call the function? }
  1032. if (srsym.typ in [absolutesym,varsym]) and
  1033. (vo_is_funcret in tvarsym(srsym).varoptions) and
  1034. (
  1035. (token=_LKLAMMER) or
  1036. (not(m_fpc in aktmodeswitches) and
  1037. (afterassignment or in_args) and
  1038. not(vo_is_result in tvarsym(srsym).varoptions))
  1039. ) then
  1040. begin
  1041. storesymtablestack:=symtablestack;
  1042. symtablestack:=srsym.owner.next;
  1043. searchsym(srsym.name,srsym,srsymtable);
  1044. if not assigned(srsym) then
  1045. srsym:=generrorsym;
  1046. if (srsym.typ<>procsym) then
  1047. Message(cg_e_illegal_expression);
  1048. symtablestack:=storesymtablestack;
  1049. end;
  1050. begin
  1051. { check semantics of private }
  1052. if (srsym.typ in [propertysym,procsym,varsym]) and
  1053. (srsym.owner.symtabletype=objectsymtable) then
  1054. begin
  1055. if (sp_private in srsym.symoptions) and
  1056. (tobjectdef(srsym.owner.defowner).owner.symtabletype=globalsymtable) and
  1057. (tobjectdef(srsym.owner.defowner).owner.unitid<>0) then
  1058. Message(parser_e_cant_access_private_member);
  1059. end;
  1060. case srsym.typ of
  1061. absolutesym :
  1062. begin
  1063. p1:=cloadnode.create(srsym,srsymtable);
  1064. end;
  1065. varsym :
  1066. begin
  1067. if (sp_static in srsym.symoptions) then
  1068. begin
  1069. static_name:=lower(srsym.owner.name^)+'_'+srsym.name;
  1070. searchsym(static_name,srsym,srsymtable);
  1071. check_hints(srsym);
  1072. end
  1073. else
  1074. begin
  1075. { are we in a class method, we check here the
  1076. srsymtable, because a field in another object
  1077. also has objectsymtable. And withsymtable is
  1078. not possible for self in class methods (PFV) }
  1079. if (srsymtable.symtabletype=objectsymtable) and
  1080. assigned(current_procinfo) and
  1081. (po_classmethod in current_procinfo.procdef.procoptions) then
  1082. Message(parser_e_only_class_methods);
  1083. end;
  1084. case srsymtable.symtabletype of
  1085. objectsymtable :
  1086. p1:=csubscriptnode.create(srsym,load_self_node);
  1087. withsymtable :
  1088. p1:=csubscriptnode.create(srsym,tnode(twithsymtable(srsymtable).withrefnode).getcopy);
  1089. else
  1090. p1:=cloadnode.create(srsym,srsymtable);
  1091. end;
  1092. if tvarsym(srsym).varstate=vs_declared then
  1093. begin
  1094. include(p1.flags,nf_first_use);
  1095. { set special between first loaded until checked in resulttypepass }
  1096. tvarsym(srsym).varstate:=vs_declared_and_first_found;
  1097. end;
  1098. end;
  1099. typedconstsym :
  1100. begin
  1101. p1:=cloadnode.create(srsym,srsymtable);
  1102. end;
  1103. syssym :
  1104. begin
  1105. p1:=statement_syssym(tsyssym(srsym).number);
  1106. end;
  1107. typesym :
  1108. begin
  1109. htype.setsym(srsym);
  1110. if not assigned(htype.def) then
  1111. begin
  1112. again:=false;
  1113. end
  1114. else
  1115. begin
  1116. if token=_LKLAMMER then
  1117. begin
  1118. consume(_LKLAMMER);
  1119. p1:=comp_expr(true);
  1120. consume(_RKLAMMER);
  1121. p1:=ctypeconvnode.create_explicit(p1,htype);
  1122. end
  1123. else { not LKLAMMER }
  1124. if (token=_POINT) and
  1125. is_object(htype.def) then
  1126. begin
  1127. consume(_POINT);
  1128. if assigned(current_procinfo) and
  1129. assigned(current_procinfo.procdef._class) and
  1130. not(getaddr) then
  1131. begin
  1132. if current_procinfo.procdef._class.is_related(tobjectdef(htype.def)) then
  1133. begin
  1134. p1:=ctypenode.create(htype);
  1135. { search also in inherited methods }
  1136. srsym:=searchsym_in_class(tobjectdef(htype.def),pattern);
  1137. check_hints(srsym);
  1138. consume(_ID);
  1139. do_member_read(false,srsym,p1,again,[]);
  1140. end
  1141. else
  1142. begin
  1143. Message(parser_e_no_super_class);
  1144. again:=false;
  1145. end;
  1146. end
  1147. else
  1148. begin
  1149. { allows @TObject.Load }
  1150. { also allows static methods and variables }
  1151. p1:=ctypenode.create(htype);
  1152. { TP allows also @TMenu.Load if Load is only }
  1153. { defined in an anchestor class }
  1154. srsym:=search_class_member(tobjectdef(htype.def),pattern);
  1155. check_hints(srsym);
  1156. if not assigned(srsym) then
  1157. Message1(sym_e_id_no_member,pattern)
  1158. else if not(getaddr) and not(sp_static in srsym.symoptions) then
  1159. Message(sym_e_only_static_in_static)
  1160. else
  1161. begin
  1162. consume(_ID);
  1163. do_member_read(getaddr,srsym,p1,again,[]);
  1164. end;
  1165. end;
  1166. end
  1167. else
  1168. begin
  1169. { class reference ? }
  1170. if is_class(htype.def) then
  1171. begin
  1172. if getaddr and (token=_POINT) then
  1173. begin
  1174. consume(_POINT);
  1175. { allows @Object.Method }
  1176. { also allows static methods and variables }
  1177. p1:=ctypenode.create(htype);
  1178. { TP allows also @TMenu.Load if Load is only }
  1179. { defined in an anchestor class }
  1180. srsym:=search_class_member(tobjectdef(htype.def),pattern);
  1181. check_hints(srsym);
  1182. if not assigned(srsym) then
  1183. Message1(sym_e_id_no_member,pattern)
  1184. else
  1185. begin
  1186. consume(_ID);
  1187. do_member_read(getaddr,srsym,p1,again,[]);
  1188. end;
  1189. end
  1190. else
  1191. begin
  1192. p1:=ctypenode.create(htype);
  1193. { For a type block we simply return only
  1194. the type. For all other blocks we return
  1195. a loadvmt node }
  1196. if (block_type<>bt_type) then
  1197. p1:=cloadvmtaddrnode.create(p1);
  1198. end;
  1199. end
  1200. else
  1201. p1:=ctypenode.create(htype);
  1202. end;
  1203. end;
  1204. end;
  1205. enumsym :
  1206. begin
  1207. p1:=genenumnode(tenumsym(srsym));
  1208. end;
  1209. constsym :
  1210. begin
  1211. case tconstsym(srsym).consttyp of
  1212. constint :
  1213. begin
  1214. { do a very dirty trick to bootstrap this code }
  1215. if (tconstsym(srsym).value.valueord>=-(int64(2147483647)+int64(1))) and
  1216. (tconstsym(srsym).value.valueord<=2147483647) then
  1217. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,s32bittype,true)
  1218. else if (tconstsym(srsym).value.valueord > maxlongint) and
  1219. (tconstsym(srsym).value.valueord <= int64(maxlongint)+int64(maxlongint)+1) then
  1220. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,u32bittype,true)
  1221. else
  1222. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,cs64bittype,true);
  1223. end;
  1224. conststring :
  1225. begin
  1226. len:=tconstsym(srsym).value.len;
  1227. if not(cs_ansistrings in aktlocalswitches) and (len>255) then
  1228. len:=255;
  1229. getmem(pc,len+1);
  1230. move(pchar(tconstsym(srsym).value.valueptr)^,pc^,len);
  1231. pc[len]:=#0;
  1232. p1:=cstringconstnode.createpchar(pc,len);
  1233. end;
  1234. constchar :
  1235. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,cchartype,true);
  1236. constreal :
  1237. p1:=crealconstnode.create(pbestreal(tconstsym(srsym).value.valueptr)^,pbestrealtype^);
  1238. constbool :
  1239. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,booltype,true);
  1240. constset :
  1241. p1:=csetconstnode.create(pconstset(tconstsym(srsym).value.valueptr),tconstsym(srsym).consttype);
  1242. constord :
  1243. p1:=cordconstnode.create(tconstsym(srsym).value.valueord,tconstsym(srsym).consttype,true);
  1244. constpointer :
  1245. p1:=cpointerconstnode.create(tconstsym(srsym).value.valueordptr,tconstsym(srsym).consttype);
  1246. constnil :
  1247. p1:=cnilnode.create;
  1248. constresourcestring:
  1249. begin
  1250. p1:=cloadnode.create(srsym,srsymtable);
  1251. do_resulttypepass(p1);
  1252. p1.resulttype:=cansistringtype;
  1253. end;
  1254. constguid :
  1255. p1:=cguidconstnode.create(pguid(tconstsym(srsym).value.valueptr)^);
  1256. end;
  1257. end;
  1258. procsym :
  1259. begin
  1260. { are we in a class method ? }
  1261. possible_error:=(srsymtable.symtabletype<>withsymtable) and
  1262. (srsym.owner.symtabletype=objectsymtable) and
  1263. not(is_interface(tdef(srsym.owner.defowner))) and
  1264. assigned(current_procinfo) and
  1265. (po_classmethod in current_procinfo.procdef.procoptions);
  1266. do_proc_call(srsym,srsymtable,
  1267. (getaddr and not(token in [_CARET,_POINT])),
  1268. again,p1);
  1269. { we need to know which procedure is called }
  1270. if possible_error then
  1271. begin
  1272. do_resulttypepass(p1);
  1273. if not(po_classmethod in tcallnode(p1).procdefinition.procoptions) then
  1274. Message(parser_e_only_class_methods);
  1275. end;
  1276. end;
  1277. propertysym :
  1278. begin
  1279. { access to property in a method }
  1280. { are we in a class method ? }
  1281. if (srsym.owner.symtabletype=objectsymtable) and
  1282. assigned(current_procinfo) and
  1283. (po_classmethod in current_procinfo.procdef.procoptions) then
  1284. Message(parser_e_only_class_methods);
  1285. { no method pointer }
  1286. p1:=nil;
  1287. handle_propertysym(srsym,srsymtable,p1,getaddr);
  1288. end;
  1289. labelsym :
  1290. begin
  1291. consume(_COLON);
  1292. if tlabelsym(srsym).defined then
  1293. Message(sym_e_label_already_defined);
  1294. tlabelsym(srsym).defined:=true;
  1295. p1:=clabelnode.create(tlabelsym(srsym),nil);
  1296. end;
  1297. errorsym :
  1298. begin
  1299. p1:=cerrornode.create;
  1300. if token=_LKLAMMER then
  1301. begin
  1302. consume(_LKLAMMER);
  1303. parse_paras(false,false);
  1304. consume(_RKLAMMER);
  1305. end;
  1306. end;
  1307. else
  1308. begin
  1309. p1:=cerrornode.create;
  1310. Message(cg_e_illegal_expression);
  1311. end;
  1312. end; { end case }
  1313. end;
  1314. end;
  1315. {---------------------------------------------
  1316. Factor_Read_Set
  1317. ---------------------------------------------}
  1318. { Read a set between [] }
  1319. function factor_read_set:tnode;
  1320. var
  1321. p1,p2 : tnode;
  1322. lastp,
  1323. buildp : tarrayconstructornode;
  1324. begin
  1325. buildp:=nil;
  1326. { be sure that a least one arrayconstructn is used, also for an
  1327. empty [] }
  1328. if token=_RECKKLAMMER then
  1329. buildp:=carrayconstructornode.create(nil,buildp)
  1330. else
  1331. begin
  1332. while true do
  1333. begin
  1334. p1:=comp_expr(true);
  1335. if token=_POINTPOINT then
  1336. begin
  1337. consume(_POINTPOINT);
  1338. p2:=comp_expr(true);
  1339. p1:=carrayconstructorrangenode.create(p1,p2);
  1340. end;
  1341. { insert at the end of the tree, to get the correct order }
  1342. if not assigned(buildp) then
  1343. begin
  1344. buildp:=carrayconstructornode.create(p1,nil);
  1345. lastp:=buildp;
  1346. end
  1347. else
  1348. begin
  1349. lastp.right:=carrayconstructornode.create(p1,nil);
  1350. lastp:=tarrayconstructornode(lastp.right);
  1351. end;
  1352. { there could be more elements }
  1353. if token=_COMMA then
  1354. consume(_COMMA)
  1355. else
  1356. break;
  1357. end;
  1358. end;
  1359. factor_read_set:=buildp;
  1360. end;
  1361. {---------------------------------------------
  1362. PostFixOperators
  1363. ---------------------------------------------}
  1364. procedure postfixoperators(var p1:tnode;var again:boolean);
  1365. { tries to avoid syntax errors after invalid qualifiers }
  1366. procedure recoverconsume_postfixops;
  1367. begin
  1368. while true do
  1369. begin
  1370. case token of
  1371. _CARET:
  1372. consume(_CARET);
  1373. _POINT:
  1374. begin
  1375. consume(_POINT);
  1376. if token=_ID then
  1377. consume(_ID);
  1378. end;
  1379. _LECKKLAMMER:
  1380. begin
  1381. consume(_LECKKLAMMER);
  1382. repeat
  1383. comp_expr(true);
  1384. if token=_COMMA then
  1385. consume(_COMMA)
  1386. else
  1387. break;
  1388. until false;
  1389. consume(_RECKKLAMMER);
  1390. end
  1391. else
  1392. break;
  1393. end;
  1394. end;
  1395. end;
  1396. var
  1397. store_static : boolean;
  1398. protsym : tpropertysym;
  1399. p2,p3 : tnode;
  1400. hsym : tsym;
  1401. classh : tobjectdef;
  1402. begin
  1403. again:=true;
  1404. while again do
  1405. begin
  1406. { we need the resulttype }
  1407. do_resulttypepass(p1);
  1408. if codegenerror then
  1409. begin
  1410. recoverconsume_postfixops;
  1411. exit;
  1412. end;
  1413. { handle token }
  1414. case token of
  1415. _CARET:
  1416. begin
  1417. consume(_CARET);
  1418. if (p1.resulttype.def.deftype<>pointerdef) then
  1419. begin
  1420. { ^ as binary operator is a problem!!!! (FK) }
  1421. again:=false;
  1422. Message(cg_e_invalid_qualifier);
  1423. recoverconsume_postfixops;
  1424. p1.destroy;
  1425. p1:=cerrornode.create;
  1426. end
  1427. else
  1428. begin
  1429. p1:=cderefnode.create(p1);
  1430. end;
  1431. end;
  1432. _LECKKLAMMER:
  1433. begin
  1434. if is_class_or_interface(p1.resulttype.def) then
  1435. begin
  1436. { default property }
  1437. protsym:=search_default_property(tobjectdef(p1.resulttype.def));
  1438. if not(assigned(protsym)) then
  1439. begin
  1440. p1.destroy;
  1441. p1:=cerrornode.create;
  1442. again:=false;
  1443. message(parser_e_no_default_property_available);
  1444. end
  1445. else
  1446. begin
  1447. { The property symbol is referenced indirect }
  1448. inc(protsym.refs);
  1449. handle_propertysym(protsym,protsym.owner,p1,getaddr);
  1450. end;
  1451. end
  1452. else
  1453. begin
  1454. consume(_LECKKLAMMER);
  1455. repeat
  1456. case p1.resulttype.def.deftype of
  1457. pointerdef:
  1458. begin
  1459. { support delphi autoderef }
  1460. if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=arraydef) and
  1461. (m_autoderef in aktmodeswitches) then
  1462. begin
  1463. p1:=cderefnode.create(p1);
  1464. end;
  1465. p2:=comp_expr(true);
  1466. p1:=cvecnode.create(p1,p2);
  1467. end;
  1468. stringdef :
  1469. begin
  1470. p2:=comp_expr(true);
  1471. p1:=cvecnode.create(p1,p2);
  1472. end;
  1473. arraydef :
  1474. begin
  1475. p2:=comp_expr(true);
  1476. { support SEG:OFS for go32v2 Mem[] }
  1477. if (target_info.system=system_i386_go32v2) and
  1478. (p1.nodetype=loadn) and
  1479. assigned(tloadnode(p1).symtableentry) and
  1480. assigned(tloadnode(p1).symtableentry.owner.name) and
  1481. (tloadnode(p1).symtableentry.owner.name^='SYSTEM') and
  1482. ((tloadnode(p1).symtableentry.name='MEM') or
  1483. (tloadnode(p1).symtableentry.name='MEMW') or
  1484. (tloadnode(p1).symtableentry.name='MEML')) then
  1485. begin
  1486. if (token=_COLON) then
  1487. begin
  1488. consume(_COLON);
  1489. p3:=caddnode.create(muln,cordconstnode.create($10,s32bittype,false),p2);
  1490. p2:=comp_expr(true);
  1491. p2:=caddnode.create(addn,p2,p3);
  1492. p1:=cvecnode.create(p1,p2);
  1493. include(tvecnode(p1).flags,nf_memseg);
  1494. include(tvecnode(p1).flags,nf_memindex);
  1495. end
  1496. else
  1497. begin
  1498. p1:=cvecnode.create(p1,p2);
  1499. include(tvecnode(p1).flags,nf_memindex);
  1500. end;
  1501. end
  1502. else
  1503. p1:=cvecnode.create(p1,p2);
  1504. end;
  1505. else
  1506. begin
  1507. Message(cg_e_invalid_qualifier);
  1508. p1.destroy;
  1509. p1:=cerrornode.create;
  1510. comp_expr(true);
  1511. again:=false;
  1512. end;
  1513. end;
  1514. do_resulttypepass(p1);
  1515. if token=_COMMA then
  1516. consume(_COMMA)
  1517. else
  1518. break;
  1519. until false;
  1520. consume(_RECKKLAMMER);
  1521. end;
  1522. end;
  1523. _POINT :
  1524. begin
  1525. consume(_POINT);
  1526. if (p1.resulttype.def.deftype=pointerdef) and
  1527. (m_autoderef in aktmodeswitches) then
  1528. begin
  1529. p1:=cderefnode.create(p1);
  1530. do_resulttypepass(p1);
  1531. end;
  1532. case p1.resulttype.def.deftype of
  1533. recorddef:
  1534. begin
  1535. hsym:=tsym(trecorddef(p1.resulttype.def).symtable.search(pattern));
  1536. check_hints(hsym);
  1537. if assigned(hsym) and
  1538. (hsym.typ=varsym) then
  1539. p1:=csubscriptnode.create(hsym,p1)
  1540. else
  1541. begin
  1542. Message1(sym_e_illegal_field,pattern);
  1543. p1.destroy;
  1544. p1:=cerrornode.create;
  1545. end;
  1546. consume(_ID);
  1547. end;
  1548. variantdef:
  1549. begin
  1550. end;
  1551. classrefdef:
  1552. begin
  1553. classh:=tobjectdef(tclassrefdef(p1.resulttype.def).pointertype.def);
  1554. hsym:=searchsym_in_class(classh,pattern);
  1555. check_hints(hsym);
  1556. if hsym=nil then
  1557. begin
  1558. Message1(sym_e_id_no_member,pattern);
  1559. p1.destroy;
  1560. p1:=cerrornode.create;
  1561. { try to clean up }
  1562. consume(_ID);
  1563. end
  1564. else
  1565. begin
  1566. consume(_ID);
  1567. do_member_read(getaddr,hsym,p1,again,[]);
  1568. end;
  1569. end;
  1570. objectdef:
  1571. begin
  1572. store_static:=allow_only_static;
  1573. allow_only_static:=false;
  1574. classh:=tobjectdef(p1.resulttype.def);
  1575. hsym:=searchsym_in_class(classh,pattern);
  1576. check_hints(hsym);
  1577. allow_only_static:=store_static;
  1578. if hsym=nil then
  1579. begin
  1580. Message1(sym_e_id_no_member,pattern);
  1581. p1.destroy;
  1582. p1:=cerrornode.create;
  1583. { try to clean up }
  1584. consume(_ID);
  1585. end
  1586. else
  1587. begin
  1588. consume(_ID);
  1589. do_member_read(getaddr,hsym,p1,again,[]);
  1590. end;
  1591. end;
  1592. pointerdef:
  1593. begin
  1594. Message(cg_e_invalid_qualifier);
  1595. if tpointerdef(p1.resulttype.def).pointertype.def.deftype in [recorddef,objectdef,classrefdef] then
  1596. Message(parser_h_maybe_deref_caret_missing);
  1597. end;
  1598. else
  1599. begin
  1600. Message(cg_e_invalid_qualifier);
  1601. p1.destroy;
  1602. p1:=cerrornode.create;
  1603. consume(_ID);
  1604. end;
  1605. end;
  1606. end;
  1607. else
  1608. begin
  1609. { is this a procedure variable ? }
  1610. if assigned(p1.resulttype.def) then
  1611. begin
  1612. if (p1.resulttype.def.deftype=procvardef) then
  1613. begin
  1614. if assigned(getprocvardef) and
  1615. equal_defs(p1.resulttype.def,getprocvardef) then
  1616. again:=false
  1617. else
  1618. if (token=_LKLAMMER) or
  1619. ((tprocvardef(p1.resulttype.def).maxparacount=0) and
  1620. (not((token in [_ASSIGNMENT,_UNEQUAL,_EQUAL]))) and
  1621. (not afterassignment) and
  1622. (not in_args)) then
  1623. begin
  1624. if try_to_consume(_LKLAMMER) then
  1625. begin
  1626. p2:=parse_paras(false,false);
  1627. consume(_RKLAMMER);
  1628. end
  1629. else
  1630. p2:=nil;
  1631. p1:=ccallnode.create_procvar(p2,p1);
  1632. { proc():= is never possible }
  1633. if token=_ASSIGNMENT then
  1634. begin
  1635. Message(cg_e_illegal_expression);
  1636. p1.free;
  1637. p1:=cerrornode.create;
  1638. again:=false;
  1639. end;
  1640. end
  1641. else
  1642. again:=false;
  1643. end
  1644. else
  1645. again:=false;
  1646. end
  1647. else
  1648. again:=false;
  1649. end;
  1650. end;
  1651. end; { while again }
  1652. end;
  1653. {---------------------------------------------
  1654. Factor (Main)
  1655. ---------------------------------------------}
  1656. var
  1657. l : longint;
  1658. card : cardinal;
  1659. ic : TConstExprInt;
  1660. oldp1,
  1661. p1 : tnode;
  1662. code : integer;
  1663. again : boolean;
  1664. sym : tsym;
  1665. pd : tprocdef;
  1666. classh : tobjectdef;
  1667. d : bestreal;
  1668. hs : string;
  1669. htype : ttype;
  1670. filepos : tfileposinfo;
  1671. {---------------------------------------------
  1672. Helpers
  1673. ---------------------------------------------}
  1674. procedure check_tokenpos;
  1675. begin
  1676. if (p1<>oldp1) then
  1677. begin
  1678. if assigned(p1) then
  1679. p1.set_tree_filepos(filepos);
  1680. oldp1:=p1;
  1681. filepos:=akttokenpos;
  1682. end;
  1683. end;
  1684. begin
  1685. oldp1:=nil;
  1686. p1:=nil;
  1687. filepos:=akttokenpos;
  1688. again:=false;
  1689. if token=_ID then
  1690. begin
  1691. factor_read_id(p1,again);
  1692. if again then
  1693. begin
  1694. check_tokenpos;
  1695. { handle post fix operators }
  1696. postfixoperators(p1,again);
  1697. end;
  1698. end
  1699. else
  1700. case token of
  1701. _SELF :
  1702. begin
  1703. again:=true;
  1704. consume(_SELF);
  1705. if not(assigned(current_procinfo) and
  1706. assigned(current_procinfo.procdef._class)) then
  1707. begin
  1708. p1:=cerrornode.create;
  1709. again:=false;
  1710. Message(parser_e_self_not_in_method);
  1711. end
  1712. else
  1713. begin
  1714. p1:=load_self_node;
  1715. postfixoperators(p1,again);
  1716. end;
  1717. end;
  1718. _INHERITED :
  1719. begin
  1720. again:=true;
  1721. consume(_INHERITED);
  1722. if assigned(current_procinfo) and
  1723. assigned(current_procinfo.procdef._class) then
  1724. begin
  1725. classh:=current_procinfo.procdef._class.childof;
  1726. { if inherited; only then we need the method with
  1727. the same name }
  1728. if token in endtokens then
  1729. begin
  1730. hs:=current_procinfo.procdef.procsym.name;
  1731. anon_inherited:=true;
  1732. { For message methods we need to search using the message
  1733. number or string }
  1734. pd:=tprocsym(current_procinfo.procdef.procsym).first_procdef;
  1735. if (po_msgint in pd.procoptions) then
  1736. sym:=searchsym_in_class_by_msgint(classh,pd.messageinf.i)
  1737. else
  1738. if (po_msgstr in pd.procoptions) then
  1739. sym:=searchsym_in_class_by_msgstr(classh,pd.messageinf.str)
  1740. else
  1741. sym:=searchsym_in_class(classh,hs);
  1742. end
  1743. else
  1744. begin
  1745. hs:=pattern;
  1746. consume(_ID);
  1747. anon_inherited:=false;
  1748. sym:=searchsym_in_class(classh,hs);
  1749. end;
  1750. if assigned(sym) then
  1751. begin
  1752. check_hints(sym);
  1753. { load the procdef from the inherited class and
  1754. not from self }
  1755. if sym.typ=procsym then
  1756. begin
  1757. htype.setdef(classh);
  1758. p1:=ctypenode.create(htype);
  1759. end;
  1760. do_member_read(false,sym,p1,again,[nf_inherited,nf_anon_inherited]);
  1761. end
  1762. else
  1763. begin
  1764. if anon_inherited then
  1765. begin
  1766. { For message methods we need to call DefaultHandler }
  1767. if (po_msgint in pd.procoptions) or
  1768. (po_msgstr in pd.procoptions) then
  1769. begin
  1770. sym:=searchsym_in_class(classh,'DEFAULTHANDLER');
  1771. if not assigned(sym) or
  1772. (sym.typ<>procsym) then
  1773. internalerror(200303171);
  1774. p1:=nil;
  1775. do_proc_call(sym,sym.owner,false,again,p1);
  1776. end
  1777. else
  1778. begin
  1779. { we need to ignore the inherited; }
  1780. p1:=cnothingnode.create;
  1781. end;
  1782. end
  1783. else
  1784. begin
  1785. Message1(sym_e_id_no_member,hs);
  1786. p1:=cerrornode.create;
  1787. end;
  1788. again:=false;
  1789. end;
  1790. { turn auto inheriting off }
  1791. anon_inherited:=false;
  1792. end
  1793. else
  1794. begin
  1795. Message(parser_e_generic_methods_only_in_methods);
  1796. again:=false;
  1797. p1:=cerrornode.create;
  1798. end;
  1799. postfixoperators(p1,again);
  1800. end;
  1801. _INTCONST :
  1802. begin
  1803. { try cardinal first }
  1804. val(pattern,card,code);
  1805. if code<>0 then
  1806. begin
  1807. { then longint }
  1808. valint(pattern,l,code);
  1809. if code <> 0 then
  1810. begin
  1811. { then int64 }
  1812. val(pattern,ic,code);
  1813. if code<>0 then
  1814. begin
  1815. {finally float }
  1816. val(pattern,d,code);
  1817. if code<>0 then
  1818. begin
  1819. Message(cg_e_invalid_integer);
  1820. consume(_INTCONST);
  1821. l:=1;
  1822. p1:=cordconstnode.create(l,s32bittype,true);
  1823. end
  1824. else
  1825. begin
  1826. consume(_INTCONST);
  1827. p1:=crealconstnode.create(d,pbestrealtype^);
  1828. end;
  1829. end
  1830. else
  1831. begin
  1832. consume(_INTCONST);
  1833. p1:=cordconstnode.create(ic,cs64bittype,true);
  1834. end
  1835. end
  1836. else
  1837. begin
  1838. consume(_INTCONST);
  1839. p1:=cordconstnode.create(l,defaultordconsttype,true)
  1840. end
  1841. end
  1842. else
  1843. begin
  1844. consume(_INTCONST);
  1845. { check whether the value isn't in the longint range as well }
  1846. { (longint is easier to perform calculations with) (JM) }
  1847. if card <= $7fffffff then
  1848. { no sign extension necessary, so not longint typecast (JM) }
  1849. p1:=cordconstnode.create(card,s32bittype,true)
  1850. else
  1851. p1:=cordconstnode.create(card,u32bittype,true)
  1852. end;
  1853. end;
  1854. _REALNUMBER :
  1855. begin
  1856. val(pattern,d,code);
  1857. if code<>0 then
  1858. begin
  1859. Message(parser_e_error_in_real);
  1860. d:=1.0;
  1861. end;
  1862. consume(_REALNUMBER);
  1863. p1:=crealconstnode.create(d,pbestrealtype^);
  1864. end;
  1865. _STRING :
  1866. begin
  1867. string_dec(htype);
  1868. { STRING can be also a type cast }
  1869. if token=_LKLAMMER then
  1870. begin
  1871. consume(_LKLAMMER);
  1872. p1:=comp_expr(true);
  1873. consume(_RKLAMMER);
  1874. p1:=ctypeconvnode.create_explicit(p1,htype);
  1875. { handle postfix operators here e.g. string(a)[10] }
  1876. again:=true;
  1877. postfixoperators(p1,again);
  1878. end
  1879. else
  1880. p1:=ctypenode.create(htype);
  1881. end;
  1882. _FILE :
  1883. begin
  1884. htype:=cfiletype;
  1885. consume(_FILE);
  1886. { FILE can be also a type cast }
  1887. if token=_LKLAMMER then
  1888. begin
  1889. consume(_LKLAMMER);
  1890. p1:=comp_expr(true);
  1891. consume(_RKLAMMER);
  1892. p1:=ctypeconvnode.create_explicit(p1,htype);
  1893. { handle postfix operators here e.g. string(a)[10] }
  1894. again:=true;
  1895. postfixoperators(p1,again);
  1896. end
  1897. else
  1898. begin
  1899. p1:=ctypenode.create(htype);
  1900. end;
  1901. end;
  1902. _CSTRING :
  1903. begin
  1904. p1:=cstringconstnode.createstr(pattern,st_default);
  1905. consume(_CSTRING);
  1906. end;
  1907. _CCHAR :
  1908. begin
  1909. p1:=cordconstnode.create(ord(pattern[1]),cchartype,true);
  1910. consume(_CCHAR);
  1911. end;
  1912. _CWSTRING:
  1913. begin
  1914. p1:=cstringconstnode.createwstr(patternw);
  1915. consume(_CWSTRING);
  1916. end;
  1917. _CWCHAR:
  1918. begin
  1919. p1:=cordconstnode.create(ord(getcharwidestring(patternw,0)),cwidechartype,true);
  1920. consume(_CWCHAR);
  1921. end;
  1922. _KLAMMERAFFE :
  1923. begin
  1924. consume(_KLAMMERAFFE);
  1925. got_addrn:=true;
  1926. { support both @<x> and @(<x>) }
  1927. if try_to_consume(_LKLAMMER) then
  1928. begin
  1929. p1:=factor(true);
  1930. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1931. begin
  1932. again:=true;
  1933. postfixoperators(p1,again);
  1934. end;
  1935. consume(_RKLAMMER);
  1936. end
  1937. else
  1938. p1:=factor(true);
  1939. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1940. begin
  1941. again:=true;
  1942. postfixoperators(p1,again);
  1943. end;
  1944. got_addrn:=false;
  1945. p1:=caddrnode.create(p1);
  1946. { Store the procvar that we are expecting, the
  1947. addrn will use the information to find the correct
  1948. procdef or it will return an error }
  1949. if assigned(getprocvardef) and
  1950. (taddrnode(p1).left.nodetype = loadn) then
  1951. taddrnode(p1).getprocvardef:=getprocvardef;
  1952. end;
  1953. _LKLAMMER :
  1954. begin
  1955. consume(_LKLAMMER);
  1956. p1:=comp_expr(true);
  1957. consume(_RKLAMMER);
  1958. { it's not a good solution }
  1959. { but (a+b)^ makes some problems }
  1960. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1961. begin
  1962. again:=true;
  1963. postfixoperators(p1,again);
  1964. end;
  1965. end;
  1966. _LECKKLAMMER :
  1967. begin
  1968. consume(_LECKKLAMMER);
  1969. p1:=factor_read_set;
  1970. consume(_RECKKLAMMER);
  1971. end;
  1972. _PLUS :
  1973. begin
  1974. consume(_PLUS);
  1975. p1:=factor(false);
  1976. end;
  1977. _MINUS :
  1978. begin
  1979. consume(_MINUS);
  1980. p1:=sub_expr(oppower,false);
  1981. p1:=cunaryminusnode.create(p1);
  1982. end;
  1983. _OP_NOT :
  1984. begin
  1985. consume(_OP_NOT);
  1986. p1:=factor(false);
  1987. p1:=cnotnode.create(p1);
  1988. end;
  1989. _TRUE :
  1990. begin
  1991. consume(_TRUE);
  1992. p1:=cordconstnode.create(1,booltype,false);
  1993. end;
  1994. _FALSE :
  1995. begin
  1996. consume(_FALSE);
  1997. p1:=cordconstnode.create(0,booltype,false);
  1998. end;
  1999. _NIL :
  2000. begin
  2001. consume(_NIL);
  2002. p1:=cnilnode.create;
  2003. { It's really ugly code nil^, but delphi allows it }
  2004. if token in [_CARET] then
  2005. begin
  2006. again:=true;
  2007. postfixoperators(p1,again);
  2008. end;
  2009. end;
  2010. else
  2011. begin
  2012. p1:=cerrornode.create;
  2013. consume(token);
  2014. Message(cg_e_illegal_expression);
  2015. end;
  2016. end;
  2017. { generate error node if no node is created }
  2018. if not assigned(p1) then
  2019. begin
  2020. {$ifdef EXTDEBUG}
  2021. Comment(V_Warning,'factor: p1=nil');
  2022. {$endif}
  2023. p1:=cerrornode.create;
  2024. end;
  2025. { get the resulttype for the node }
  2026. if (not assigned(p1.resulttype.def)) then
  2027. do_resulttypepass(p1);
  2028. { tp7 procvar handling, but not if the next token
  2029. will be a := }
  2030. check_tp_procvar(p1);
  2031. factor:=p1;
  2032. check_tokenpos;
  2033. end;
  2034. {$ifdef fpc}
  2035. {$maxfpuregisters default}
  2036. {$endif fpc}
  2037. {****************************************************************************
  2038. Sub_Expr
  2039. ****************************************************************************}
  2040. const
  2041. { Warning these stay be ordered !! }
  2042. operator_levels:array[Toperator_precedence] of set of Ttoken=
  2043. ([_LT,_LTE,_GT,_GTE,_EQUAL,_UNEQUAL,_OP_IN,_OP_IS],
  2044. [_PLUS,_MINUS,_OP_OR,_OP_XOR],
  2045. [_CARET,_SYMDIF,_STARSTAR,_STAR,_SLASH,
  2046. _OP_AS,_OP_AND,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR],
  2047. [_STARSTAR] );
  2048. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;
  2049. {Reads a subexpression while the operators are of the current precedence
  2050. level, or any higher level. Replaces the old term, simpl_expr and
  2051. simpl2_expr.}
  2052. var
  2053. p1,p2 : tnode;
  2054. oldt : Ttoken;
  2055. filepos : tfileposinfo;
  2056. begin
  2057. if pred_level=highest_precedence then
  2058. p1:=factor(false)
  2059. else
  2060. p1:=sub_expr(succ(pred_level),true);
  2061. repeat
  2062. if (token in operator_levels[pred_level]) and
  2063. ((token<>_EQUAL) or accept_equal) then
  2064. begin
  2065. oldt:=token;
  2066. filepos:=akttokenpos;
  2067. consume(token);
  2068. if pred_level=highest_precedence then
  2069. p2:=factor(false)
  2070. else
  2071. p2:=sub_expr(succ(pred_level),true);
  2072. case oldt of
  2073. _PLUS :
  2074. p1:=caddnode.create(addn,p1,p2);
  2075. _MINUS :
  2076. p1:=caddnode.create(subn,p1,p2);
  2077. _STAR :
  2078. p1:=caddnode.create(muln,p1,p2);
  2079. _SLASH :
  2080. p1:=caddnode.create(slashn,p1,p2);
  2081. _EQUAL :
  2082. p1:=caddnode.create(equaln,p1,p2);
  2083. _GT :
  2084. p1:=caddnode.create(gtn,p1,p2);
  2085. _LT :
  2086. p1:=caddnode.create(ltn,p1,p2);
  2087. _GTE :
  2088. p1:=caddnode.create(gten,p1,p2);
  2089. _LTE :
  2090. p1:=caddnode.create(lten,p1,p2);
  2091. _SYMDIF :
  2092. p1:=caddnode.create(symdifn,p1,p2);
  2093. _STARSTAR :
  2094. p1:=caddnode.create(starstarn,p1,p2);
  2095. _OP_AS :
  2096. p1:=casnode.create(p1,p2);
  2097. _OP_IN :
  2098. p1:=cinnode.create(p1,p2);
  2099. _OP_IS :
  2100. p1:=cisnode.create(p1,p2);
  2101. _OP_OR :
  2102. p1:=caddnode.create(orn,p1,p2);
  2103. _OP_AND :
  2104. p1:=caddnode.create(andn,p1,p2);
  2105. _OP_DIV :
  2106. p1:=cmoddivnode.create(divn,p1,p2);
  2107. _OP_NOT :
  2108. p1:=cnotnode.create(p1);
  2109. _OP_MOD :
  2110. p1:=cmoddivnode.create(modn,p1,p2);
  2111. _OP_SHL :
  2112. p1:=cshlshrnode.create(shln,p1,p2);
  2113. _OP_SHR :
  2114. p1:=cshlshrnode.create(shrn,p1,p2);
  2115. _OP_XOR :
  2116. p1:=caddnode.create(xorn,p1,p2);
  2117. _ASSIGNMENT :
  2118. p1:=cassignmentnode.create(p1,p2);
  2119. _CARET :
  2120. p1:=caddnode.create(caretn,p1,p2);
  2121. _UNEQUAL :
  2122. p1:=caddnode.create(unequaln,p1,p2);
  2123. end;
  2124. p1.set_tree_filepos(filepos);
  2125. end
  2126. else
  2127. break;
  2128. until false;
  2129. sub_expr:=p1;
  2130. end;
  2131. function comp_expr(accept_equal : boolean):tnode;
  2132. var
  2133. oldafterassignment : boolean;
  2134. p1 : tnode;
  2135. begin
  2136. oldafterassignment:=afterassignment;
  2137. afterassignment:=true;
  2138. p1:=sub_expr(opcompare,accept_equal);
  2139. { get the resulttype for this expression }
  2140. if not assigned(p1.resulttype.def) then
  2141. do_resulttypepass(p1);
  2142. afterassignment:=oldafterassignment;
  2143. comp_expr:=p1;
  2144. end;
  2145. function expr : tnode;
  2146. var
  2147. p1,p2 : tnode;
  2148. oldafterassignment : boolean;
  2149. oldp1 : tnode;
  2150. filepos : tfileposinfo;
  2151. begin
  2152. oldafterassignment:=afterassignment;
  2153. p1:=sub_expr(opcompare,true);
  2154. { get the resulttype for this expression }
  2155. if not assigned(p1.resulttype.def) then
  2156. do_resulttypepass(p1);
  2157. filepos:=akttokenpos;
  2158. check_tp_procvar(p1);
  2159. if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
  2160. afterassignment:=true;
  2161. oldp1:=p1;
  2162. case token of
  2163. _POINTPOINT :
  2164. begin
  2165. consume(_POINTPOINT);
  2166. p2:=sub_expr(opcompare,true);
  2167. p1:=crangenode.create(p1,p2);
  2168. end;
  2169. _ASSIGNMENT :
  2170. begin
  2171. consume(_ASSIGNMENT);
  2172. if (p1.resulttype.def.deftype=procvardef) then
  2173. getprocvardef:=tprocvardef(p1.resulttype.def);
  2174. p2:=sub_expr(opcompare,true);
  2175. if assigned(getprocvardef) then
  2176. handle_procvar(getprocvardef,p2);
  2177. getprocvardef:=nil;
  2178. p1:=cassignmentnode.create(p1,p2);
  2179. end;
  2180. _PLUSASN :
  2181. begin
  2182. consume(_PLUSASN);
  2183. p2:=sub_expr(opcompare,true);
  2184. p1:=cassignmentnode.create(p1,caddnode.create(addn,p1.getcopy,p2));
  2185. end;
  2186. _MINUSASN :
  2187. begin
  2188. consume(_MINUSASN);
  2189. p2:=sub_expr(opcompare,true);
  2190. p1:=cassignmentnode.create(p1,caddnode.create(subn,p1.getcopy,p2));
  2191. end;
  2192. _STARASN :
  2193. begin
  2194. consume(_STARASN );
  2195. p2:=sub_expr(opcompare,true);
  2196. p1:=cassignmentnode.create(p1,caddnode.create(muln,p1.getcopy,p2));
  2197. end;
  2198. _SLASHASN :
  2199. begin
  2200. consume(_SLASHASN );
  2201. p2:=sub_expr(opcompare,true);
  2202. p1:=cassignmentnode.create(p1,caddnode.create(slashn,p1.getcopy,p2));
  2203. end;
  2204. end;
  2205. { get the resulttype for this expression }
  2206. if not assigned(p1.resulttype.def) then
  2207. do_resulttypepass(p1);
  2208. afterassignment:=oldafterassignment;
  2209. if p1<>oldp1 then
  2210. p1.set_tree_filepos(filepos);
  2211. expr:=p1;
  2212. end;
  2213. {$ifdef int64funcresok}
  2214. function get_intconst:TConstExprInt;
  2215. {$else int64funcresok}
  2216. function get_intconst:longint;
  2217. {$endif int64funcresok}
  2218. {Reads an expression, tries to evalute it and check if it is an integer
  2219. constant. Then the constant is returned.}
  2220. var
  2221. p:tnode;
  2222. begin
  2223. p:=comp_expr(true);
  2224. if not codegenerror then
  2225. begin
  2226. if (p.nodetype<>ordconstn) or
  2227. not(is_integer(p.resulttype.def)) then
  2228. Message(cg_e_illegal_expression)
  2229. else
  2230. get_intconst:=tordconstnode(p).value;
  2231. end;
  2232. p.free;
  2233. end;
  2234. function get_stringconst:string;
  2235. {Reads an expression, tries to evaluate it and checks if it is a string
  2236. constant. Then the constant is returned.}
  2237. var
  2238. p:tnode;
  2239. begin
  2240. get_stringconst:='';
  2241. p:=comp_expr(true);
  2242. if p.nodetype<>stringconstn then
  2243. begin
  2244. if (p.nodetype=ordconstn) and is_char(p.resulttype.def) then
  2245. get_stringconst:=char(tordconstnode(p).value)
  2246. else
  2247. Message(cg_e_illegal_expression);
  2248. end
  2249. else
  2250. get_stringconst:=strpas(tstringconstnode(p).value_str);
  2251. p.free;
  2252. end;
  2253. end.
  2254. {
  2255. $Log$
  2256. Revision 1.124 2003-08-10 17:25:23 peter
  2257. * fixed some reported bugs
  2258. Revision 1.123 2003/06/13 21:19:31 peter
  2259. * current_procdef removed, use current_procinfo.procdef instead
  2260. Revision 1.122 2003/06/03 21:02:57 peter
  2261. * don't set nf_member when loaded from with symtable
  2262. * allow static variables in class methods
  2263. Revision 1.121 2003/05/22 17:43:21 peter
  2264. * search defaulthandler only for message methods
  2265. Revision 1.120 2003/05/15 18:58:53 peter
  2266. * removed selfpointer_offset, vmtpointer_offset
  2267. * tvarsym.adjusted_address
  2268. * address in localsymtable is now in the real direction
  2269. * removed some obsolete globals
  2270. Revision 1.119 2003/05/13 20:54:39 peter
  2271. * ifdef'd code that checked for failed inherited constructors
  2272. Revision 1.118 2003/05/13 19:14:41 peter
  2273. * failn removed
  2274. * inherited result code check moven to pexpr
  2275. Revision 1.117 2003/05/11 21:37:03 peter
  2276. * moved implicit exception frame from ncgutil to psub
  2277. * constructor/destructor helpers moved from cobj/ncgutil to psub
  2278. Revision 1.116 2003/05/11 14:45:12 peter
  2279. * tloadnode does not support objectsymtable,withsymtable anymore
  2280. * withnode cleanup
  2281. * direct with rewritten to use temprefnode
  2282. Revision 1.115 2003/05/09 17:47:03 peter
  2283. * self moved to hidden parameter
  2284. * removed hdisposen,hnewn,selfn
  2285. Revision 1.114 2003/05/01 07:59:42 florian
  2286. * introduced defaultordconsttype to decribe the default size of ordinal constants
  2287. on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
  2288. + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
  2289. * int64s/qwords are allowed as for loop counter on 64 bit CPUs
  2290. Revision 1.113 2003/04/27 11:21:33 peter
  2291. * aktprocdef renamed to current_procinfo.procdef
  2292. * procinfo renamed to current_procinfo
  2293. * procinfo will now be stored in current_module so it can be
  2294. cleaned up properly
  2295. * gen_main_procsym changed to create_main_proc and release_main_proc
  2296. to also generate a tprocinfo structure
  2297. * fixed unit implicit initfinal
  2298. Revision 1.112 2003/04/27 07:29:50 peter
  2299. * current_procinfo.procdef cleanup, current_procdef is now always nil when parsing
  2300. a new procdef declaration
  2301. * aktprocsym removed
  2302. * lexlevel removed, use symtable.symtablelevel instead
  2303. * implicit init/final code uses the normal genentry/genexit
  2304. * funcret state checking updated for new funcret handling
  2305. Revision 1.111 2003/04/26 00:33:07 peter
  2306. * vo_is_result flag added for the special RESULT symbol
  2307. Revision 1.110 2003/04/25 20:59:33 peter
  2308. * removed funcretn,funcretsym, function result is now in varsym
  2309. and aliases for result and function name are added using absolutesym
  2310. * vs_hidden parameter for funcret passed in parameter
  2311. * vs_hidden fixes
  2312. * writenode changed to printnode and released from extdebug
  2313. * -vp option added to generate a tree.log with the nodetree
  2314. * nicer printnode for statements, callnode
  2315. Revision 1.109 2003/04/23 10:13:55 peter
  2316. * firstaddr will check procvardef
  2317. Revision 1.108 2003/04/22 23:50:23 peter
  2318. * firstpass uses expectloc
  2319. * checks if there are differences between the expectloc and
  2320. location.loc from secondpass in EXTDEBUG
  2321. Revision 1.107 2003/04/11 15:49:01 peter
  2322. * default property also increased the reference count for the
  2323. property symbol
  2324. Revision 1.106 2003/04/11 14:50:08 peter
  2325. * fix tw2454
  2326. Revision 1.105 2003/03/27 17:44:13 peter
  2327. * fixed small mem leaks
  2328. Revision 1.104 2003/03/17 18:55:30 peter
  2329. * allow more tokens instead of only semicolon after inherited
  2330. Revision 1.103 2003/03/17 16:54:41 peter
  2331. * support DefaultHandler and anonymous inheritance fixed
  2332. for message methods
  2333. Revision 1.102 2003/01/30 21:46:57 peter
  2334. * self fixes for static methods (merged)
  2335. Revision 1.101 2003/01/16 22:12:22 peter
  2336. * Find the correct procvar to load when using @ in fpc mode
  2337. Revision 1.100 2003/01/15 01:44:32 peter
  2338. * merged methodpointer fixes from 1.0.x
  2339. Revision 1.98 2003/01/12 17:51:42 peter
  2340. * tp procvar handling fix for tb0448
  2341. Revision 1.97 2003/01/05 22:44:14 peter
  2342. * remove a lot of code to support typen in loadn-procsym
  2343. Revision 1.96 2002/12/11 22:40:36 peter
  2344. * assigned(procvar) fix for delphi mode, fixes tb0430
  2345. Revision 1.95 2002/11/30 11:12:48 carl
  2346. + checking for symbols used with hint directives is done mostly in pexpr
  2347. only now
  2348. Revision 1.94 2002/11/27 15:33:47 peter
  2349. * the never ending story of tp procvar hacks
  2350. Revision 1.93 2002/11/26 22:58:24 peter
  2351. * fix for tw2178. When a ^ or . follows a procsym then the procsym
  2352. needs to be called
  2353. Revision 1.92 2002/11/25 17:43:22 peter
  2354. * splitted defbase in defutil,symutil,defcmp
  2355. * merged isconvertable and is_equal into compare_defs(_ext)
  2356. * made operator search faster by walking the list only once
  2357. Revision 1.91 2002/11/22 22:48:10 carl
  2358. * memory optimization with tconstsym (1.5%)
  2359. Revision 1.90 2002/11/20 22:49:55 pierre
  2360. * commented check code tht was invalid in 1.1
  2361. Revision 1.89 2002/11/18 18:34:41 peter
  2362. * fix crash with EXTDEBUG code
  2363. Revision 1.88 2002/11/18 17:48:21 peter
  2364. * fix tw2209 (merged)
  2365. Revision 1.87 2002/11/18 17:31:58 peter
  2366. * pass proccalloption to ret_in_xxx and push_xxx functions
  2367. Revision 1.86 2002/10/05 00:48:57 peter
  2368. * support inherited; support for overload as it is handled by
  2369. delphi. This is only for delphi mode as it is working is
  2370. undocumented and hard to predict what is done
  2371. Revision 1.85 2002/10/04 21:13:59 peter
  2372. * ignore vecn,subscriptn when checking for a procvar loadn
  2373. Revision 1.84 2002/10/02 20:51:22 peter
  2374. * don't check interfaces for class methods
  2375. Revision 1.83 2002/10/02 18:20:52 peter
  2376. * Copy() is now internal syssym that calls compilerprocs
  2377. Revision 1.82 2002/09/30 07:00:48 florian
  2378. * fixes to common code to get the alpha compiler compiled applied
  2379. Revision 1.81 2002/09/16 19:06:14 peter
  2380. * allow ^ after nil
  2381. Revision 1.80 2002/09/07 15:25:07 peter
  2382. * old logs removed and tabs fixed
  2383. Revision 1.79 2002/09/07 12:16:03 carl
  2384. * second part bug report 1996 fix, testrange in cordconstnode
  2385. only called if option is set (also make parsing a tiny faster)
  2386. Revision 1.78 2002/09/03 16:26:27 daniel
  2387. * Make Tprocdef.defs protected
  2388. Revision 1.77 2002/08/18 20:06:24 peter
  2389. * inlining is now also allowed in interface
  2390. * renamed write/load to ppuwrite/ppuload
  2391. * tnode storing in ppu
  2392. * nld,ncon,nbas are already updated for storing in ppu
  2393. Revision 1.76 2002/08/17 09:23:39 florian
  2394. * first part of procinfo rewrite
  2395. Revision 1.75 2002/08/01 16:37:47 jonas
  2396. - removed some superfluous "in_paras := true" statements
  2397. Revision 1.74 2002/07/26 21:15:41 florian
  2398. * rewrote the system handling
  2399. Revision 1.73 2002/07/23 09:51:23 daniel
  2400. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2401. are worth comitting.
  2402. Revision 1.72 2002/07/20 11:57:55 florian
  2403. * types.pas renamed to defbase.pas because D6 contains a types
  2404. unit so this would conflicts if D6 programms are compiled
  2405. + Willamette/SSE2 instructions to assembler added
  2406. Revision 1.71 2002/07/16 15:34:20 florian
  2407. * exit is now a syssym instead of a keyword
  2408. Revision 1.70 2002/07/06 20:18:02 carl
  2409. * longstring declaration now gives parser error since its not supported!
  2410. Revision 1.69 2002/06/12 15:46:14 jonas
  2411. * fixed web bug 1995
  2412. Revision 1.68 2002/05/18 13:34:12 peter
  2413. * readded missing revisions
  2414. Revision 1.67 2002/05/16 19:46:43 carl
  2415. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  2416. + try to fix temp allocation (still in ifdef)
  2417. + generic constructor calls
  2418. + start of tassembler / tmodulebase class cleanup
  2419. Revision 1.65 2002/05/12 16:53:09 peter
  2420. * moved entry and exitcode to ncgutil and cgobj
  2421. * foreach gets extra argument for passing local data to the
  2422. iterator function
  2423. * -CR checks also class typecasts at runtime by changing them
  2424. into as
  2425. * fixed compiler to cycle with the -CR option
  2426. * fixed stabs with elf writer, finally the global variables can
  2427. be watched
  2428. * removed a lot of routines from cga unit and replaced them by
  2429. calls to cgobj
  2430. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  2431. u32bit then the other is typecasted also to u32bit without giving
  2432. a rangecheck warning/error.
  2433. * fixed pascal calling method with reversing also the high tree in
  2434. the parast, detected by tcalcst3 test
  2435. Revision 1.64 2002/04/23 19:16:34 peter
  2436. * add pinline unit that inserts compiler supported functions using
  2437. one or more statements
  2438. * moved finalize and setlength from ninl to pinline
  2439. Revision 1.63 2002/04/21 19:02:05 peter
  2440. * removed newn and disposen nodes, the code is now directly
  2441. inlined from pexpr
  2442. * -an option that will write the secondpass nodes to the .s file, this
  2443. requires EXTDEBUG define to actually write the info
  2444. * fixed various internal errors and crashes due recent code changes
  2445. Revision 1.62 2002/04/16 16:11:17 peter
  2446. * using inherited; without a parent having the same function
  2447. will do nothing like delphi
  2448. Revision 1.61 2002/04/07 13:31:36 carl
  2449. + change unit use
  2450. Revision 1.60 2002/04/01 20:57:13 jonas
  2451. * fixed web bug 1907
  2452. * fixed some other procvar related bugs (all related to accepting procvar
  2453. constructs with either too many or too little parameters)
  2454. (both merged, includes second typo fix of pexpr.pas)
  2455. Revision 1.59 2002/03/31 20:26:35 jonas
  2456. + a_loadfpu_* and a_loadmm_* methods in tcg
  2457. * register allocation is now handled by a class and is mostly processor
  2458. independent (+rgobj.pas and i386/rgcpu.pas)
  2459. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  2460. * some small improvements and fixes to the optimizer
  2461. * some register allocation fixes
  2462. * some fpuvaroffset fixes in the unary minus node
  2463. * push/popusedregisters is now called rg.save/restoreusedregisters and
  2464. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  2465. also better optimizable)
  2466. * fixed and optimized register saving/restoring for new/dispose nodes
  2467. * LOC_FPU locations now also require their "register" field to be set to
  2468. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  2469. - list field removed of the tnode class because it's not used currently
  2470. and can cause hard-to-find bugs
  2471. }