pexpr.pas 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684
  1. {
  2. $Id$
  3. Copyright (c) 1998 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. interface
  20. uses symtable,tree;
  21. { reads a whole expression }
  22. function expr : ptree;
  23. { reads an expression without assignements and .. }
  24. function comp_expr(accept_equal : boolean):Ptree;
  25. { reads a single factor }
  26. function factor(getaddr : boolean) : ptree;
  27. { the ID token has to be consumed before calling this function }
  28. procedure do_member_read(getaddr : boolean;const sym : psym;var p1 : ptree;
  29. var pd : pdef;var again : boolean);
  30. function get_intconst:longint;
  31. function get_stringconst:string;
  32. implementation
  33. uses
  34. globtype,systems,tokens,
  35. cobjects,globals,scanner,
  36. symconst,aasm,
  37. hcodegen,types,verbose,strings,
  38. {$ifndef newcg}
  39. tccal,
  40. {$endif newcg}
  41. pass_1,
  42. { parser specific stuff }
  43. pbase,pdecl,
  44. { processor specific stuff }
  45. cpubase,cpuinfo;
  46. const
  47. allow_type : boolean = true;
  48. got_addrn : boolean = false;
  49. function parse_paras(__colon,in_prop_paras : boolean) : ptree;
  50. var
  51. p1,p2 : ptree;
  52. end_of_paras : ttoken;
  53. begin
  54. if in_prop_paras then
  55. end_of_paras:=_RECKKLAMMER
  56. else
  57. end_of_paras:=_RKLAMMER;
  58. if token=end_of_paras then
  59. begin
  60. parse_paras:=nil;
  61. exit;
  62. end;
  63. p2:=nil;
  64. inc(parsing_para_level);
  65. while true do
  66. begin
  67. p1:=comp_expr(true);
  68. p2:=gencallparanode(p1,p2);
  69. { it's for the str(l:5,s); }
  70. if __colon and (token=_COLON) then
  71. begin
  72. consume(_COLON);
  73. p1:=comp_expr(true);
  74. p2:=gencallparanode(p1,p2);
  75. p2^.is_colon_para:=true;
  76. if token=_COLON then
  77. begin
  78. consume(_COLON);
  79. p1:=comp_expr(true);
  80. p2:=gencallparanode(p1,p2);
  81. p2^.is_colon_para:=true;
  82. end
  83. end;
  84. if token=_COMMA then
  85. consume(_COMMA)
  86. else
  87. break;
  88. end;
  89. dec(parsing_para_level);
  90. parse_paras:=p2;
  91. end;
  92. procedure check_tp_procvar(var p : ptree);
  93. var
  94. p1 : ptree;
  95. Store_valid : boolean;
  96. begin
  97. if (m_tp_procvar in aktmodeswitches) and
  98. (not got_addrn) and
  99. (not in_args) and
  100. (p^.treetype=loadn) then
  101. begin
  102. { support if procvar then for tp7 and many other expression like this }
  103. Store_valid:=Must_be_valid;
  104. Must_be_valid:=false;
  105. do_firstpass(p);
  106. Must_be_valid:=Store_valid;
  107. if not(getprocvar) and (p^.resulttype^.deftype=procvardef) then
  108. begin
  109. p1:=gencallnode(nil,nil);
  110. p1^.right:=p;
  111. p1^.resulttype:=pprocvardef(p^.resulttype)^.retdef;
  112. firstpass(p1);
  113. p:=p1;
  114. end;
  115. end;
  116. end;
  117. function statement_syssym(l : longint;var pd : pdef) : ptree;
  118. var
  119. p1,p2,paras : ptree;
  120. prev_in_args : boolean;
  121. Store_valid : boolean;
  122. begin
  123. prev_in_args:=in_args;
  124. Store_valid:=Must_be_valid;
  125. case l of
  126. in_ord_x :
  127. begin
  128. consume(_LKLAMMER);
  129. in_args:=true;
  130. Must_be_valid:=true;
  131. p1:=comp_expr(true);
  132. consume(_RKLAMMER);
  133. do_firstpass(p1);
  134. p1:=geninlinenode(in_ord_x,false,p1);
  135. do_firstpass(p1);
  136. statement_syssym := p1;
  137. pd:=p1^.resulttype;
  138. end;
  139. in_break :
  140. begin
  141. statement_syssym:=genzeronode(breakn);
  142. pd:=voiddef;
  143. end;
  144. in_continue :
  145. begin
  146. statement_syssym:=genzeronode(continuen);
  147. pd:=voiddef;
  148. end;
  149. in_typeof_x :
  150. begin
  151. consume(_LKLAMMER);
  152. in_args:=true;
  153. {allow_type:=true;}
  154. p1:=comp_expr(true);
  155. {allow_type:=false;}
  156. consume(_RKLAMMER);
  157. pd:=voidpointerdef;
  158. if p1^.treetype=typen then
  159. begin
  160. if (p1^.typenodetype=nil) then
  161. begin
  162. Message(type_e_mismatch);
  163. statement_syssym:=genzeronode(errorn);
  164. end
  165. else
  166. if p1^.typenodetype^.deftype=objectdef then
  167. begin
  168. { we can use resulttype in pass_2 (PM) }
  169. p1^.resulttype:=p1^.typenodetype;
  170. statement_syssym:=geninlinenode(in_typeof_x,false,p1);
  171. end
  172. else
  173. begin
  174. Message(type_e_mismatch);
  175. disposetree(p1);
  176. statement_syssym:=genzeronode(errorn);
  177. end;
  178. end
  179. else { not a type node }
  180. begin
  181. Must_be_valid:=false;
  182. do_firstpass(p1);
  183. if (p1^.resulttype=nil) then
  184. begin
  185. Message(type_e_mismatch);
  186. disposetree(p1);
  187. statement_syssym:=genzeronode(errorn)
  188. end
  189. else
  190. if p1^.resulttype^.deftype=objectdef then
  191. statement_syssym:=geninlinenode(in_typeof_x,false,p1)
  192. else
  193. begin
  194. Message(type_e_mismatch);
  195. statement_syssym:=genzeronode(errorn);
  196. disposetree(p1);
  197. end;
  198. end;
  199. end;
  200. in_sizeof_x :
  201. begin
  202. consume(_LKLAMMER);
  203. in_args:=true;
  204. {allow_type:=true;}
  205. p1:=comp_expr(true);
  206. {allow_type:=false; }
  207. consume(_RKLAMMER);
  208. pd:=s32bitdef;
  209. if p1^.treetype=typen then
  210. begin
  211. statement_syssym:=genordinalconstnode(p1^.typenodetype^.size,pd);
  212. { p1 not needed !}
  213. disposetree(p1);
  214. end
  215. else
  216. begin
  217. Must_be_valid:=false;
  218. do_firstpass(p1);
  219. if ((p1^.resulttype^.deftype=objectdef) and
  220. (oo_has_constructor in pobjectdef(p1^.resulttype)^.objectoptions)) or
  221. is_open_array(p1^.resulttype) or
  222. is_open_string(p1^.resulttype) then
  223. statement_syssym:=geninlinenode(in_sizeof_x,false,p1)
  224. else
  225. begin
  226. statement_syssym:=genordinalconstnode(p1^.resulttype^.size,pd);
  227. { p1 not needed !}
  228. disposetree(p1);
  229. end;
  230. end;
  231. end;
  232. in_assigned_x :
  233. begin
  234. consume(_LKLAMMER);
  235. in_args:=true;
  236. p1:=comp_expr(true);
  237. Must_be_valid:=true;
  238. do_firstpass(p1);
  239. if not codegenerror then
  240. begin
  241. case p1^.resulttype^.deftype of
  242. pointerdef,
  243. procvardef,
  244. classrefdef : ;
  245. objectdef :
  246. if not(pobjectdef(p1^.resulttype)^.is_class) then
  247. Message(parser_e_illegal_parameter_list);
  248. else
  249. Message(parser_e_illegal_parameter_list);
  250. end;
  251. end;
  252. p2:=gencallparanode(p1,nil);
  253. p2:=geninlinenode(in_assigned_x,false,p2);
  254. consume(_RKLAMMER);
  255. pd:=booldef;
  256. statement_syssym:=p2;
  257. end;
  258. in_ofs_x :
  259. begin
  260. consume(_LKLAMMER);
  261. in_args:=true;
  262. p1:=comp_expr(true);
  263. p1:=gensinglenode(addrn,p1);
  264. Must_be_valid:=false;
  265. do_firstpass(p1);
  266. { Ofs() returns a longint, not a pointer }
  267. p1^.resulttype:=u32bitdef;
  268. pd:=p1^.resulttype;
  269. consume(_RKLAMMER);
  270. statement_syssym:=p1;
  271. end;
  272. in_addr_x :
  273. begin
  274. consume(_LKLAMMER);
  275. in_args:=true;
  276. p1:=comp_expr(true);
  277. p1:=gensinglenode(addrn,p1);
  278. Must_be_valid:=false;
  279. do_firstpass(p1);
  280. pd:=p1^.resulttype;
  281. consume(_RKLAMMER);
  282. statement_syssym:=p1;
  283. end;
  284. in_seg_x :
  285. begin
  286. consume(_LKLAMMER);
  287. in_args:=true;
  288. p1:=comp_expr(true);
  289. do_firstpass(p1);
  290. if p1^.location.loc<>LOC_REFERENCE then
  291. Message(cg_e_illegal_expression);
  292. p1:=genordinalconstnode(0,s32bitdef);
  293. Must_be_valid:=false;
  294. pd:=s32bitdef;
  295. consume(_RKLAMMER);
  296. statement_syssym:=p1;
  297. end;
  298. in_high_x,
  299. in_low_x :
  300. begin
  301. consume(_LKLAMMER);
  302. in_args:=true;
  303. {allow_type:=true;}
  304. p1:=comp_expr(true);
  305. {allow_type:=false;}
  306. do_firstpass(p1);
  307. if p1^.treetype=typen then
  308. p1^.resulttype:=p1^.typenodetype;
  309. Must_be_valid:=false;
  310. p2:=geninlinenode(l,false,p1);
  311. consume(_RKLAMMER);
  312. pd:=s32bitdef;
  313. statement_syssym:=p2;
  314. end;
  315. in_succ_x,
  316. in_pred_x :
  317. begin
  318. consume(_LKLAMMER);
  319. in_args:=true;
  320. p1:=comp_expr(true);
  321. do_firstpass(p1);
  322. Must_be_valid:=false;
  323. p2:=geninlinenode(l,false,p1);
  324. consume(_RKLAMMER);
  325. pd:=p1^.resulttype;
  326. statement_syssym:=p2;
  327. end;
  328. in_inc_x,
  329. in_dec_x :
  330. begin
  331. consume(_LKLAMMER);
  332. in_args:=true;
  333. p1:=comp_expr(true);
  334. Must_be_valid:=false;
  335. if token=_COMMA then
  336. begin
  337. consume(_COMMA);
  338. p2:=gencallparanode(comp_expr(true),nil);
  339. end
  340. else
  341. p2:=nil;
  342. p2:=gencallparanode(p1,p2);
  343. statement_syssym:=geninlinenode(l,false,p2);
  344. consume(_RKLAMMER);
  345. pd:=voiddef;
  346. end;
  347. in_concat_x :
  348. begin
  349. consume(_LKLAMMER);
  350. in_args:=true;
  351. p2:=nil;
  352. while true do
  353. begin
  354. p1:=comp_expr(true);
  355. Must_be_valid:=true;
  356. do_firstpass(p1);
  357. if not((p1^.resulttype^.deftype=stringdef) or
  358. ((p1^.resulttype^.deftype=orddef) and
  359. (porddef(p1^.resulttype)^.typ=uchar))) then
  360. Message(parser_e_illegal_parameter_list);
  361. if p2<>nil then
  362. p2:=gennode(addn,p2,p1)
  363. else
  364. p2:=p1;
  365. if token=_COMMA then
  366. consume(_COMMA)
  367. else
  368. break;
  369. end;
  370. consume(_RKLAMMER);
  371. pd:=cshortstringdef;
  372. statement_syssym:=p2;
  373. end;
  374. in_read_x,
  375. in_readln_x :
  376. begin
  377. if token=_LKLAMMER then
  378. begin
  379. consume(_LKLAMMER);
  380. in_args:=true;
  381. Must_be_valid:=false;
  382. paras:=parse_paras(false,false);
  383. consume(_RKLAMMER);
  384. end
  385. else
  386. paras:=nil;
  387. pd:=voiddef;
  388. p1:=geninlinenode(l,false,paras);
  389. do_firstpass(p1);
  390. statement_syssym := p1;
  391. end;
  392. in_write_x,
  393. in_writeln_x :
  394. begin
  395. if token=_LKLAMMER then
  396. begin
  397. consume(_LKLAMMER);
  398. in_args:=true;
  399. Must_be_valid:=true;
  400. paras:=parse_paras(true,false);
  401. consume(_RKLAMMER);
  402. end
  403. else
  404. paras:=nil;
  405. pd:=voiddef;
  406. p1 := geninlinenode(l,false,paras);
  407. do_firstpass(p1);
  408. statement_syssym := p1;
  409. end;
  410. in_str_x_string :
  411. begin
  412. consume(_LKLAMMER);
  413. in_args:=true;
  414. paras:=parse_paras(true,false);
  415. consume(_RKLAMMER);
  416. p1 := geninlinenode(l,false,paras);
  417. do_firstpass(p1);
  418. statement_syssym := p1;
  419. pd:=voiddef;
  420. end;
  421. in_val_x:
  422. Begin
  423. consume(_LKLAMMER);
  424. in_args := true;
  425. p1:= gencallparanode(comp_expr(true), nil);
  426. Must_be_valid := False;
  427. consume(_COMMA);
  428. p2 := gencallparanode(comp_expr(true),p1);
  429. if (token = _COMMA) then
  430. Begin
  431. consume(_COMMA);
  432. p2 := gencallparanode(comp_expr(true),p2)
  433. End;
  434. consume(_RKLAMMER);
  435. p2 := geninlinenode(l,false,p2);
  436. do_firstpass(p2);
  437. statement_syssym := p2;
  438. pd := voiddef;
  439. End;
  440. in_include_x_y,
  441. in_exclude_x_y :
  442. begin
  443. consume(_LKLAMMER);
  444. in_args:=true;
  445. p1:=comp_expr(true);
  446. Must_be_valid:=false;
  447. consume(_COMMA);
  448. p2:=comp_expr(true);
  449. statement_syssym:=geninlinenode(l,false,gencallparanode(p1,gencallparanode(p2,nil)));
  450. consume(_RKLAMMER);
  451. pd:=voiddef;
  452. end;
  453. in_assert_x_y :
  454. begin
  455. consume(_LKLAMMER);
  456. in_args:=true;
  457. p1:=comp_expr(true);
  458. if token=_COMMA then
  459. begin
  460. consume(_COMMA);
  461. p2:=comp_expr(true);
  462. end
  463. else
  464. begin
  465. { then insert an empty string }
  466. p2:=genstringconstnode('');
  467. end;
  468. statement_syssym:=geninlinenode(l,false,gencallparanode(p1,gencallparanode(p2,nil)));
  469. consume(_RKLAMMER);
  470. pd:=voiddef;
  471. end;
  472. else
  473. internalerror(15);
  474. end;
  475. in_args:=prev_in_args;
  476. Must_be_valid:=Store_valid;
  477. end;
  478. { reads the parameter for a subroutine call }
  479. procedure do_proc_call(getaddr : boolean;var again : boolean;var p1:Ptree;var pd:Pdef);
  480. var
  481. prev_in_args : boolean;
  482. prevafterassn : boolean;
  483. Store_valid : boolean;
  484. begin
  485. prev_in_args:=in_args;
  486. prevafterassn:=afterassignment;
  487. afterassignment:=false;
  488. { want we only determine the address of }
  489. { a subroutine ? }
  490. if not(getaddr) then
  491. begin
  492. if token=_LKLAMMER then
  493. begin
  494. consume(_LKLAMMER);
  495. in_args:=true;
  496. p1^.left:=parse_paras(false,false);
  497. consume(_RKLAMMER);
  498. end
  499. else p1^.left:=nil;
  500. { do firstpass because we need the }
  501. { result type }
  502. Store_valid:=Must_be_valid;
  503. Must_be_valid:=false;
  504. do_firstpass(p1);
  505. Must_be_valid:=Store_valid;
  506. end
  507. else
  508. begin
  509. { address operator @: }
  510. p1^.left:=nil;
  511. { forget pd }
  512. pd:=nil;
  513. if (p1^.symtableproc^.symtabletype=withsymtable) and
  514. (p1^.symtableproc^.defowner^.deftype=objectdef) then
  515. begin
  516. p1^.methodpointer:=getcopy(pwithsymtable(p1^.symtableproc)^.withrefnode);
  517. end
  518. else if not(assigned(p1^.methodpointer)) then
  519. begin
  520. { we must provide a method pointer, if it isn't given, }
  521. { it is self }
  522. p1^.methodpointer:=genselfnode(procinfo._class);
  523. p1^.methodpointer^.resulttype:=procinfo._class;
  524. end;
  525. { no postfix operators }
  526. again:=false;
  527. end;
  528. pd:=p1^.resulttype;
  529. in_args:=prev_in_args;
  530. afterassignment:=prevafterassn;
  531. end;
  532. procedure handle_procvar(pv : pprocvardef;var p2 : ptree);
  533. procedure doconv(procvar : pprocvardef;var t : ptree);
  534. var
  535. hp : ptree;
  536. begin
  537. hp:=nil;
  538. if (proc_to_procvar_equal(pprocsym(t^.symtableentry)^.definition,procvar)) then
  539. begin
  540. if (po_methodpointer in procvar^.procoptions) then
  541. hp:=genloadmethodcallnode(pprocsym(t^.symtableprocentry),t^.symtable,getcopy(t^.methodpointer))
  542. else
  543. hp:=genloadcallnode(pprocsym(t^.symtableprocentry),t^.symtable);
  544. end;
  545. if assigned(hp) then
  546. begin
  547. disposetree(t);
  548. t:=hp;
  549. end;
  550. end;
  551. begin
  552. if (p2^.treetype=calln) then
  553. doconv(pv,p2)
  554. else
  555. if (p2^.treetype=typeconvn) and
  556. (p2^.left^.treetype=calln) then
  557. doconv(pv,p2^.left);
  558. end;
  559. { the following procedure handles the access to a property symbol }
  560. procedure handle_propertysym(sym : psym;st : psymtable;var p1 : ptree;
  561. var pd : pdef);
  562. var
  563. paras : ptree;
  564. p2 : ptree;
  565. plist : ppropsymlist;
  566. begin
  567. paras:=nil;
  568. { property parameters? }
  569. if token=_LECKKLAMMER then
  570. begin
  571. consume(_LECKKLAMMER);
  572. paras:=parse_paras(false,true);
  573. consume(_RECKKLAMMER);
  574. end;
  575. { indexed property }
  576. if (ppo_indexed in ppropertysym(sym)^.propoptions) then
  577. begin
  578. p2:=genordinalconstnode(ppropertysym(sym)^.index,s32bitdef);
  579. paras:=gencallparanode(p2,paras);
  580. end;
  581. { we need only a write property if a := follows }
  582. { if not(afterassignment) and not(in_args) then }
  583. if token=_ASSIGNMENT then
  584. begin
  585. { write property: }
  586. { no result }
  587. pd:=voiddef;
  588. if assigned(ppropertysym(sym)^.writeaccesssym) then
  589. begin
  590. case ppropertysym(sym)^.writeaccesssym^.sym^.typ of
  591. procsym :
  592. begin
  593. { generate the method call }
  594. p1:=genmethodcallnode(pprocsym(ppropertysym(sym)^.writeaccesssym^.sym),st,p1);
  595. { we know the procedure to call, so
  596. force the usage of that procedure }
  597. p1^.procdefinition:=pprocdef(ppropertysym(sym)^.writeaccessdef);
  598. p1^.left:=paras;
  599. consume(_ASSIGNMENT);
  600. { read the expression }
  601. getprocvar:=ppropertysym(sym)^.proptype^.deftype=procvardef;
  602. p2:=comp_expr(true);
  603. if getprocvar then
  604. handle_procvar(pprocvardef(ppropertysym(sym)^.proptype),p2);
  605. p1^.left:=gencallparanode(p2,p1^.left);
  606. getprocvar:=false;
  607. end;
  608. varsym :
  609. begin
  610. if assigned(paras) then
  611. message(parser_e_no_paras_allowed);
  612. { subscribed access? }
  613. plist:=ppropertysym(sym)^.writeaccesssym;
  614. while assigned(plist) do
  615. begin
  616. if p1=nil then
  617. p1:=genloadnode(pvarsym(plist^.sym),st)
  618. else
  619. p1:=gensubscriptnode(pvarsym(plist^.sym),p1);
  620. plist:=plist^.next;
  621. end;
  622. consume(_ASSIGNMENT);
  623. { read the expression }
  624. p2:=comp_expr(true);
  625. p1:=gennode(assignn,p1,p2);
  626. end
  627. else
  628. begin
  629. p1:=genzeronode(errorn);
  630. Message(parser_e_no_procedure_to_access_property);
  631. end;
  632. end;
  633. end
  634. else
  635. begin
  636. p1:=genzeronode(errorn);
  637. Message(parser_e_no_procedure_to_access_property);
  638. end;
  639. end
  640. else
  641. begin
  642. { read property: }
  643. pd:=ppropertysym(sym)^.proptype;
  644. if assigned(ppropertysym(sym)^.readaccesssym) then
  645. begin
  646. case ppropertysym(sym)^.readaccesssym^.sym^.typ of
  647. varsym :
  648. begin
  649. if assigned(paras) then
  650. message(parser_e_no_paras_allowed);
  651. { subscribed access? }
  652. plist:=ppropertysym(sym)^.readaccesssym;
  653. while assigned(plist) do
  654. begin
  655. if p1=nil then
  656. p1:=genloadnode(pvarsym(plist^.sym),st)
  657. else
  658. p1:=gensubscriptnode(pvarsym(plist^.sym),p1);
  659. plist:=plist^.next;
  660. end;
  661. end;
  662. procsym :
  663. begin
  664. { generate the method call }
  665. p1:=genmethodcallnode(pprocsym(ppropertysym(sym)^.readaccesssym^.sym),st,p1);
  666. { we know the procedure to call, so
  667. force the usage of that procedure }
  668. p1^.procdefinition:=pprocdef(ppropertysym(sym)^.readaccessdef);
  669. { insert paras }
  670. p1^.left:=paras;
  671. end
  672. else
  673. begin
  674. p1:=genzeronode(errorn);
  675. Message(type_e_mismatch);
  676. end;
  677. end;
  678. end
  679. else
  680. begin
  681. { error, no function to read property }
  682. p1:=genzeronode(errorn);
  683. Message(parser_e_no_procedure_to_access_property);
  684. end;
  685. end;
  686. end;
  687. { the ID token has to be consumed before calling this function }
  688. procedure do_member_read(getaddr : boolean;const sym : psym;var p1 : ptree;
  689. var pd : pdef;var again : boolean);
  690. var
  691. static_name : string;
  692. isclassref : boolean;
  693. begin
  694. if sym=nil then
  695. begin
  696. { pattern is still valid unless
  697. there is another ID just after the ID of sym }
  698. Message1(sym_e_id_no_member,pattern);
  699. disposetree(p1);
  700. p1:=genzeronode(errorn);
  701. { try to clean up }
  702. pd:=generrordef;
  703. again:=false;
  704. end
  705. else
  706. begin
  707. isclassref:=pd^.deftype=classrefdef;
  708. { check protected and private members }
  709. { please leave this code as it is, }
  710. { it has now the same behaviaor as TP/Delphi }
  711. if (sp_private in sym^.symoptions) and
  712. (pobjectdef(pd)^.owner^.symtabletype=unitsymtable) then
  713. Message(parser_e_cant_access_private_member);
  714. if (sp_protected in sym^.symoptions) and
  715. (pobjectdef(pd)^.owner^.symtabletype=unitsymtable) then
  716. begin
  717. if assigned(aktprocsym^.definition^._class) then
  718. begin
  719. if not aktprocsym^.definition^._class^.is_related(pobjectdef(sym^.owner^.defowner)) then
  720. Message(parser_e_cant_access_protected_member);
  721. end
  722. else
  723. Message(parser_e_cant_access_protected_member);
  724. end;
  725. { we assume, that only procsyms and varsyms are in an object }
  726. { symbol table, for classes, properties are allowed }
  727. case sym^.typ of
  728. procsym:
  729. begin
  730. p1:=genmethodcallnode(pprocsym(sym),srsymtable,p1);
  731. do_proc_call(getaddr or
  732. (block_type=bt_const) or
  733. (getprocvar and
  734. (m_tp_procvar in aktmodeswitches) and
  735. proc_to_procvar_equal(pprocsym(sym)^.definition,getprocvardef))
  736. ,again,p1,pd);
  737. if (block_type=bt_const) then
  738. handle_procvar(getprocvardef,p1);
  739. { now we know the real method e.g. we can check for a class method }
  740. if isclassref and
  741. assigned(p1^.procdefinition) and
  742. not(po_classmethod in p1^.procdefinition^.procoptions) and
  743. not(p1^.procdefinition^.proctypeoption=potype_constructor) then
  744. Message(parser_e_only_class_methods_via_class_ref);
  745. end;
  746. varsym:
  747. begin
  748. if isclassref then
  749. Message(parser_e_only_class_methods_via_class_ref);
  750. if (sp_static in sym^.symoptions) then
  751. begin
  752. { static_name:=lower(srsymtable^.name^)+'_'+sym^.name;
  753. this is wrong for static field in with symtable (PM) }
  754. static_name:=lower(srsym^.owner^.name^)+'_'+sym^.name;
  755. getsym(static_name,true);
  756. disposetree(p1);
  757. p1:=genloadnode(pvarsym(srsym),srsymtable);
  758. end
  759. else
  760. p1:=gensubscriptnode(pvarsym(sym),p1);
  761. pd:=pvarsym(sym)^.definition;
  762. end;
  763. propertysym:
  764. begin
  765. if isclassref then
  766. Message(parser_e_only_class_methods_via_class_ref);
  767. handle_propertysym(sym,srsymtable,p1,pd);
  768. end;
  769. else internalerror(16);
  770. end;
  771. end;
  772. end;
  773. {****************************************************************************
  774. Factor
  775. ****************************************************************************}
  776. function factor(getaddr : boolean) : ptree;
  777. var
  778. l : longint;
  779. oldp1,
  780. p1,p2,p3 : ptree;
  781. code : integer;
  782. pd,pd2 : pdef;
  783. possible_error,
  784. unit_specific,
  785. again : boolean;
  786. sym : pvarsym;
  787. classh : pobjectdef;
  788. d : bestreal;
  789. static_name : string;
  790. propsym : ppropertysym;
  791. filepos : tfileposinfo;
  792. {---------------------------------------------
  793. Is_func_ret
  794. ---------------------------------------------}
  795. function is_func_ret(sym : psym) : boolean;
  796. var
  797. p : pprocinfo;
  798. storesymtablestack : psymtable;
  799. begin
  800. is_func_ret:=false;
  801. if (sym^.typ<>funcretsym) and ((procinfo.flags and pi_operator)=0) then
  802. exit;
  803. p:=@procinfo;
  804. while system.assigned(p) do
  805. begin
  806. { is this an access to a function result ? }
  807. if assigned(p^.funcretsym) and
  808. ((pfuncretsym(sym)=p^.funcretsym) or
  809. ((pvarsym(sym)=opsym) and
  810. ((p^.flags and pi_operator)<>0))) and
  811. (p^.retdef<>pdef(voiddef)) and
  812. (token<>_LKLAMMER) and
  813. (not ((m_tp in aktmodeswitches) and
  814. (afterassignment or in_args))) then
  815. begin
  816. if ((pvarsym(sym)=opsym) and
  817. ((p^.flags and pi_operator)<>0)) then
  818. inc(opsym^.refs);
  819. if ((pvarsym(sym)=opsym) and
  820. ((p^.flags and pi_operator)<>0)) then
  821. inc(opsym^.refs);
  822. p1:=genzeronode(funcretn);
  823. pd:=p^.retdef;
  824. p1^.funcretprocinfo:=p;
  825. p1^.retdef:=pd;
  826. is_func_ret:=true;
  827. exit;
  828. end;
  829. p:=p^.parent;
  830. end;
  831. { we must use the function call }
  832. if(sym^.typ=funcretsym) then
  833. begin
  834. storesymtablestack:=symtablestack;
  835. symtablestack:=srsymtable^.next;
  836. getsym(sym^.name,true);
  837. if srsym^.typ<>procsym then
  838. Message(cg_e_illegal_expression);
  839. symtablestack:=storesymtablestack;
  840. end;
  841. end;
  842. {---------------------------------------------
  843. Factor_read_id
  844. ---------------------------------------------}
  845. procedure factor_read_id;
  846. var
  847. pc : pchar;
  848. len : longint;
  849. begin
  850. { allow post fix operators }
  851. again:=true;
  852. if (m_result in aktmodeswitches) and
  853. (idtoken=_RESULT) and
  854. assigned(aktprocsym) and
  855. (procinfo.retdef<>pdef(voiddef)) then
  856. begin
  857. consume(_ID);
  858. p1:=genzeronode(funcretn);
  859. pd:=procinfo.retdef;
  860. p1^.funcretprocinfo:=pointer(@procinfo);
  861. p1^.retdef:=pd;
  862. end
  863. else
  864. begin
  865. if lastsymknown then
  866. begin
  867. srsym:=lastsrsym;
  868. srsymtable:=lastsrsymtable;
  869. lastsymknown:=false;
  870. end
  871. else
  872. getsym(pattern,true);
  873. consume(_ID);
  874. if not is_func_ret(srsym) then
  875. { else it's a normal symbol }
  876. begin
  877. { is it defined like UNIT.SYMBOL ? }
  878. if srsym^.typ=unitsym then
  879. begin
  880. consume(_POINT);
  881. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  882. unit_specific:=true;
  883. consume(_ID);
  884. end
  885. else
  886. unit_specific:=false;
  887. if not assigned(srsym) then
  888. Begin
  889. p1:=genzeronode(errorn);
  890. { try to clean up }
  891. pd:=generrordef;
  892. end
  893. else
  894. Begin
  895. { check semantics of private }
  896. if (srsym^.typ in [propertysym,procsym,varsym]) and
  897. (srsymtable^.symtabletype=objectsymtable) then
  898. begin
  899. if (sp_private in srsym^.symoptions) and
  900. (pobjectdef(srsym^.owner^.defowner)^.owner^.symtabletype=unitsymtable) then
  901. Message(parser_e_cant_access_private_member);
  902. end;
  903. case srsym^.typ of
  904. absolutesym : begin
  905. p1:=genloadnode(pvarsym(srsym),srsymtable);
  906. pd:=pabsolutesym(srsym)^.definition;
  907. end;
  908. varsym : begin
  909. { are we in a class method ? }
  910. if (srsymtable^.symtabletype=objectsymtable) and
  911. assigned(aktprocsym) and
  912. (po_classmethod in aktprocsym^.definition^.procoptions) then
  913. Message(parser_e_only_class_methods);
  914. if (sp_static in srsym^.symoptions) then
  915. begin
  916. static_name:=lower(srsym^.owner^.name^)+'_'+srsym^.name;
  917. getsym(static_name,true);
  918. end;
  919. p1:=genloadnode(pvarsym(srsym),srsymtable);
  920. if pvarsym(srsym)^.varstate=vs_declared then
  921. begin
  922. p1^.is_first := true;
  923. { set special between first loaded until checked in firstpass }
  924. pvarsym(srsym)^.varstate:=vs_declared2;
  925. end;
  926. pd:=pvarsym(srsym)^.definition;
  927. end;
  928. typedconstsym : begin
  929. p1:=gentypedconstloadnode(ptypedconstsym(srsym),srsymtable);
  930. pd:=ptypedconstsym(srsym)^.definition;
  931. end;
  932. syssym : p1:=statement_syssym(psyssym(srsym)^.number,pd);
  933. typesym : begin
  934. pd:=ptypesym(srsym)^.definition;
  935. if not assigned(pd) then
  936. begin
  937. pd:=generrordef;
  938. again:=false;
  939. end
  940. else
  941. begin
  942. { if we read a type declaration }
  943. { we have to return the type and }
  944. { nothing else }
  945. if block_type=bt_type then
  946. begin
  947. { we don't need sym reference when it's in the
  948. current unit or system unit, because those
  949. units are always loaded (PFV) }
  950. if (pd^.owner^.unitid=0) or
  951. (pd^.owner^.unitid=1) then
  952. p1:=gentypenode(pd,nil)
  953. else
  954. p1:=gentypenode(pd,ptypesym(srsym));
  955. { here we can also set resulttype !! }
  956. p1^.resulttype:=pd;
  957. pd:=voiddef;
  958. end
  959. else { not type block }
  960. begin
  961. if token=_LKLAMMER then
  962. begin
  963. consume(_LKLAMMER);
  964. p1:=comp_expr(true);
  965. consume(_RKLAMMER);
  966. p1:=gentypeconvnode(p1,pd);
  967. p1^.explizit:=true;
  968. end
  969. else { not LKLAMMER}
  970. if (token=_POINT) and
  971. (pd^.deftype=objectdef) and
  972. not(pobjectdef(pd)^.is_class) then
  973. begin
  974. consume(_POINT);
  975. if assigned(procinfo._class) and
  976. not(getaddr) then
  977. begin
  978. if procinfo._class^.is_related(pobjectdef(pd)) then
  979. begin
  980. p1:=gentypenode(pd,ptypesym(srsym));
  981. p1^.resulttype:=pd;
  982. { search also in inherited methods }
  983. repeat
  984. srsymtable:=pobjectdef(pd)^.symtable;
  985. sym:=pvarsym(srsymtable^.search(pattern));
  986. if assigned(sym) then
  987. break;
  988. pd:=pobjectdef(pd)^.childof;
  989. until not assigned(pd);
  990. consume(_ID);
  991. do_member_read(false,sym,p1,pd,again);
  992. end
  993. else
  994. begin
  995. Message(parser_e_no_super_class);
  996. pd:=generrordef;
  997. again:=false;
  998. end;
  999. end
  1000. else
  1001. begin
  1002. { allows @TObject.Load }
  1003. { also allows static methods and variables }
  1004. p1:=genzeronode(typen);
  1005. p1^.resulttype:=pd;
  1006. { srsymtable:=pobjectdef(pd)^.symtable;
  1007. sym:=pvarsym(srsymtable^.search(pattern)); }
  1008. { TP allows also @TMenu.Load if Load is only }
  1009. { defined in an anchestor class }
  1010. sym:=pvarsym(search_class_member(pobjectdef(pd),pattern));
  1011. if not assigned(sym) then
  1012. Message1(sym_e_id_no_member,pattern)
  1013. else if not(getaddr) and not(sp_static in sym^.symoptions) then
  1014. Message(sym_e_only_static_in_static)
  1015. else
  1016. begin
  1017. consume(_ID);
  1018. do_member_read(getaddr,sym,p1,pd,again);
  1019. end;
  1020. end;
  1021. end
  1022. else
  1023. begin
  1024. { class reference ? }
  1025. if (pd^.deftype=objectdef)
  1026. and pobjectdef(pd)^.is_class then
  1027. begin
  1028. p1:=gentypenode(pd,nil);
  1029. p1^.resulttype:=pd;
  1030. pd:=new(pclassrefdef,init(pd));
  1031. p1:=gensinglenode(loadvmtn,p1);
  1032. p1^.resulttype:=pd;
  1033. end
  1034. else
  1035. begin
  1036. { generate a type node }
  1037. { (for typeof etc) }
  1038. if allow_type then
  1039. begin
  1040. p1:=gentypenode(pd,nil);
  1041. { here we must use typenodetype explicitly !! PM
  1042. p1^.resulttype:=pd; }
  1043. pd:=voiddef;
  1044. end
  1045. else
  1046. Message(parser_e_no_type_not_allowed_here);
  1047. end;
  1048. end;
  1049. end;
  1050. end;
  1051. end;
  1052. enumsym : begin
  1053. p1:=genenumnode(penumsym(srsym));
  1054. pd:=p1^.resulttype;
  1055. end;
  1056. constsym : begin
  1057. case pconstsym(srsym)^.consttype of
  1058. constint :
  1059. p1:=genordinalconstnode(pconstsym(srsym)^.value,s32bitdef);
  1060. conststring :
  1061. begin
  1062. len:=pconstsym(srsym)^.len;
  1063. if not(cs_ansistrings in aktlocalswitches) and (len>255) then
  1064. len:=255;
  1065. getmem(pc,len+1);
  1066. move(pchar(pconstsym(srsym)^.value)^,pc^,len);
  1067. pc[len]:=#0;
  1068. p1:=genpcharconstnode(pc,len);
  1069. end;
  1070. constchar :
  1071. p1:=genordinalconstnode(pconstsym(srsym)^.value,cchardef);
  1072. constreal :
  1073. p1:=genrealconstnode(pbestreal(pconstsym(srsym)^.value)^,bestrealdef^);
  1074. constbool :
  1075. p1:=genordinalconstnode(pconstsym(srsym)^.value,booldef);
  1076. constset :
  1077. p1:=gensetconstnode(pconstset(pconstsym(srsym)^.value),
  1078. psetdef(pconstsym(srsym)^.definition));
  1079. constord :
  1080. p1:=genordinalconstnode(pconstsym(srsym)^.value,
  1081. pconstsym(srsym)^.definition);
  1082. constpointer :
  1083. p1:=genpointerconstnode(pconstsym(srsym)^.value,
  1084. pconstsym(srsym)^.definition);
  1085. constnil :
  1086. p1:=genzeronode(niln);
  1087. constresourcestring:
  1088. begin
  1089. p1:=genloadnode(pvarsym(srsym),srsymtable);
  1090. p1^.resulttype:=cansistringdef;
  1091. end;
  1092. end;
  1093. pd:=p1^.resulttype;
  1094. end;
  1095. procsym : begin
  1096. { are we in a class method ? }
  1097. possible_error:=(srsymtable^.symtabletype=objectsymtable) and
  1098. assigned(aktprocsym) and
  1099. (po_classmethod in aktprocsym^.definition^.procoptions);
  1100. p1:=gencallnode(pprocsym(srsym),srsymtable);
  1101. p1^.unit_specific:=unit_specific;
  1102. do_proc_call(getaddr or
  1103. (block_type=bt_const) or
  1104. (getprocvar and
  1105. (m_tp_procvar in aktmodeswitches) and
  1106. proc_to_procvar_equal(pprocsym(srsym)^.definition,getprocvardef)),
  1107. again,p1,pd);
  1108. if (block_type=bt_const) then
  1109. handle_procvar(getprocvardef,p1);
  1110. if possible_error and
  1111. not(po_classmethod in p1^.procdefinition^.procoptions) then
  1112. Message(parser_e_only_class_methods);
  1113. end;
  1114. propertysym : begin
  1115. { access to property in a method }
  1116. { are we in a class method ? }
  1117. if (srsymtable^.symtabletype=objectsymtable) and
  1118. assigned(aktprocsym) and
  1119. (po_classmethod in aktprocsym^.definition^.procoptions) then
  1120. Message(parser_e_only_class_methods);
  1121. { no method pointer }
  1122. p1:=nil;
  1123. handle_propertysym(srsym,srsymtable,p1,pd);
  1124. end;
  1125. errorsym : begin
  1126. p1:=genzeronode(errorn);
  1127. p1^.resulttype:=generrordef;
  1128. pd:=generrordef;
  1129. if token=_LKLAMMER then
  1130. begin
  1131. consume(_LKLAMMER);
  1132. parse_paras(false,false);
  1133. consume(_RKLAMMER);
  1134. end;
  1135. end;
  1136. else
  1137. begin
  1138. p1:=genzeronode(errorn);
  1139. pd:=generrordef;
  1140. Message(cg_e_illegal_expression);
  1141. end;
  1142. end; { end case }
  1143. end;
  1144. end;
  1145. end;
  1146. end;
  1147. {---------------------------------------------
  1148. Factor_Read_Set
  1149. ---------------------------------------------}
  1150. { Read a set between [] }
  1151. function factor_read_set:ptree;
  1152. var
  1153. p1,
  1154. lastp,
  1155. buildp : ptree;
  1156. begin
  1157. buildp:=nil;
  1158. { be sure that a least one arrayconstructn is used, also for an
  1159. empty [] }
  1160. if token=_RECKKLAMMER then
  1161. buildp:=gennode(arrayconstructn,nil,buildp)
  1162. else
  1163. begin
  1164. while true do
  1165. begin
  1166. p1:=comp_expr(true);
  1167. if token=_POINTPOINT then
  1168. begin
  1169. consume(_POINTPOINT);
  1170. p2:=comp_expr(true);
  1171. p1:=gennode(arrayconstructrangen,p1,p2);
  1172. end;
  1173. { insert at the end of the tree, to get the correct order }
  1174. if not assigned(buildp) then
  1175. begin
  1176. buildp:=gennode(arrayconstructn,p1,nil);
  1177. lastp:=buildp;
  1178. end
  1179. else
  1180. begin
  1181. lastp^.right:=gennode(arrayconstructn,p1,nil);
  1182. lastp:=lastp^.right;
  1183. end;
  1184. { there could be more elements }
  1185. if token=_COMMA then
  1186. consume(_COMMA)
  1187. else
  1188. break;
  1189. end;
  1190. end;
  1191. factor_read_set:=buildp;
  1192. end;
  1193. {---------------------------------------------
  1194. Helpers
  1195. ---------------------------------------------}
  1196. procedure check_tokenpos;
  1197. begin
  1198. if (p1<>oldp1) then
  1199. begin
  1200. if assigned(p1) then
  1201. set_tree_filepos(p1,filepos);
  1202. oldp1:=p1;
  1203. filepos:=tokenpos;
  1204. end;
  1205. end;
  1206. {---------------------------------------------
  1207. PostFixOperators
  1208. ---------------------------------------------}
  1209. procedure postfixoperators;
  1210. var
  1211. store_static : boolean;
  1212. { p1 and p2 must contain valid value_str }
  1213. begin
  1214. check_tokenpos;
  1215. while again do
  1216. begin
  1217. { prevent crashes with unknown types }
  1218. if not assigned(pd) then
  1219. begin
  1220. { try to recover }
  1221. repeat
  1222. case token of
  1223. _CARET:
  1224. consume(_CARET);
  1225. _POINT:
  1226. begin
  1227. consume(_POINT);
  1228. consume(_ID);
  1229. end;
  1230. _LECKKLAMMER:
  1231. begin
  1232. repeat
  1233. consume(token);
  1234. until token in [_RECKKLAMMER,_SEMICOLON];
  1235. end;
  1236. else
  1237. break;
  1238. end;
  1239. until false;
  1240. exit;
  1241. end;
  1242. { handle token }
  1243. case token of
  1244. _CARET:
  1245. begin
  1246. consume(_CARET);
  1247. if (pd^.deftype<>pointerdef) then
  1248. begin
  1249. { ^ as binary operator is a problem!!!! (FK) }
  1250. again:=false;
  1251. Message(cg_e_invalid_qualifier);
  1252. disposetree(p1);
  1253. p1:=genzeronode(errorn);
  1254. end
  1255. else
  1256. begin
  1257. p1:=gensinglenode(derefn,p1);
  1258. pd:=ppointerdef(pd)^.definition;
  1259. end;
  1260. end;
  1261. _LECKKLAMMER:
  1262. begin
  1263. if (pd^.deftype=objectdef) and pobjectdef(pd)^.is_class then
  1264. begin
  1265. { default property }
  1266. propsym:=search_default_property(pobjectdef(pd));
  1267. if not(assigned(propsym)) then
  1268. begin
  1269. disposetree(p1);
  1270. p1:=genzeronode(errorn);
  1271. again:=false;
  1272. message(parser_e_no_default_property_available);
  1273. end
  1274. else
  1275. handle_propertysym(propsym,propsym^.owner,p1,pd);
  1276. end
  1277. else
  1278. begin
  1279. consume(_LECKKLAMMER);
  1280. repeat
  1281. case pd^.deftype of
  1282. pointerdef:
  1283. begin
  1284. p2:=comp_expr(true);
  1285. p1:=gennode(vecn,p1,p2);
  1286. pd:=ppointerdef(pd)^.definition;
  1287. end;
  1288. stringdef : begin
  1289. p2:=comp_expr(true);
  1290. p1:=gennode(vecn,p1,p2);
  1291. pd:=cchardef
  1292. end;
  1293. arraydef : begin
  1294. p2:=comp_expr(true);
  1295. { support SEG:OFS for go32v2 Mem[] }
  1296. if (target_info.target=target_i386_go32v2) and
  1297. (p1^.treetype=loadn) and
  1298. assigned(p1^.symtableentry) and
  1299. assigned(p1^.symtableentry^.owner^.name) and
  1300. (p1^.symtableentry^.owner^.name^='SYSTEM') and
  1301. ((p1^.symtableentry^.name='MEM') or
  1302. (p1^.symtableentry^.name='MEMW') or
  1303. (p1^.symtableentry^.name='MEML')) then
  1304. begin
  1305. if (token=_COLON) then
  1306. begin
  1307. consume(_COLON);
  1308. p3:=gennode(muln,genordinalconstnode($10,s32bitdef),p2);
  1309. p2:=comp_expr(true);
  1310. p2:=gennode(addn,p2,p3);
  1311. p1:=gennode(vecn,p1,p2);
  1312. p1^.memseg:=true;
  1313. p1^.memindex:=true;
  1314. end
  1315. else
  1316. begin
  1317. p1:=gennode(vecn,p1,p2);
  1318. p1^.memindex:=true;
  1319. end;
  1320. end
  1321. else
  1322. p1:=gennode(vecn,p1,p2);
  1323. pd:=parraydef(pd)^.definition;
  1324. end;
  1325. else
  1326. begin
  1327. Message(cg_e_invalid_qualifier);
  1328. disposetree(p1);
  1329. p1:=genzeronode(errorn);
  1330. again:=false;
  1331. end;
  1332. end;
  1333. if token=_COMMA then
  1334. consume(_COMMA)
  1335. else
  1336. break;
  1337. until false;
  1338. consume(_RECKKLAMMER);
  1339. end;
  1340. end;
  1341. _POINT : begin
  1342. consume(_POINT);
  1343. if (pd^.deftype=pointerdef) and
  1344. (m_autoderef in aktmodeswitches) then
  1345. begin
  1346. p1:=gensinglenode(derefn,p1);
  1347. pd:=ppointerdef(pd)^.definition;
  1348. end;
  1349. case pd^.deftype of
  1350. recorddef:
  1351. begin
  1352. sym:=pvarsym(precorddef(pd)^.symtable^.search(pattern));
  1353. if sym=nil then
  1354. begin
  1355. Message1(sym_e_illegal_field,pattern);
  1356. disposetree(p1);
  1357. p1:=genzeronode(errorn);
  1358. end
  1359. else
  1360. begin
  1361. p1:=gensubscriptnode(sym,p1);
  1362. pd:=sym^.definition;
  1363. end;
  1364. consume(_ID);
  1365. end;
  1366. classrefdef:
  1367. begin
  1368. classh:=pobjectdef(pclassrefdef(pd)^.definition);
  1369. sym:=nil;
  1370. while assigned(classh) do
  1371. begin
  1372. sym:=pvarsym(classh^.symtable^.search(pattern));
  1373. srsymtable:=classh^.symtable;
  1374. if assigned(sym) then
  1375. break;
  1376. classh:=classh^.childof;
  1377. end;
  1378. consume(_ID);
  1379. do_member_read(getaddr,sym,p1,pd,again);
  1380. end;
  1381. objectdef:
  1382. begin
  1383. classh:=pobjectdef(pd);
  1384. sym:=nil;
  1385. store_static:=allow_only_static;
  1386. allow_only_static:=false;
  1387. while assigned(classh) do
  1388. begin
  1389. sym:=pvarsym(classh^.symtable^.search(pattern));
  1390. srsymtable:=classh^.symtable;
  1391. if assigned(sym) then
  1392. break;
  1393. classh:=classh^.childof;
  1394. end;
  1395. allow_only_static:=store_static;
  1396. consume(_ID);
  1397. do_member_read(getaddr,sym,p1,pd,again);
  1398. end;
  1399. pointerdef:
  1400. begin
  1401. Message(cg_e_invalid_qualifier);
  1402. if ppointerdef(pd)^.definition^.deftype in [recorddef,objectdef,classrefdef] then
  1403. Message(parser_h_maybe_deref_caret_missing);
  1404. end;
  1405. else
  1406. begin
  1407. Message(cg_e_invalid_qualifier);
  1408. disposetree(p1);
  1409. p1:=genzeronode(errorn);
  1410. end;
  1411. end;
  1412. end;
  1413. else
  1414. begin
  1415. { is this a procedure variable ? }
  1416. if assigned(pd) then
  1417. begin
  1418. if (pd^.deftype=procvardef) then
  1419. begin
  1420. if getprocvar and is_equal(pd,getprocvardef) then
  1421. again:=false
  1422. else
  1423. if (token=_LKLAMMER) or
  1424. ((pprocvardef(pd)^.para1=nil) and
  1425. (not((token in [_ASSIGNMENT,_UNEQUAL,_EQUAL]))) and
  1426. (not afterassignment) and
  1427. (not in_args)) then
  1428. begin
  1429. { do this in a strange way }
  1430. { it's not a clean solution }
  1431. p2:=p1;
  1432. p1:=gencallnode(nil,nil);
  1433. p1^.right:=p2;
  1434. p1^.unit_specific:=unit_specific;
  1435. p1^.symtableprocentry:=pprocsym(sym);
  1436. if token=_LKLAMMER then
  1437. begin
  1438. consume(_LKLAMMER);
  1439. p1^.left:=parse_paras(false,false);
  1440. consume(_RKLAMMER);
  1441. end;
  1442. pd:=pprocvardef(pd)^.retdef;
  1443. { proc():= is never possible }
  1444. if token=_ASSIGNMENT then
  1445. begin
  1446. Message(cg_e_illegal_expression);
  1447. p1:=genzeronode(errorn);
  1448. again:=false;
  1449. end;
  1450. p1^.resulttype:=pd;
  1451. end
  1452. else
  1453. again:=false;
  1454. p1^.resulttype:=pd;
  1455. end
  1456. else
  1457. again:=false;
  1458. end
  1459. else
  1460. again:=false;
  1461. end;
  1462. end;
  1463. check_tokenpos;
  1464. end; { while again }
  1465. end;
  1466. {---------------------------------------------
  1467. Factor (Main)
  1468. ---------------------------------------------}
  1469. begin
  1470. oldp1:=nil;
  1471. p1:=nil;
  1472. filepos:=tokenpos;
  1473. if token=_ID then
  1474. begin
  1475. factor_read_id;
  1476. { handle post fix operators }
  1477. postfixoperators;
  1478. end
  1479. else
  1480. case token of
  1481. _NEW : begin
  1482. consume(_NEW);
  1483. consume(_LKLAMMER);
  1484. {allow_type:=true;}
  1485. p1:=factor(false);
  1486. {allow_type:=false;}
  1487. if p1^.treetype<>typen then
  1488. begin
  1489. Message(type_e_type_id_expected);
  1490. disposetree(p1);
  1491. pd:=generrordef;
  1492. end
  1493. else
  1494. pd:=p1^.typenodetype;
  1495. pd2:=pd;
  1496. if (pd^.deftype<>pointerdef) then
  1497. Message1(type_e_pointer_type_expected,pd^.typename)
  1498. else if {(ppointerdef(pd)^.definition^.deftype<>objectdef)}
  1499. token=_RKLAMMER then
  1500. begin
  1501. if (ppointerdef(pd)^.definition^.deftype=objectdef) and
  1502. (oo_has_vmt in pobjectdef(ppointerdef(pd)^.definition)^.objectoptions) then
  1503. Message(parser_w_use_extended_syntax_for_objects);
  1504. p1:=gensinglenode(newn,nil);
  1505. p1^.resulttype:=pd2;
  1506. consume(_RKLAMMER);
  1507. (*Message(parser_e_pointer_to_class_expected);
  1508. { if an error occurs, read til the end of
  1509. the new statement }
  1510. p1:=genzeronode(errorn);
  1511. l:=1;
  1512. while true do
  1513. begin
  1514. case token of
  1515. _LKLAMMER : inc(l);
  1516. _RKLAMMER : dec(l);
  1517. end;
  1518. consume(token);
  1519. if l=0 then
  1520. break;
  1521. end;*)
  1522. end
  1523. else
  1524. begin
  1525. disposetree(p1);
  1526. p1:=genzeronode(hnewn);
  1527. p1^.resulttype:=ppointerdef(pd)^.definition;
  1528. consume(_COMMA);
  1529. afterassignment:=false;
  1530. { determines the current object defintion }
  1531. classh:=pobjectdef(ppointerdef(pd)^.definition);
  1532. { check for an abstract class }
  1533. if (oo_has_abstract in classh^.objectoptions) then
  1534. Message(sym_e_no_instance_of_abstract_object);
  1535. { search the constructor also in the symbol tables of
  1536. the parents }
  1537. { no constructor found }
  1538. sym:=nil;
  1539. while assigned(classh) do
  1540. begin
  1541. sym:=pvarsym(classh^.symtable^.search(pattern));
  1542. srsymtable:=classh^.symtable;
  1543. if assigned(sym) then
  1544. break;
  1545. classh:=classh^.childof;
  1546. end;
  1547. consume(_ID);
  1548. do_member_read(false,sym,p1,pd,again);
  1549. if (p1^.treetype<>calln) or
  1550. (assigned(p1^.procdefinition) and
  1551. (p1^.procdefinition^.proctypeoption<>potype_constructor)) then
  1552. Message(parser_e_expr_have_to_be_constructor_call);
  1553. p1:=gensinglenode(newn,p1);
  1554. { set the resulttype }
  1555. p1^.resulttype:=pd2;
  1556. consume(_RKLAMMER);
  1557. end;
  1558. postfixoperators;
  1559. end;
  1560. _SELF : begin
  1561. again:=true;
  1562. consume(_SELF);
  1563. if not assigned(procinfo._class) then
  1564. begin
  1565. p1:=genzeronode(errorn);
  1566. pd:=generrordef;
  1567. again:=false;
  1568. Message(parser_e_self_not_in_method);
  1569. end
  1570. else
  1571. begin
  1572. if (po_classmethod in aktprocsym^.definition^.procoptions) then
  1573. begin
  1574. { self in class methods is a class reference type }
  1575. pd:=new(pclassrefdef,init(procinfo._class));
  1576. p1:=genselfnode(pd);
  1577. p1^.resulttype:=pd;
  1578. end
  1579. else
  1580. begin
  1581. p1:=genselfnode(procinfo._class);
  1582. p1^.resulttype:=procinfo._class;
  1583. end;
  1584. pd:=p1^.resulttype;
  1585. postfixoperators;
  1586. end;
  1587. end;
  1588. _INHERITED : begin
  1589. again:=true;
  1590. consume(_INHERITED);
  1591. if assigned(procinfo._class) then
  1592. begin
  1593. classh:=procinfo._class^.childof;
  1594. while assigned(classh) do
  1595. begin
  1596. srsymtable:=pobjectdef(classh)^.symtable;
  1597. sym:=pvarsym(srsymtable^.search(pattern));
  1598. if assigned(sym) then
  1599. begin
  1600. p1:=genzeronode(typen);
  1601. p1^.resulttype:=classh;
  1602. pd:=p1^.resulttype;
  1603. consume(_ID);
  1604. do_member_read(false,sym,p1,pd,again);
  1605. break;
  1606. end;
  1607. classh:=classh^.childof;
  1608. end;
  1609. if classh=nil then
  1610. begin
  1611. Message1(sym_e_id_no_member,pattern);
  1612. again:=false;
  1613. pd:=generrordef;
  1614. p1:=genzeronode(errorn);
  1615. end;
  1616. end
  1617. else
  1618. begin
  1619. Message(parser_e_generic_methods_only_in_methods);
  1620. again:=false;
  1621. pd:=generrordef;
  1622. p1:=genzeronode(errorn);
  1623. end;
  1624. postfixoperators;
  1625. end;
  1626. _INTCONST : begin
  1627. valint(pattern,l,code);
  1628. if code<>0 then
  1629. begin
  1630. val(pattern,d,code);
  1631. if code<>0 then
  1632. begin
  1633. Message(cg_e_invalid_integer);
  1634. consume(_INTCONST);
  1635. l:=1;
  1636. p1:=genordinalconstnode(l,s32bitdef);
  1637. end
  1638. else
  1639. begin
  1640. consume(_INTCONST);
  1641. p1:=genrealconstnode(d,bestrealdef^);
  1642. end;
  1643. end
  1644. else
  1645. begin
  1646. consume(_INTCONST);
  1647. p1:=genordinalconstnode(l,s32bitdef);
  1648. end;
  1649. end;
  1650. _REALNUMBER : begin
  1651. val(pattern,d,code);
  1652. if code<>0 then
  1653. begin
  1654. Message(parser_e_error_in_real);
  1655. d:=1.0;
  1656. end;
  1657. consume(_REALNUMBER);
  1658. p1:=genrealconstnode(d,bestrealdef^);
  1659. end;
  1660. _STRING : begin
  1661. pd:=stringtype;
  1662. { STRING can be also a type cast }
  1663. if token=_LKLAMMER then
  1664. begin
  1665. consume(_LKLAMMER);
  1666. p1:=comp_expr(true);
  1667. consume(_RKLAMMER);
  1668. p1:=gentypeconvnode(p1,pd);
  1669. p1^.explizit:=true;
  1670. { handle postfix operators here e.g. string(a)[10] }
  1671. again:=true;
  1672. postfixoperators;
  1673. end
  1674. else
  1675. p1:=gentypenode(pd,nil);
  1676. end;
  1677. _FILE : begin
  1678. pd:=cfiledef;
  1679. consume(_FILE);
  1680. { FILE can be also a type cast }
  1681. if token=_LKLAMMER then
  1682. begin
  1683. consume(_LKLAMMER);
  1684. p1:=comp_expr(true);
  1685. consume(_RKLAMMER);
  1686. p1:=gentypeconvnode(p1,pd);
  1687. p1^.explizit:=true;
  1688. { handle postfix operators here e.g. string(a)[10] }
  1689. again:=true;
  1690. postfixoperators;
  1691. end
  1692. else
  1693. p1:=gentypenode(pd,nil);
  1694. end;
  1695. _CSTRING : begin
  1696. p1:=genstringconstnode(pattern);
  1697. consume(_CSTRING);
  1698. end;
  1699. _CCHAR : begin
  1700. p1:=genordinalconstnode(ord(pattern[1]),cchardef);
  1701. consume(_CCHAR);
  1702. end;
  1703. _KLAMMERAFFE : begin
  1704. consume(_KLAMMERAFFE);
  1705. got_addrn:=true;
  1706. { support both @<x> and @(<x>) }
  1707. if token=_LKLAMMER then
  1708. begin
  1709. consume(_LKLAMMER);
  1710. p1:=factor(true);
  1711. consume(_RKLAMMER);
  1712. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1713. begin
  1714. { we need the resulttype }
  1715. { of the expression in pd }
  1716. do_firstpass(p1);
  1717. pd:=p1^.resulttype;
  1718. again:=true;
  1719. postfixoperators;
  1720. end;
  1721. end
  1722. else
  1723. p1:=factor(true);
  1724. got_addrn:=false;
  1725. p1:=gensinglenode(addrn,p1);
  1726. end;
  1727. _LKLAMMER : begin
  1728. consume(_LKLAMMER);
  1729. p1:=comp_expr(true);
  1730. consume(_RKLAMMER);
  1731. { it's not a good solution }
  1732. { but (a+b)^ makes some problems }
  1733. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1734. begin
  1735. { we need the resulttype }
  1736. { of the expression in pd }
  1737. do_firstpass(p1);
  1738. pd:=p1^.resulttype;
  1739. again:=true;
  1740. postfixoperators;
  1741. end;
  1742. end;
  1743. _LECKKLAMMER : begin
  1744. consume(_LECKKLAMMER);
  1745. p1:=factor_read_set;
  1746. consume(_RECKKLAMMER);
  1747. end;
  1748. _PLUS : begin
  1749. consume(_PLUS);
  1750. p1:=factor(false);
  1751. end;
  1752. _MINUS : begin
  1753. consume(_MINUS);
  1754. p1:=factor(false);
  1755. p1:=gensinglenode(umminusn,p1);
  1756. end;
  1757. _NOT : begin
  1758. consume(_NOT);
  1759. p1:=factor(false);
  1760. p1:=gensinglenode(notn,p1);
  1761. end;
  1762. _TRUE : begin
  1763. consume(_TRUE);
  1764. p1:=genordinalconstnode(1,booldef);
  1765. end;
  1766. _FALSE : begin
  1767. consume(_FALSE);
  1768. p1:=genordinalconstnode(0,booldef);
  1769. end;
  1770. _NIL : begin
  1771. consume(_NIL);
  1772. p1:=genzeronode(niln);
  1773. end;
  1774. else
  1775. begin
  1776. p1:=genzeronode(errorn);
  1777. consume(token);
  1778. Message(cg_e_illegal_expression);
  1779. end;
  1780. end;
  1781. { generate error node if no node is created }
  1782. if not assigned(p1) then
  1783. p1:=genzeronode(errorn);
  1784. { tp7 procvar handling, but not if the next token
  1785. will be a := }
  1786. if (m_tp_procvar in aktmodeswitches) and
  1787. (token<>_ASSIGNMENT) then
  1788. check_tp_procvar(p1);
  1789. factor:=p1;
  1790. check_tokenpos;
  1791. end;
  1792. {****************************************************************************
  1793. Sub_Expr
  1794. ****************************************************************************}
  1795. type
  1796. Toperator_precedence=(opcompare,opaddition,opmultiply);
  1797. Ttok2nodeRec=record
  1798. tok : ttoken;
  1799. nod : ttreetyp;
  1800. end;
  1801. const
  1802. tok2nodes=23;
  1803. tok2node:array[1..tok2nodes] of ttok2noderec=(
  1804. (tok:_PLUS ;nod:addn),
  1805. (tok:_MINUS ;nod:subn),
  1806. (tok:_STAR ;nod:muln),
  1807. (tok:_SLASH ;nod:slashn),
  1808. (tok:_EQUAL ;nod:equaln),
  1809. (tok:_GT ;nod:gtn),
  1810. (tok:_LT ;nod:ltn),
  1811. (tok:_GTE ;nod:gten),
  1812. (tok:_LTE ;nod:lten),
  1813. (tok:_SYMDIF ;nod:symdifn),
  1814. (tok:_STARSTAR;nod:starstarn),
  1815. (tok:_CARET ;nod:caretn),
  1816. (tok:_UNEQUAL ;nod:unequaln),
  1817. (tok:_AS ;nod:asn),
  1818. (tok:_IN ;nod:inn),
  1819. (tok:_IS ;nod:isn),
  1820. (tok:_OR ;nod:orn),
  1821. (tok:_AND ;nod:andn),
  1822. (tok:_DIV ;nod:divn),
  1823. (tok:_MOD ;nod:modn),
  1824. (tok:_SHL ;nod:shln),
  1825. (tok:_SHR ;nod:shrn),
  1826. (tok:_XOR ;nod:xorn)
  1827. );
  1828. operator_levels:array[Toperator_precedence] of set of Ttoken=
  1829. ([_LT,_LTE,_GT,_GTE,_EQUAL,_UNEQUAL,_IN,_IS],
  1830. [_PLUS,_MINUS,_OR,_XOR],
  1831. [_CARET,_SYMDIF,_STARSTAR,_STAR,_SLASH,_DIV,_MOD,_AND,_SHL,_SHR,_AS]);
  1832. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):Ptree;
  1833. {Reads a subexpression while the operators are of the current precedence
  1834. level, or any higher level. Replaces the old term, simpl_expr and
  1835. simpl2_expr.}
  1836. var
  1837. low,high,mid : longint;
  1838. p1,p2 : Ptree;
  1839. oldt : Ttoken;
  1840. filepos : tfileposinfo;
  1841. begin
  1842. if pred_level=opmultiply then
  1843. p1:=factor(false)
  1844. else
  1845. p1:=sub_expr(succ(pred_level),true);
  1846. repeat
  1847. if (token in operator_levels[pred_level]) and
  1848. ((token<>_EQUAL) or accept_equal) then
  1849. begin
  1850. oldt:=token;
  1851. filepos:=tokenpos;
  1852. consume(token);
  1853. if pred_level=opmultiply then
  1854. p2:=factor(false)
  1855. else
  1856. p2:=sub_expr(succ(pred_level),true);
  1857. low:=1;
  1858. high:=tok2nodes;
  1859. while (low<high) do
  1860. begin
  1861. mid:=(low+high+1) shr 1;
  1862. if oldt<tok2node[mid].tok then
  1863. high:=mid-1
  1864. else
  1865. low:=mid;
  1866. end;
  1867. if tok2node[high].tok=oldt then
  1868. p1:=gennode(tok2node[high].nod,p1,p2)
  1869. else
  1870. p1:=gennode(nothingn,p1,p2);
  1871. set_tree_filepos(p1,filepos);
  1872. end
  1873. else
  1874. break;
  1875. until false;
  1876. sub_expr:=p1;
  1877. end;
  1878. function comp_expr(accept_equal : boolean):Ptree;
  1879. var
  1880. oldafterassignment : boolean;
  1881. p1 : ptree;
  1882. begin
  1883. oldafterassignment:=afterassignment;
  1884. afterassignment:=true;
  1885. p1:=sub_expr(opcompare,accept_equal);
  1886. afterassignment:=oldafterassignment;
  1887. comp_expr:=p1;
  1888. end;
  1889. function expr : ptree;
  1890. var
  1891. p1,p2 : ptree;
  1892. oldafterassignment : boolean;
  1893. oldp1 : ptree;
  1894. filepos : tfileposinfo;
  1895. begin
  1896. oldafterassignment:=afterassignment;
  1897. p1:=sub_expr(opcompare,true);
  1898. filepos:=tokenpos;
  1899. if (m_tp_procvar in aktmodeswitches) and
  1900. (token<>_ASSIGNMENT) then
  1901. check_tp_procvar(p1);
  1902. if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
  1903. afterassignment:=true;
  1904. oldp1:=p1;
  1905. case token of
  1906. _POINTPOINT : begin
  1907. consume(_POINTPOINT);
  1908. p2:=sub_expr(opcompare,true);
  1909. p1:=gennode(rangen,p1,p2);
  1910. end;
  1911. _ASSIGNMENT : begin
  1912. consume(_ASSIGNMENT);
  1913. { avoid a firstpass of a procedure if
  1914. it must be assigned to a procvar }
  1915. { should be recursive for a:=b:=c !!! }
  1916. if (p1^.resulttype<>nil) and (p1^.resulttype^.deftype=procvardef) then
  1917. begin
  1918. getprocvar:=true;
  1919. getprocvardef:=pprocvardef(p1^.resulttype);
  1920. end;
  1921. p2:=sub_expr(opcompare,true);
  1922. if getprocvar then
  1923. handle_procvar(getprocvardef,p2);
  1924. getprocvar:=false;
  1925. p1:=gennode(assignn,p1,p2);
  1926. end;
  1927. { this is the code for C like assignements }
  1928. { from an improvement of Peter Schaefer }
  1929. _PLUSASN : begin
  1930. consume(_PLUSASN );
  1931. p2:=sub_expr(opcompare,true);
  1932. p1:=gennode(assignn,p1,gennode(addn,getcopy(p1),p2));
  1933. { was first
  1934. p1:=gennode(assignn,p1,gennode(addn,p1,p2));
  1935. but disposetree assumes that we have a real
  1936. *** tree *** }
  1937. end;
  1938. _MINUSASN : begin
  1939. consume(_MINUSASN );
  1940. p2:=sub_expr(opcompare,true);
  1941. p1:=gennode(assignn,p1,gennode(subn,getcopy(p1),p2));
  1942. end;
  1943. _STARASN : begin
  1944. consume(_STARASN );
  1945. p2:=sub_expr(opcompare,true);
  1946. p1:=gennode(assignn,p1,gennode(muln,getcopy(p1),p2));
  1947. end;
  1948. _SLASHASN : begin
  1949. consume(_SLASHASN );
  1950. p2:=sub_expr(opcompare,true);
  1951. p1:=gennode(assignn,p1,gennode(slashn,getcopy(p1),p2));
  1952. end;
  1953. end;
  1954. afterassignment:=oldafterassignment;
  1955. if p1<>oldp1 then
  1956. set_tree_filepos(p1,filepos);
  1957. expr:=p1;
  1958. end;
  1959. function get_intconst:longint;
  1960. {Reads an expression, tries to evalute it and check if it is an integer
  1961. constant. Then the constant is returned.}
  1962. var
  1963. p:Ptree;
  1964. begin
  1965. p:=comp_expr(true);
  1966. do_firstpass(p);
  1967. if not codegenerror then
  1968. begin
  1969. if (p^.treetype<>ordconstn) and
  1970. (p^.resulttype^.deftype=orddef) and
  1971. not(Porddef(p^.resulttype)^.typ in [uvoid,uchar,bool8bit,bool16bit,bool32bit]) then
  1972. Message(cg_e_illegal_expression)
  1973. else
  1974. get_intconst:=p^.value;
  1975. end;
  1976. disposetree(p);
  1977. end;
  1978. function get_stringconst:string;
  1979. {Reads an expression, tries to evaluate it and checks if it is a string
  1980. constant. Then the constant is returned.}
  1981. var
  1982. p:Ptree;
  1983. begin
  1984. get_stringconst:='';
  1985. p:=comp_expr(true);
  1986. do_firstpass(p);
  1987. if p^.treetype<>stringconstn then
  1988. begin
  1989. if (p^.treetype=ordconstn) and is_char(p^.resulttype) then
  1990. get_stringconst:=char(p^.value)
  1991. else
  1992. Message(cg_e_illegal_expression);
  1993. end
  1994. else
  1995. get_stringconst:=strpas(p^.value_str);
  1996. disposetree(p);
  1997. end;
  1998. end.
  1999. {
  2000. $Log$
  2001. Revision 1.144 1999-09-26 21:30:19 peter
  2002. + constant pointer support which can happend with typecasting like
  2003. const p=pointer(1)
  2004. * better procvar parsing in typed consts
  2005. Revision 1.143 1999/09/15 20:35:41 florian
  2006. * small fix to operator overloading when in MMX mode
  2007. + the compiler uses now fldz and fld1 if possible
  2008. + some fixes to floating point registers
  2009. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  2010. * .... ???
  2011. Revision 1.142 1999/09/13 16:26:32 peter
  2012. * fix crash with empty object as childs
  2013. Revision 1.141 1999/09/11 19:47:26 florian
  2014. * bug fix for @tobject.method, fixes bug 557, 605 and 606
  2015. Revision 1.140 1999/09/11 09:08:33 florian
  2016. * fixed bug 596
  2017. * fixed some problems with procedure variables and procedures of object,
  2018. especially in TP mode. Procedure of object doesn't apply only to classes,
  2019. it is also allowed for objects !!
  2020. Revision 1.139 1999/09/10 18:48:07 florian
  2021. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  2022. * most things for stored properties fixed
  2023. Revision 1.138 1999/09/07 08:01:20 peter
  2024. * @(<x>) support
  2025. Revision 1.137 1999/09/01 22:08:58 peter
  2026. * fixed crash with assigned()
  2027. Revision 1.136 1999/08/15 22:47:45 peter
  2028. * fixed property writeaccess which was buggy after my previous
  2029. subscribed property access
  2030. Revision 1.135 1999/08/14 00:38:56 peter
  2031. * hack to support property with record fields
  2032. Revision 1.134 1999/08/09 22:16:29 peter
  2033. * fixed crash after wrong para's with class contrustor
  2034. Revision 1.133 1999/08/05 16:53:04 peter
  2035. * V_Fatal=1, all other V_ are also increased
  2036. * Check for local procedure when assigning procvar
  2037. * fixed comment parsing because directives
  2038. * oldtp mode directives better supported
  2039. * added some messages to errore.msg
  2040. Revision 1.132 1999/08/04 13:49:45 florian
  2041. * new(...)^. is now allowed
  2042. Revision 1.131 1999/08/04 13:02:55 jonas
  2043. * all tokens now start with an underscore
  2044. * PowerPC compiles!!
  2045. Revision 1.130 1999/08/04 00:23:12 florian
  2046. * renamed i386asm and i386base to cpuasm and cpubase
  2047. Revision 1.129 1999/08/03 22:02:59 peter
  2048. * moved bitmask constants to sets
  2049. * some other type/const renamings
  2050. Revision 1.128 1999/08/03 13:50:17 michael
  2051. + Changes for alpha
  2052. Revision 1.127 1999/08/01 18:28:13 florian
  2053. * modifications for the new code generator
  2054. Revision 1.126 1999/07/30 12:28:40 peter
  2055. * fixed crash with unknown id and colon parameter in write
  2056. Revision 1.125 1999/07/27 23:42:14 peter
  2057. * indirect type referencing is now allowed
  2058. Revision 1.124 1999/07/23 21:31:42 peter
  2059. * fixed crash with resourcestring
  2060. Revision 1.123 1999/07/23 11:37:46 peter
  2061. * error for illegal type reference, instead of 10998
  2062. Revision 1.122 1999/07/22 09:37:52 florian
  2063. + resourcestring implemented
  2064. + start of longstring support
  2065. Revision 1.121 1999/07/16 10:04:35 peter
  2066. * merged
  2067. Revision 1.120 1999/07/06 22:38:11 florian
  2068. * another fix for TP/Delphi styled procedure variables
  2069. Revision 1.119 1999/07/05 20:13:16 peter
  2070. * removed temp defines
  2071. Revision 1.118 1999/07/01 21:33:57 peter
  2072. * merged
  2073. Revision 1.117 1999/06/30 15:43:20 florian
  2074. * two bugs regarding method variables fixed
  2075. - if you take in a method the address of another method
  2076. don't need self anymore
  2077. - if the class pointer was in a register, wrong code for a method
  2078. variable load was generated
  2079. Revision 1.116 1999/06/26 00:24:53 pierre
  2080. * mereg from fixes-0_99_12 branch
  2081. Revision 1.112.2.8 1999/07/16 09:54:57 peter
  2082. * @procvar support in tp7 mode works again
  2083. Revision 1.112.2.7 1999/07/07 07:53:10 michael
  2084. + Merged patches from florian
  2085. Revision 1.112.2.6 1999/07/01 21:31:59 peter
  2086. * procvar fixes again
  2087. Revision 1.112.2.5 1999/07/01 15:17:17 peter
  2088. * methoidpointer fixes from florian
  2089. Revision 1.112.2.4 1999/06/26 00:22:30 pierre
  2090. * wrong warnings in -So mode suppressed
  2091. Revision 1.112.2.3 1999/06/17 12:51:44 pierre
  2092. * changed is_assignment_overloaded into
  2093. function assignment_overloaded : pprocdef
  2094. to allow overloading of assignment with only different result type
  2095. Revision 1.112.2.2 1999/06/15 18:54:52 peter
  2096. * more procvar fixes
  2097. Revision 1.112.2.1 1999/06/13 22:38:09 peter
  2098. * tp_procvar check for loading of procvars when getaddr=false
  2099. Revision 1.112 1999/06/02 22:44:11 pierre
  2100. * previous wrong log corrected
  2101. Revision 1.111 1999/06/02 22:25:43 pierre
  2102. * changed $ifdef FPC @ into $ifndef TP
  2103. * changes for correct procvar handling under tp mode
  2104. Revision 1.110 1999/06/01 19:27:55 peter
  2105. * better checks for procvar and methodpointer
  2106. Revision 1.109 1999/05/27 19:44:46 peter
  2107. * removed oldasm
  2108. * plabel -> pasmlabel
  2109. * -a switches to source writing automaticly
  2110. * assembler readers OOPed
  2111. * asmsymbol automaticly external
  2112. * jumptables and other label fixes for asm readers
  2113. Revision 1.108 1999/05/18 14:15:54 peter
  2114. * containsself fixes
  2115. * checktypes()
  2116. Revision 1.107 1999/05/18 09:52:18 peter
  2117. * procedure of object and addrn fixes
  2118. Revision 1.106 1999/05/16 17:06:31 peter
  2119. * remove firstcallparan which looks obsolete
  2120. Revision 1.105 1999/05/12 22:36:09 florian
  2121. * override isn't allowed in objects!
  2122. Revision 1.104 1999/05/07 10:35:23 florian
  2123. * first fix for a problem with method pointer properties, still doesn't work
  2124. with WITH
  2125. Revision 1.103 1999/05/06 21:40:16 peter
  2126. * fixed crash
  2127. Revision 1.101 1999/05/06 09:05:21 peter
  2128. * generic write_float and str_float
  2129. * fixed constant float conversions
  2130. Revision 1.100 1999/05/04 21:44:57 florian
  2131. * changes to compile it with Delphi 4.0
  2132. Revision 1.99 1999/05/01 13:24:31 peter
  2133. * merged nasm compiler
  2134. * old asm moved to oldasm/
  2135. Revision 1.98 1999/04/26 18:29:56 peter
  2136. * farpointerdef moved into pointerdef.is_far
  2137. Revision 1.97 1999/04/19 09:27:48 peter
  2138. * removed my property fix
  2139. Revision 1.96 1999/04/19 09:13:47 peter
  2140. * class property without write support
  2141. Revision 1.95 1999/04/19 06:10:08 florian
  2142. * property problem fixed: a propertysym is only a write
  2143. access if it is followed by a assignment token
  2144. Revision 1.94 1999/04/17 13:12:17 peter
  2145. * addr() internal
  2146. Revision 1.93 1999/04/15 09:00:08 peter
  2147. * fixed property write
  2148. Revision 1.92 1999/04/08 20:59:43 florian
  2149. * fixed problem with default properties which are a class
  2150. * case bug (from the mailing list with -O2) fixed, the
  2151. distance of the case labels can be greater than the positive
  2152. range of a longint => it is now a dword for fpc
  2153. Revision 1.91 1999/04/06 11:21:56 peter
  2154. * more use of ttoken
  2155. Revision 1.90 1999/03/31 13:55:12 peter
  2156. * assembler inlining working for ag386bin
  2157. Revision 1.89 1999/03/26 00:05:36 peter
  2158. * released valintern
  2159. + deffile is now removed when compiling is finished
  2160. * ^( compiles now correct
  2161. + static directive
  2162. * shrd fixed
  2163. Revision 1.88 1999/03/24 23:17:15 peter
  2164. * fixed bugs 212,222,225,227,229,231,233
  2165. Revision 1.87 1999/03/16 17:52:52 jonas
  2166. * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
  2167. * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
  2168. * in cgai386: also small fixes to emitrangecheck
  2169. Revision 1.86 1999/03/04 13:55:44 pierre
  2170. * some m68k fixes (still not compilable !)
  2171. * new(tobj) does not give warning if tobj has no VMT !
  2172. Revision 1.85 1999/02/22 15:09:39 florian
  2173. * behaviaor of PROTECTED and PRIVATE fixed, works now like TP/Delphi
  2174. Revision 1.84 1999/02/22 02:15:26 peter
  2175. * updates for ag386bin
  2176. Revision 1.83 1999/02/11 09:46:25 pierre
  2177. * fix for normal method calls inside static methods :
  2178. WARNING there were both parser and codegen errors !!
  2179. added static_call boolean to calln tree
  2180. Revision 1.82 1999/01/28 14:06:47 florian
  2181. * small fix for method pointers
  2182. * found the annoying strpas bug, mainly nested call to type cast which
  2183. use ansistrings crash
  2184. Revision 1.81 1999/01/27 00:13:55 florian
  2185. * "procedure of object"-stuff fixed
  2186. Revision 1.80 1999/01/21 16:41:01 pierre
  2187. * fix for constructor inside with statements
  2188. Revision 1.79 1998/12/30 22:15:48 peter
  2189. + farpointer type
  2190. * absolutesym now also stores if its far
  2191. Revision 1.78 1998/12/11 00:03:32 peter
  2192. + globtype,tokens,version unit splitted from globals
  2193. Revision 1.77 1998/12/04 10:18:09 florian
  2194. * some stuff for procedures of object added
  2195. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  2196. Revision 1.76 1998/11/27 14:50:40 peter
  2197. + open strings, $P switch support
  2198. Revision 1.75 1998/11/25 19:12:51 pierre
  2199. * var:=new(pointer_type) support added
  2200. Revision 1.74 1998/11/13 10:18:11 peter
  2201. + nil constants
  2202. Revision 1.73 1998/11/05 12:02:52 peter
  2203. * released useansistring
  2204. * removed -Sv, its now available in fpc modes
  2205. Revision 1.72 1998/11/04 10:11:41 peter
  2206. * ansistring fixes
  2207. Revision 1.71 1998/10/22 23:57:29 peter
  2208. * fixed filedef for typenodetype
  2209. Revision 1.70 1998/10/21 15:12:54 pierre
  2210. * bug fix for IOCHECK inside a procedure with iocheck modifier
  2211. * removed the GPF for unexistant overloading
  2212. (firstcall was called with procedinition=nil !)
  2213. * changed typen to what Florian proposed
  2214. gentypenode(p : pdef) sets the typenodetype field
  2215. and resulttype is only set if inside bt_type block !
  2216. Revision 1.69 1998/10/20 15:10:19 pierre
  2217. * type ptree only allowed inside expression
  2218. if following sizeof typeof low high or as first arg of new !!
  2219. Revision 1.68 1998/10/20 11:15:44 pierre
  2220. * calling of private method allowed inside child object method
  2221. Revision 1.67 1998/10/19 08:54:57 pierre
  2222. * wrong stabs info corrected once again !!
  2223. + variable vmt offset with vmt field only if required
  2224. implemented now !!!
  2225. Revision 1.66 1998/10/15 15:13:28 pierre
  2226. + added oo_hasconstructor and oo_hasdestructor
  2227. for objects options
  2228. Revision 1.65 1998/10/13 13:10:24 peter
  2229. * new style for m68k/i386 infos and enums
  2230. Revision 1.64 1998/10/12 12:20:55 pierre
  2231. + added tai_const_symbol_offset
  2232. for r : pointer = @var.field;
  2233. * better message for different arg names on implementation
  2234. of function
  2235. Revision 1.63 1998/10/12 10:28:30 florian
  2236. + auto dereferencing of pointers to structured types in delphi mode
  2237. Revision 1.62 1998/10/12 10:05:41 peter
  2238. * fixed mem leak with arrayconstrutor
  2239. Revision 1.61 1998/10/05 13:57:15 peter
  2240. * crash preventions
  2241. Revision 1.60 1998/10/05 12:32:46 peter
  2242. + assert() support
  2243. Revision 1.59 1998/10/01 14:56:24 peter
  2244. * crash preventions
  2245. Revision 1.58 1998/09/30 07:40:35 florian
  2246. * better error recovering
  2247. Revision 1.57 1998/09/28 16:18:16 florian
  2248. * two fixes to get ansi strings work
  2249. Revision 1.56 1998/09/26 17:45:36 peter
  2250. + idtoken and only one token table
  2251. Revision 1.55 1998/09/24 23:49:10 peter
  2252. + aktmodeswitches
  2253. Revision 1.54 1998/09/23 15:46:39 florian
  2254. * problem with with and classes fixed
  2255. Revision 1.53 1998/09/23 09:58:54 peter
  2256. * first working array of const things
  2257. Revision 1.52 1998/09/20 09:38:45 florian
  2258. * hasharray for defs fixed
  2259. * ansistring code generation corrected (init/final, assignement)
  2260. Revision 1.51 1998/09/18 16:03:43 florian
  2261. * some changes to compile with Delphi
  2262. Revision 1.50 1998/09/17 13:41:18 pierre
  2263. sizeof(TPOINT) problem
  2264. Revision 1.49.2.1 1998/09/17 08:42:31 pierre
  2265. TPOINT sizeof fix
  2266. Revision 1.49 1998/09/09 11:50:53 pierre
  2267. * forward def are not put in record or objects
  2268. + added check for forwards also in record and objects
  2269. * dummy parasymtable for unit initialization removed from
  2270. symtable stack
  2271. Revision 1.48 1998/09/07 22:25:53 peter
  2272. * fixed str(boolean,string) which was allowed
  2273. * fixed write(' ':<int expression>) only constants where allowed :(
  2274. Revision 1.47 1998/09/07 18:46:10 peter
  2275. * update smartlinking, uses getdatalabel
  2276. * renamed ptree.value vars to value_str,value_real,value_set
  2277. Revision 1.46 1998/09/04 08:42:03 peter
  2278. * updated some error messages
  2279. Revision 1.45 1998/09/01 17:39:49 peter
  2280. + internal constant functions
  2281. Revision 1.44 1998/08/28 10:54:24 peter
  2282. * fixed smallset generation from elements, it has never worked before!
  2283. Revision 1.43 1998/08/23 16:07:24 florian
  2284. * internalerror with mod/div fixed
  2285. Revision 1.42 1998/08/21 14:08:50 pierre
  2286. + TEST_FUNCRET now default (old code removed)
  2287. works also for m68k (at least compiles)
  2288. Revision 1.41 1998/08/20 21:36:39 peter
  2289. * fixed 'with object do' bug
  2290. Revision 1.40 1998/08/20 09:26:41 pierre
  2291. + funcret setting in underproc testing
  2292. compile with _dTEST_FUNCRET
  2293. Revision 1.39 1998/08/18 16:48:48 pierre
  2294. * bug for -So proc assignment to p^rocvar fixed
  2295. Revision 1.38 1998/08/18 14:17:09 pierre
  2296. * bug about assigning the return value of a function to
  2297. a procvar fixed : warning
  2298. assigning a proc to a procvar need @ in FPC mode !!
  2299. * missing file/line info restored
  2300. Revision 1.37 1998/08/18 09:24:43 pierre
  2301. * small warning position bug fixed
  2302. * support_mmx switches splitting was missing
  2303. * rhide error and warning output corrected
  2304. Revision 1.36 1998/08/15 16:50:29 peter
  2305. * fixed proc()=expr which was not allowed anymore by my previous fix
  2306. Revision 1.35 1998/08/14 18:18:46 peter
  2307. + dynamic set contruction
  2308. * smallsets are now working (always longint size)
  2309. Revision 1.34 1998/08/13 11:00:12 peter
  2310. * fixed procedure<>procedure construct
  2311. Revision 1.33 1998/08/11 15:31:39 peter
  2312. * write extended to ppu file
  2313. * new version 0.99.7
  2314. Revision 1.32 1998/08/11 14:05:32 peter
  2315. * fixed sizeof(array of char)
  2316. Revision 1.31 1998/08/10 14:50:11 peter
  2317. + localswitches, moduleswitches, globalswitches splitting
  2318. Revision 1.30 1998/07/28 21:52:54 florian
  2319. + implementation of raise and try..finally
  2320. + some misc. exception stuff
  2321. Revision 1.29 1998/07/27 21:57:13 florian
  2322. * fix to allow tv like stream registration:
  2323. @tmenu.load doesn't work if load had parameters or if load was only
  2324. declared in an anchestor class of tmenu
  2325. Revision 1.28 1998/07/14 21:46:51 peter
  2326. * updated messages file
  2327. Revision 1.27 1998/06/25 14:04:23 peter
  2328. + internal inc/dec
  2329. Revision 1.26 1998/06/09 16:01:46 pierre
  2330. + added procedure directive parsing for procvars
  2331. (accepted are popstack cdecl and pascal)
  2332. + added C vars with the following syntax
  2333. var C calias 'true_c_name';(can be followed by external)
  2334. reason is that you must add the Cprefix
  2335. which is target dependent
  2336. Revision 1.25 1998/06/05 14:37:33 pierre
  2337. * fixes for inline for operators
  2338. * inline procedure more correctly restricted
  2339. Revision 1.24 1998/06/04 23:51:52 peter
  2340. * m68k compiles
  2341. + .def file creation moved to gendef.pas so it could also be used
  2342. for win32
  2343. Revision 1.23 1998/06/04 09:55:40 pierre
  2344. * demangled name of procsym reworked to become independant of the mangling scheme
  2345. Revision 1.22 1998/06/02 17:03:03 pierre
  2346. * with node corrected for objects
  2347. * small bugs for SUPPORT_MMX fixed
  2348. Revision 1.21 1998/05/27 19:45:05 peter
  2349. * symtable.pas splitted into includefiles
  2350. * symtable adapted for $ifdef NEWPPU
  2351. Revision 1.20 1998/05/26 07:53:59 pierre
  2352. * bug fix for empty sets (nil pd was dereferenced )
  2353. Revision 1.19 1998/05/25 17:11:43 pierre
  2354. * firstpasscount bug fixed
  2355. now all is already set correctly the first time
  2356. under EXTDEBUG try -gp to skip all other firstpasses
  2357. it works !!
  2358. * small bug fixes
  2359. - for smallsets with -dTESTSMALLSET
  2360. - some warnings removed (by correcting code !)
  2361. Revision 1.18 1998/05/23 01:21:20 peter
  2362. + aktasmmode, aktoptprocessor, aktoutputformat
  2363. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  2364. + $LIBNAME to set the library name where the unit will be put in
  2365. * splitted cgi386 a bit (codeseg to large for bp7)
  2366. * nasm, tasm works again. nasm moved to ag386nsm.pas
  2367. Revision 1.17 1998/05/22 12:37:03 carl
  2368. * crash bugfix (patched msanually to main branch)
  2369. Revision 1.16 1998/05/21 19:33:32 peter
  2370. + better procedure directive handling and only one table
  2371. Revision 1.15 1998/05/20 09:42:35 pierre
  2372. + UseTokenInfo now default
  2373. * unit in interface uses and implementation uses gives error now
  2374. * only one error for unknown symbol (uses lastsymknown boolean)
  2375. the problem came from the label code !
  2376. + first inlined procedures and function work
  2377. (warning there might be allowed cases were the result is still wrong !!)
  2378. * UseBrower updated gives a global list of all position of all used symbols
  2379. with switch -gb
  2380. Revision 1.14 1998/05/11 13:07:56 peter
  2381. + $ifdef NEWPPU for the new ppuformat
  2382. + $define GDB not longer required
  2383. * removed all warnings and stripped some log comments
  2384. * no findfirst/findnext anymore to remove smartlink *.o files
  2385. Revision 1.13 1998/05/06 08:38:45 pierre
  2386. * better position info with UseTokenInfo
  2387. UseTokenInfo greatly simplified
  2388. + added check for changed tree after first time firstpass
  2389. (if we could remove all the cases were it happen
  2390. we could skip all firstpass if firstpasscount > 1)
  2391. Only with ExtDebug
  2392. Revision 1.12 1998/05/05 12:05:42 florian
  2393. * problems with properties fixed
  2394. * crash fixed: i:=l when i and l are undefined, was a problem with
  2395. implementation of private/protected
  2396. Revision 1.11 1998/05/04 11:22:26 florian
  2397. * problem with DOM solved: it crashes when accessing a property in a method
  2398. Revision 1.10 1998/05/01 16:38:45 florian
  2399. * handling of private and protected fixed
  2400. + change_keywords_to_tp implemented to remove
  2401. keywords which aren't supported by tp
  2402. * break and continue are now symbols of the system unit
  2403. + widestring, longstring and ansistring type released
  2404. Revision 1.9 1998/04/29 10:33:58 pierre
  2405. + added some code for ansistring (not complete nor working yet)
  2406. * corrected operator overloading
  2407. * corrected nasm output
  2408. + started inline procedures
  2409. + added starstarn : use ** for exponentiation (^ gave problems)
  2410. + started UseTokenInfo cond to get accurate positions
  2411. Revision 1.8 1998/04/14 23:27:03 florian
  2412. + exclude/include with constant second parameter added
  2413. Revision 1.7 1998/04/09 23:02:15 florian
  2414. * small problems solved to get remake3 work
  2415. Revision 1.6 1998/04/09 22:16:35 florian
  2416. * problem with previous REGALLOC solved
  2417. * improved property support
  2418. Revision 1.5 1998/04/08 10:26:09 florian
  2419. * correct error handling of virtual constructors
  2420. * problem with new type declaration handling fixed
  2421. Revision 1.4 1998/04/07 22:45:05 florian
  2422. * bug0092, bug0115 and bug0121 fixed
  2423. + packed object/class/array
  2424. Revision 1.3 1998/04/07 13:19:46 pierre
  2425. * bugfixes for reset_gdb_info
  2426. in MEM parsing for go32v2
  2427. better external symbol creation
  2428. support for rhgdb.exe (lowercase file names)
  2429. }