pexpr.pas 93 KB

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