pexpr.pas 90 KB

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