pexpr.pas 89 KB

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