pexpr.pas 100 KB

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