pexpr.pas 100 KB

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