pexpr.pas 83 KB

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