pexpr.pas 96 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696
  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. Message1(sym_e_id_no_member,hs);
  1843. again:=false;
  1844. p1:=cerrornode.create;
  1845. end;
  1846. { turn auto inheriting off }
  1847. auto_inherited:=false;
  1848. end
  1849. else
  1850. begin
  1851. Message(parser_e_generic_methods_only_in_methods);
  1852. again:=false;
  1853. p1:=cerrornode.create;
  1854. end;
  1855. postfixoperators(p1,again);
  1856. end;
  1857. _INTCONST :
  1858. begin
  1859. { try cardinal first }
  1860. val(pattern,card,code);
  1861. if code<>0 then
  1862. begin
  1863. { then longint }
  1864. valint(pattern,l,code);
  1865. if code <> 0 then
  1866. begin
  1867. { then int64 }
  1868. val(pattern,ic,code);
  1869. if code<>0 then
  1870. begin
  1871. {finally float }
  1872. val(pattern,d,code);
  1873. if code<>0 then
  1874. begin
  1875. Message(cg_e_invalid_integer);
  1876. consume(_INTCONST);
  1877. l:=1;
  1878. p1:=cordconstnode.create(l,s32bittype);
  1879. end
  1880. else
  1881. begin
  1882. consume(_INTCONST);
  1883. p1:=crealconstnode.create(d,pbestrealtype^);
  1884. end;
  1885. end
  1886. else
  1887. begin
  1888. consume(_INTCONST);
  1889. p1:=cordconstnode.create(ic,cs64bittype);
  1890. end
  1891. end
  1892. else
  1893. begin
  1894. consume(_INTCONST);
  1895. p1:=cordconstnode.create(l,s32bittype)
  1896. end
  1897. end
  1898. else
  1899. begin
  1900. consume(_INTCONST);
  1901. { check whether the value isn't in the longint range as well }
  1902. { (longint is easier to perform calculations with) (JM) }
  1903. if card <= $7fffffff then
  1904. { no sign extension necessary, so not longint typecast (JM) }
  1905. p1:=cordconstnode.create(card,s32bittype)
  1906. else
  1907. p1:=cordconstnode.create(card,u32bittype)
  1908. end;
  1909. end;
  1910. _REALNUMBER :
  1911. begin
  1912. val(pattern,d,code);
  1913. if code<>0 then
  1914. begin
  1915. Message(parser_e_error_in_real);
  1916. d:=1.0;
  1917. end;
  1918. consume(_REALNUMBER);
  1919. p1:=crealconstnode.create(d,pbestrealtype^);
  1920. end;
  1921. _STRING :
  1922. begin
  1923. string_dec(htype);
  1924. { STRING can be also a type cast }
  1925. if token=_LKLAMMER then
  1926. begin
  1927. consume(_LKLAMMER);
  1928. p1:=comp_expr(true);
  1929. consume(_RKLAMMER);
  1930. p1:=ctypeconvnode.create(p1,htype);
  1931. include(p1.flags,nf_explizit);
  1932. { handle postfix operators here e.g. string(a)[10] }
  1933. again:=true;
  1934. postfixoperators(p1,again);
  1935. end
  1936. else
  1937. p1:=ctypenode.create(htype);
  1938. end;
  1939. _FILE :
  1940. begin
  1941. htype:=cfiletype;
  1942. consume(_FILE);
  1943. { FILE can be also a type cast }
  1944. if token=_LKLAMMER then
  1945. begin
  1946. consume(_LKLAMMER);
  1947. p1:=comp_expr(true);
  1948. consume(_RKLAMMER);
  1949. p1:=ctypeconvnode.create(p1,htype);
  1950. include(p1.flags,nf_explizit);
  1951. { handle postfix operators here e.g. string(a)[10] }
  1952. again:=true;
  1953. postfixoperators(p1,again);
  1954. end
  1955. else
  1956. begin
  1957. p1:=ctypenode.create(htype);
  1958. end;
  1959. end;
  1960. _CSTRING :
  1961. begin
  1962. p1:=cstringconstnode.createstr(pattern,st_default);
  1963. consume(_CSTRING);
  1964. end;
  1965. _CCHAR :
  1966. begin
  1967. p1:=cordconstnode.create(ord(pattern[1]),cchartype);
  1968. consume(_CCHAR);
  1969. end;
  1970. _CWSTRING:
  1971. begin
  1972. p1:=cstringconstnode.createwstr(patternw);
  1973. consume(_CWSTRING);
  1974. end;
  1975. _CWCHAR:
  1976. begin
  1977. p1:=cordconstnode.create(ord(getcharwidestring(patternw,0)),cwidechartype);
  1978. consume(_CWCHAR);
  1979. end;
  1980. _KLAMMERAFFE :
  1981. begin
  1982. consume(_KLAMMERAFFE);
  1983. got_addrn:=true;
  1984. { support both @<x> and @(<x>) }
  1985. if token=_LKLAMMER then
  1986. begin
  1987. consume(_LKLAMMER);
  1988. p1:=factor(true);
  1989. consume(_RKLAMMER);
  1990. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1991. begin
  1992. again:=true;
  1993. postfixoperators(p1,again);
  1994. end;
  1995. end
  1996. else
  1997. p1:=factor(true);
  1998. got_addrn:=false;
  1999. p1:=caddrnode.create(p1);
  2000. if assigned(getprocvardef) then
  2001. taddrnode(p1).getprocvardef:=getprocvardef;
  2002. end;
  2003. _LKLAMMER :
  2004. begin
  2005. consume(_LKLAMMER);
  2006. p1:=comp_expr(true);
  2007. consume(_RKLAMMER);
  2008. { it's not a good solution }
  2009. { but (a+b)^ makes some problems }
  2010. if token in [_CARET,_POINT,_LECKKLAMMER] then
  2011. begin
  2012. again:=true;
  2013. postfixoperators(p1,again);
  2014. end;
  2015. end;
  2016. _LECKKLAMMER :
  2017. begin
  2018. consume(_LECKKLAMMER);
  2019. p1:=factor_read_set;
  2020. consume(_RECKKLAMMER);
  2021. end;
  2022. _PLUS :
  2023. begin
  2024. consume(_PLUS);
  2025. p1:=factor(false);
  2026. end;
  2027. _MINUS :
  2028. begin
  2029. consume(_MINUS);
  2030. p1:=sub_expr(oppower,false);
  2031. p1:=cunaryminusnode.create(p1);
  2032. end;
  2033. _OP_NOT :
  2034. begin
  2035. consume(_OP_NOT);
  2036. p1:=factor(false);
  2037. p1:=cnotnode.create(p1);
  2038. end;
  2039. _TRUE :
  2040. begin
  2041. consume(_TRUE);
  2042. p1:=cordconstnode.create(1,booltype);
  2043. end;
  2044. _FALSE :
  2045. begin
  2046. consume(_FALSE);
  2047. p1:=cordconstnode.create(0,booltype);
  2048. end;
  2049. _NIL :
  2050. begin
  2051. consume(_NIL);
  2052. p1:=cnilnode.create;
  2053. end;
  2054. else
  2055. begin
  2056. p1:=cerrornode.create;
  2057. consume(token);
  2058. Message(cg_e_illegal_expression);
  2059. end;
  2060. end;
  2061. { generate error node if no node is created }
  2062. if not assigned(p1) then
  2063. begin
  2064. {$ifdef EXTDEBUG}
  2065. Comment(V_Warning,'factor: p1=nil');
  2066. {$endif}
  2067. p1:=cerrornode.create;
  2068. end;
  2069. { get the resulttype for the node }
  2070. if (not assigned(p1.resulttype.def)) then
  2071. do_resulttypepass(p1);
  2072. { tp7 procvar handling, but not if the next token
  2073. will be a := }
  2074. if (m_tp_procvar in aktmodeswitches) and
  2075. (token<>_ASSIGNMENT) then
  2076. check_tp_procvar(p1);
  2077. factor:=p1;
  2078. check_tokenpos;
  2079. end;
  2080. {$ifdef fpc}
  2081. {$maxfpuregisters default}
  2082. {$endif fpc}
  2083. {****************************************************************************
  2084. Sub_Expr
  2085. ****************************************************************************}
  2086. const
  2087. { Warning these stay be ordered !! }
  2088. operator_levels:array[Toperator_precedence] of set of Ttoken=
  2089. ([_LT,_LTE,_GT,_GTE,_EQUAL,_UNEQUAL,_OP_IN,_OP_IS],
  2090. [_PLUS,_MINUS,_OP_OR,_OP_XOR],
  2091. [_CARET,_SYMDIF,_STARSTAR,_STAR,_SLASH,
  2092. _OP_AS,_OP_AND,_OP_DIV,_OP_MOD,_OP_SHL,_OP_SHR],
  2093. [_STARSTAR] );
  2094. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):tnode;
  2095. {Reads a subexpression while the operators are of the current precedence
  2096. level, or any higher level. Replaces the old term, simpl_expr and
  2097. simpl2_expr.}
  2098. var
  2099. p1,p2 : tnode;
  2100. oldt : Ttoken;
  2101. filepos : tfileposinfo;
  2102. begin
  2103. if pred_level=highest_precedence then
  2104. p1:=factor(false)
  2105. else
  2106. p1:=sub_expr(succ(pred_level),true);
  2107. repeat
  2108. if (token in operator_levels[pred_level]) and
  2109. ((token<>_EQUAL) or accept_equal) then
  2110. begin
  2111. oldt:=token;
  2112. filepos:=akttokenpos;
  2113. consume(token);
  2114. if pred_level=highest_precedence then
  2115. p2:=factor(false)
  2116. else
  2117. p2:=sub_expr(succ(pred_level),true);
  2118. case oldt of
  2119. _PLUS :
  2120. p1:=caddnode.create(addn,p1,p2);
  2121. _MINUS :
  2122. p1:=caddnode.create(subn,p1,p2);
  2123. _STAR :
  2124. p1:=caddnode.create(muln,p1,p2);
  2125. _SLASH :
  2126. p1:=caddnode.create(slashn,p1,p2);
  2127. _EQUAL :
  2128. p1:=caddnode.create(equaln,p1,p2);
  2129. _GT :
  2130. p1:=caddnode.create(gtn,p1,p2);
  2131. _LT :
  2132. p1:=caddnode.create(ltn,p1,p2);
  2133. _GTE :
  2134. p1:=caddnode.create(gten,p1,p2);
  2135. _LTE :
  2136. p1:=caddnode.create(lten,p1,p2);
  2137. _SYMDIF :
  2138. p1:=caddnode.create(symdifn,p1,p2);
  2139. _STARSTAR :
  2140. p1:=caddnode.create(starstarn,p1,p2);
  2141. _OP_AS :
  2142. p1:=casnode.create(p1,p2);
  2143. _OP_IN :
  2144. p1:=cinnode.create(p1,p2);
  2145. _OP_IS :
  2146. p1:=cisnode.create(p1,p2);
  2147. _OP_OR :
  2148. p1:=caddnode.create(orn,p1,p2);
  2149. _OP_AND :
  2150. p1:=caddnode.create(andn,p1,p2);
  2151. _OP_DIV :
  2152. p1:=cmoddivnode.create(divn,p1,p2);
  2153. _OP_NOT :
  2154. p1:=cnotnode.create(p1);
  2155. _OP_MOD :
  2156. p1:=cmoddivnode.create(modn,p1,p2);
  2157. _OP_SHL :
  2158. p1:=cshlshrnode.create(shln,p1,p2);
  2159. _OP_SHR :
  2160. p1:=cshlshrnode.create(shrn,p1,p2);
  2161. _OP_XOR :
  2162. p1:=caddnode.create(xorn,p1,p2);
  2163. _ASSIGNMENT :
  2164. p1:=cassignmentnode.create(p1,p2);
  2165. _CARET :
  2166. p1:=caddnode.create(caretn,p1,p2);
  2167. _UNEQUAL :
  2168. p1:=caddnode.create(unequaln,p1,p2);
  2169. end;
  2170. p1.set_tree_filepos(filepos);
  2171. end
  2172. else
  2173. break;
  2174. until false;
  2175. sub_expr:=p1;
  2176. end;
  2177. function comp_expr(accept_equal : boolean):tnode;
  2178. var
  2179. oldafterassignment : boolean;
  2180. p1 : tnode;
  2181. begin
  2182. oldafterassignment:=afterassignment;
  2183. afterassignment:=true;
  2184. p1:=sub_expr(opcompare,accept_equal);
  2185. { get the resulttype for this expression }
  2186. if not assigned(p1.resulttype.def) then
  2187. do_resulttypepass(p1);
  2188. afterassignment:=oldafterassignment;
  2189. comp_expr:=p1;
  2190. end;
  2191. function expr : tnode;
  2192. var
  2193. p1,p2 : tnode;
  2194. oldafterassignment : boolean;
  2195. oldp1 : tnode;
  2196. filepos : tfileposinfo;
  2197. begin
  2198. oldafterassignment:=afterassignment;
  2199. p1:=sub_expr(opcompare,true);
  2200. { get the resulttype for this expression }
  2201. if not assigned(p1.resulttype.def) then
  2202. do_resulttypepass(p1);
  2203. filepos:=akttokenpos;
  2204. if (m_tp_procvar in aktmodeswitches) and
  2205. (token<>_ASSIGNMENT) then
  2206. check_tp_procvar(p1);
  2207. if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
  2208. afterassignment:=true;
  2209. oldp1:=p1;
  2210. case token of
  2211. _POINTPOINT :
  2212. begin
  2213. consume(_POINTPOINT);
  2214. p2:=sub_expr(opcompare,true);
  2215. p1:=crangenode.create(p1,p2);
  2216. end;
  2217. _ASSIGNMENT :
  2218. begin
  2219. consume(_ASSIGNMENT);
  2220. if (p1.resulttype.def.deftype=procvardef) then
  2221. getprocvardef:=tprocvardef(p1.resulttype.def);
  2222. p2:=sub_expr(opcompare,true);
  2223. if assigned(getprocvardef) then
  2224. handle_procvar(getprocvardef,p2,true);
  2225. getprocvardef:=nil;
  2226. p1:=cassignmentnode.create(p1,p2);
  2227. end;
  2228. _PLUSASN :
  2229. begin
  2230. consume(_PLUSASN);
  2231. p2:=sub_expr(opcompare,true);
  2232. p1:=cassignmentnode.create(p1,caddnode.create(addn,p1.getcopy,p2));
  2233. end;
  2234. _MINUSASN :
  2235. begin
  2236. consume(_MINUSASN);
  2237. p2:=sub_expr(opcompare,true);
  2238. p1:=cassignmentnode.create(p1,caddnode.create(subn,p1.getcopy,p2));
  2239. end;
  2240. _STARASN :
  2241. begin
  2242. consume(_STARASN );
  2243. p2:=sub_expr(opcompare,true);
  2244. p1:=cassignmentnode.create(p1,caddnode.create(muln,p1.getcopy,p2));
  2245. end;
  2246. _SLASHASN :
  2247. begin
  2248. consume(_SLASHASN );
  2249. p2:=sub_expr(opcompare,true);
  2250. p1:=cassignmentnode.create(p1,caddnode.create(slashn,p1.getcopy,p2));
  2251. end;
  2252. end;
  2253. { get the resulttype for this expression }
  2254. if not assigned(p1.resulttype.def) then
  2255. do_resulttypepass(p1);
  2256. afterassignment:=oldafterassignment;
  2257. if p1<>oldp1 then
  2258. p1.set_tree_filepos(filepos);
  2259. expr:=p1;
  2260. end;
  2261. {$ifdef int64funcresok}
  2262. function get_intconst:TConstExprInt;
  2263. {$else int64funcresok}
  2264. function get_intconst:longint;
  2265. {$endif int64funcresok}
  2266. {Reads an expression, tries to evalute it and check if it is an integer
  2267. constant. Then the constant is returned.}
  2268. var
  2269. p:tnode;
  2270. begin
  2271. p:=comp_expr(true);
  2272. if not codegenerror then
  2273. begin
  2274. if (p.nodetype<>ordconstn) or
  2275. not(is_integer(p.resulttype.def)) then
  2276. Message(cg_e_illegal_expression)
  2277. else
  2278. get_intconst:=tordconstnode(p).value;
  2279. end;
  2280. p.free;
  2281. end;
  2282. function get_stringconst:string;
  2283. {Reads an expression, tries to evaluate it and checks if it is a string
  2284. constant. Then the constant is returned.}
  2285. var
  2286. p:tnode;
  2287. begin
  2288. get_stringconst:='';
  2289. p:=comp_expr(true);
  2290. if p.nodetype<>stringconstn then
  2291. begin
  2292. if (p.nodetype=ordconstn) and is_char(p.resulttype.def) then
  2293. get_stringconst:=char(tordconstnode(p).value)
  2294. else
  2295. Message(cg_e_illegal_expression);
  2296. end
  2297. else
  2298. get_stringconst:=strpas(tstringconstnode(p).value_str);
  2299. p.free;
  2300. end;
  2301. end.
  2302. {
  2303. $Log$
  2304. Revision 1.61 2002-04-07 13:31:36 carl
  2305. + change unit use
  2306. Revision 1.60 2002/04/01 20:57:13 jonas
  2307. * fixed web bug 1907
  2308. * fixed some other procvar related bugs (all related to accepting procvar
  2309. constructs with either too many or too little parameters)
  2310. (both merged, includes second typo fix of pexpr.pas)
  2311. Revision 1.59 2002/03/31 20:26:35 jonas
  2312. + a_loadfpu_* and a_loadmm_* methods in tcg
  2313. * register allocation is now handled by a class and is mostly processor
  2314. independent (+rgobj.pas and i386/rgcpu.pas)
  2315. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  2316. * some small improvements and fixes to the optimizer
  2317. * some register allocation fixes
  2318. * some fpuvaroffset fixes in the unary minus node
  2319. * push/popusedregisters is now called rg.save/restoreusedregisters and
  2320. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  2321. also better optimizable)
  2322. * fixed and optimized register saving/restoring for new/dispose nodes
  2323. * LOC_FPU locations now also require their "register" field to be set to
  2324. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  2325. - list field removed of the tnode class because it's not used currently
  2326. and can cause hard-to-find bugs
  2327. Revision 1.58 2002/03/01 14:08:26 peter
  2328. * fixed sizeof(TClass) to return only 4
  2329. Revision 1.57 2002/02/03 09:30:04 peter
  2330. * more fixes for protected handling
  2331. Revision 1.56 2002/01/29 21:25:22 peter
  2332. * more checks for private and protected
  2333. Revision 1.55 2002/01/24 18:25:49 peter
  2334. * implicit result variable generation for assembler routines
  2335. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  2336. Revision 1.54 2002/01/06 21:47:32 peter
  2337. * removed getprocvar, use only getprocvardef
  2338. Revision 1.53 2001/12/31 16:59:42 peter
  2339. * protected/private symbols parsing fixed
  2340. Revision 1.52 2001/12/06 17:57:36 florian
  2341. + parasym to tparaitem added
  2342. Revision 1.51 2001/11/14 01:12:44 florian
  2343. * variant paramter passing and functions results fixed
  2344. Revision 1.50 2001/11/02 23:16:51 peter
  2345. * removed obsolete chainprocsym and test_procsym code
  2346. Revision 1.49 2001/11/02 22:58:05 peter
  2347. * procsym definition rewrite
  2348. Revision 1.48 2001/10/28 17:22:25 peter
  2349. * allow assignment of overloaded procedures to procvars when we know
  2350. which procedure to take
  2351. Revision 1.47 2001/10/24 11:51:39 marco
  2352. * Make new/dispose system functions instead of keywords
  2353. Revision 1.46 2001/10/21 13:10:51 peter
  2354. * better support for indexed properties
  2355. Revision 1.45 2001/10/21 12:33:07 peter
  2356. * array access for properties added
  2357. Revision 1.44 2001/10/20 19:28:39 peter
  2358. * interface 2 guid support
  2359. * guid constants support
  2360. Revision 1.43 2001/10/18 16:30:38 jonas
  2361. * property parameters are now fully parsed by the firstcall code to
  2362. check for the correct amount and types (merged)
  2363. Revision 1.42 2001/09/02 21:18:28 peter
  2364. * split constsym.value in valueord,valueordptr,valueptr. The valueordptr
  2365. is used for holding target platform pointer values. As those can be
  2366. bigger than the source platform.
  2367. Revision 1.41 2001/08/26 13:36:45 florian
  2368. * some cg reorganisation
  2369. * some PPC updates
  2370. Revision 1.40 2001/08/22 21:16:21 florian
  2371. * some interfaces related problems regarding
  2372. mapping of interface implementions fixed
  2373. Revision 1.39 2001/08/06 21:40:47 peter
  2374. * funcret moved from tprocinfo to tprocdef
  2375. Revision 1.38 2001/07/09 21:15:41 peter
  2376. * Length made internal
  2377. * Add array support for Length
  2378. Revision 1.37 2001/06/29 14:16:57 jonas
  2379. * fixed inconsistent handling of procvars in FPC mode (sometimes @ was
  2380. required to assign the address of a procedure to a procvar, sometimes
  2381. not. Now it is always required) (merged)
  2382. Revision 1.36 2001/06/04 18:16:42 peter
  2383. * fixed tp procvar support in parameters of a called procvar
  2384. * typenode cleanup, no special handling needed anymore for bt_type
  2385. Revision 1.35 2001/06/04 11:45:35 peter
  2386. * parse const after .. using bt_const block to allow expressions, this
  2387. is Delphi compatible
  2388. Revision 1.34 2001/05/19 21:15:53 peter
  2389. * allow typenodes for typeinfo and typeof
  2390. * tp procvar fixes for properties
  2391. Revision 1.33 2001/05/19 12:23:59 peter
  2392. * fixed crash with auto dereferencing
  2393. Revision 1.32 2001/05/09 19:52:51 peter
  2394. * removed unused allow_type
  2395. Revision 1.31 2001/05/04 15:52:03 florian
  2396. * some Delphi incompatibilities fixed:
  2397. - out, dispose and new can be used as idenfiers now
  2398. - const p = apointerype(nil); is supported now
  2399. + support for const p = apointertype(pointer(1234)); added
  2400. Revision 1.30 2001/04/14 14:07:10 peter
  2401. * moved more code from pass_1 to det_resulttype
  2402. Revision 1.29 2001/04/13 23:50:24 peter
  2403. * fpc mode now requires @ also when left of assignment is an procvardef
  2404. Revision 1.28 2001/04/13 01:22:12 peter
  2405. * symtable change to classes
  2406. * range check generation and errors fixed, make cycle DEBUG=1 works
  2407. * memory leaks fixed
  2408. Revision 1.27 2001/04/04 22:43:52 peter
  2409. * remove unnecessary calls to firstpass
  2410. Revision 1.26 2001/04/02 21:20:33 peter
  2411. * resulttype rewrite
  2412. Revision 1.25 2001/03/11 22:58:50 peter
  2413. * getsym redesign, removed the globals srsym,srsymtable
  2414. Revision 1.24 2000/12/25 00:07:27 peter
  2415. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  2416. tlinkedlist objects)
  2417. Revision 1.23 2000/12/19 20:36:03 peter
  2418. * cardinal const expr fix from jonas
  2419. Revision 1.22 2000/12/17 14:00:18 peter
  2420. * fixed static variables
  2421. Revision 1.21 2000/12/15 13:26:01 jonas
  2422. * only return int64's from functions if it int64funcresok is defined
  2423. + added int64funcresok define to options.pas
  2424. Revision 1.20 2000/12/15 12:13:52 michael
  2425. + Fix from Peter
  2426. Revision 1.19 2000/12/07 17:19:42 jonas
  2427. * new constant handling: from now on, hex constants >$7fffffff are
  2428. parsed as unsigned constants (otherwise, $80000000 got sign extended
  2429. and became $ffffffff80000000), all constants in the longint range
  2430. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  2431. are cardinals and the rest are int64's.
  2432. * added lots of longint typecast to prevent range check errors in the
  2433. compiler and rtl
  2434. * type casts of symbolic ordinal constants are now preserved
  2435. * fixed bug where the original resulttype.def wasn't restored correctly
  2436. after doing a 64bit rangecheck
  2437. Revision 1.18 2000/11/29 00:30:36 florian
  2438. * unused units removed from uses clause
  2439. * some changes for widestrings
  2440. Revision 1.17 2000/11/09 17:46:55 florian
  2441. * System.TypeInfo fixed
  2442. + System.Finalize implemented
  2443. + some new keywords for interface support added
  2444. Revision 1.16 2000/11/06 20:30:55 peter
  2445. * more fixes to get make cycle working
  2446. Revision 1.15 2000/11/04 14:25:20 florian
  2447. + merged Attila's changes for interfaces, not tested yet
  2448. Revision 1.14 2000/10/31 22:02:49 peter
  2449. * symtable splitted, no real code changes
  2450. Revision 1.13 2000/10/26 23:40:54 peter
  2451. * fixed crash with call from type decl which is not allowed (merged)
  2452. Revision 1.12 2000/10/21 18:16:12 florian
  2453. * a lot of changes:
  2454. - basic dyn. array support
  2455. - basic C++ support
  2456. - some work for interfaces done
  2457. ....
  2458. Revision 1.11 2000/10/14 10:14:51 peter
  2459. * moehrendorf oct 2000 rewrite
  2460. Revision 1.10 2000/10/01 19:48:25 peter
  2461. * lot of compile updates for cg11
  2462. Revision 1.9 2000/09/24 21:19:50 peter
  2463. * delphi compile fixes
  2464. Revision 1.8 2000/09/24 15:06:22 peter
  2465. * use defines.inc
  2466. Revision 1.7 2000/08/27 16:11:51 peter
  2467. * moved some util functions from globals,cobjects to cutils
  2468. * splitted files into finput,fmodule
  2469. Revision 1.6 2000/08/20 15:12:49 peter
  2470. * auto derefence mode for array pointer (merged)
  2471. Revision 1.5 2000/08/16 18:33:53 peter
  2472. * splitted namedobjectitem.next into indexnext and listnext so it
  2473. can be used in both lists
  2474. * don't allow "word = word" type definitions (merged)
  2475. Revision 1.4 2000/08/16 13:06:06 florian
  2476. + support of 64 bit integer constants
  2477. Revision 1.3 2000/08/04 22:00:52 peter
  2478. * merges from fixes
  2479. Revision 1.2 2000/07/13 11:32:44 michael
  2480. + removed logs
  2481. }