pexpr.pas 92 KB

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