pexpr.pas 97 KB

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