pexpr.pas 96 KB

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