pexpr.pas 91 KB

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