pexpr.pas 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713
  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)^.para^.empty) 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
  1511. if 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. end
  1520. else
  1521. begin
  1522. disposetree(p1);
  1523. p1:=genzeronode(hnewn);
  1524. p1^.resulttype:=ppointerdef(pd)^.definition;
  1525. consume(_COMMA);
  1526. afterassignment:=false;
  1527. { determines the current object defintion }
  1528. classh:=pobjectdef(ppointerdef(pd)^.definition);
  1529. if classh^.deftype<>objectdef then
  1530. Message(parser_e_pointer_to_class_expected)
  1531. else
  1532. begin
  1533. { check for an abstract class }
  1534. if (oo_has_abstract in classh^.objectoptions) then
  1535. Message(sym_e_no_instance_of_abstract_object);
  1536. { search the constructor also in the symbol tables of
  1537. the parents }
  1538. sym:=nil;
  1539. while assigned(classh) do
  1540. begin
  1541. sym:=pvarsym(classh^.symtable^.search(pattern));
  1542. srsymtable:=classh^.symtable;
  1543. if assigned(sym) then
  1544. break;
  1545. classh:=classh^.childof;
  1546. end;
  1547. consume(_ID);
  1548. do_member_read(false,sym,p1,pd,again);
  1549. if (p1^.treetype<>calln) or
  1550. (assigned(p1^.procdefinition) and
  1551. (p1^.procdefinition^.proctypeoption<>potype_constructor)) then
  1552. Message(parser_e_expr_have_to_be_constructor_call);
  1553. end;
  1554. p1:=gensinglenode(newn,p1);
  1555. { set the resulttype }
  1556. p1^.resulttype:=pd2;
  1557. consume(_RKLAMMER);
  1558. end;
  1559. postfixoperators;
  1560. end;
  1561. _SELF : begin
  1562. again:=true;
  1563. consume(_SELF);
  1564. if not assigned(procinfo^._class) then
  1565. begin
  1566. p1:=genzeronode(errorn);
  1567. pd:=generrordef;
  1568. again:=false;
  1569. Message(parser_e_self_not_in_method);
  1570. end
  1571. else
  1572. begin
  1573. if (po_classmethod in aktprocsym^.definition^.procoptions) then
  1574. begin
  1575. { self in class methods is a class reference type }
  1576. pd:=new(pclassrefdef,init(procinfo^._class));
  1577. p1:=genselfnode(pd);
  1578. p1^.resulttype:=pd;
  1579. end
  1580. else
  1581. begin
  1582. p1:=genselfnode(procinfo^._class);
  1583. p1^.resulttype:=procinfo^._class;
  1584. end;
  1585. pd:=p1^.resulttype;
  1586. postfixoperators;
  1587. end;
  1588. end;
  1589. _INHERITED : begin
  1590. again:=true;
  1591. consume(_INHERITED);
  1592. if assigned(procinfo^._class) then
  1593. begin
  1594. classh:=procinfo^._class^.childof;
  1595. while assigned(classh) do
  1596. begin
  1597. srsymtable:=pobjectdef(classh)^.symtable;
  1598. sym:=pvarsym(srsymtable^.search(pattern));
  1599. if assigned(sym) then
  1600. begin
  1601. p1:=genzeronode(typen);
  1602. p1^.resulttype:=classh;
  1603. pd:=p1^.resulttype;
  1604. consume(_ID);
  1605. do_member_read(false,sym,p1,pd,again);
  1606. break;
  1607. end;
  1608. classh:=classh^.childof;
  1609. end;
  1610. if classh=nil then
  1611. begin
  1612. Message1(sym_e_id_no_member,pattern);
  1613. again:=false;
  1614. pd:=generrordef;
  1615. p1:=genzeronode(errorn);
  1616. end;
  1617. end
  1618. else
  1619. begin
  1620. Message(parser_e_generic_methods_only_in_methods);
  1621. again:=false;
  1622. pd:=generrordef;
  1623. p1:=genzeronode(errorn);
  1624. end;
  1625. postfixoperators;
  1626. end;
  1627. _INTCONST : begin
  1628. valint(pattern,l,code);
  1629. if code<>0 then
  1630. begin
  1631. val(pattern,d,code);
  1632. if code<>0 then
  1633. begin
  1634. Message(cg_e_invalid_integer);
  1635. consume(_INTCONST);
  1636. l:=1;
  1637. p1:=genordinalconstnode(l,s32bitdef);
  1638. end
  1639. else
  1640. begin
  1641. consume(_INTCONST);
  1642. p1:=genrealconstnode(d,bestrealdef^);
  1643. end;
  1644. end
  1645. else
  1646. begin
  1647. consume(_INTCONST);
  1648. p1:=genordinalconstnode(l,s32bitdef);
  1649. end;
  1650. end;
  1651. _REALNUMBER : begin
  1652. val(pattern,d,code);
  1653. if code<>0 then
  1654. begin
  1655. Message(parser_e_error_in_real);
  1656. d:=1.0;
  1657. end;
  1658. consume(_REALNUMBER);
  1659. p1:=genrealconstnode(d,bestrealdef^);
  1660. end;
  1661. _STRING : begin
  1662. pd:=string_dec;
  1663. { STRING can be also a type cast }
  1664. if token=_LKLAMMER then
  1665. begin
  1666. consume(_LKLAMMER);
  1667. p1:=comp_expr(true);
  1668. consume(_RKLAMMER);
  1669. p1:=gentypeconvnode(p1,pd);
  1670. p1^.explizit:=true;
  1671. { handle postfix operators here e.g. string(a)[10] }
  1672. again:=true;
  1673. postfixoperators;
  1674. end
  1675. else
  1676. p1:=gentypenode(pd,nil);
  1677. end;
  1678. _FILE : begin
  1679. pd:=cfiledef;
  1680. consume(_FILE);
  1681. { FILE can be also a type cast }
  1682. if token=_LKLAMMER then
  1683. begin
  1684. consume(_LKLAMMER);
  1685. p1:=comp_expr(true);
  1686. consume(_RKLAMMER);
  1687. p1:=gentypeconvnode(p1,pd);
  1688. p1^.explizit:=true;
  1689. { handle postfix operators here e.g. string(a)[10] }
  1690. again:=true;
  1691. postfixoperators;
  1692. end
  1693. else
  1694. p1:=gentypenode(pd,nil);
  1695. end;
  1696. _CSTRING : begin
  1697. p1:=genstringconstnode(pattern);
  1698. consume(_CSTRING);
  1699. end;
  1700. _CCHAR : begin
  1701. p1:=genordinalconstnode(ord(pattern[1]),cchardef);
  1702. consume(_CCHAR);
  1703. end;
  1704. _KLAMMERAFFE : begin
  1705. consume(_KLAMMERAFFE);
  1706. got_addrn:=true;
  1707. { support both @<x> and @(<x>) }
  1708. if token=_LKLAMMER then
  1709. begin
  1710. consume(_LKLAMMER);
  1711. p1:=factor(true);
  1712. consume(_RKLAMMER);
  1713. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1714. begin
  1715. { we need the resulttype }
  1716. { of the expression in pd }
  1717. do_firstpass(p1);
  1718. pd:=p1^.resulttype;
  1719. again:=true;
  1720. postfixoperators;
  1721. end;
  1722. end
  1723. else
  1724. p1:=factor(true);
  1725. got_addrn:=false;
  1726. p1:=gensinglenode(addrn,p1);
  1727. end;
  1728. _LKLAMMER : begin
  1729. consume(_LKLAMMER);
  1730. p1:=comp_expr(true);
  1731. consume(_RKLAMMER);
  1732. { it's not a good solution }
  1733. { but (a+b)^ makes some problems }
  1734. if token in [_CARET,_POINT,_LECKKLAMMER] then
  1735. begin
  1736. { we need the resulttype }
  1737. { of the expression in pd }
  1738. do_firstpass(p1);
  1739. pd:=p1^.resulttype;
  1740. again:=true;
  1741. postfixoperators;
  1742. end;
  1743. end;
  1744. _LECKKLAMMER : begin
  1745. consume(_LECKKLAMMER);
  1746. p1:=factor_read_set;
  1747. consume(_RECKKLAMMER);
  1748. end;
  1749. _PLUS : begin
  1750. consume(_PLUS);
  1751. p1:=factor(false);
  1752. end;
  1753. _MINUS : begin
  1754. consume(_MINUS);
  1755. p1:=factor(false);
  1756. p1:=gensinglenode(umminusn,p1);
  1757. end;
  1758. _NOT : begin
  1759. consume(_NOT);
  1760. p1:=factor(false);
  1761. p1:=gensinglenode(notn,p1);
  1762. end;
  1763. _TRUE : begin
  1764. consume(_TRUE);
  1765. p1:=genordinalconstnode(1,booldef);
  1766. end;
  1767. _FALSE : begin
  1768. consume(_FALSE);
  1769. p1:=genordinalconstnode(0,booldef);
  1770. end;
  1771. _NIL : begin
  1772. consume(_NIL);
  1773. p1:=genzeronode(niln);
  1774. end;
  1775. else
  1776. begin
  1777. p1:=genzeronode(errorn);
  1778. consume(token);
  1779. Message(cg_e_illegal_expression);
  1780. end;
  1781. end;
  1782. { generate error node if no node is created }
  1783. if not assigned(p1) then
  1784. p1:=genzeronode(errorn);
  1785. { tp7 procvar handling, but not if the next token
  1786. will be a := }
  1787. if (m_tp_procvar in aktmodeswitches) and
  1788. (token<>_ASSIGNMENT) then
  1789. check_tp_procvar(p1);
  1790. factor:=p1;
  1791. check_tokenpos;
  1792. end;
  1793. {****************************************************************************
  1794. Sub_Expr
  1795. ****************************************************************************}
  1796. type
  1797. Toperator_precedence=(opcompare,opaddition,opmultiply);
  1798. Ttok2nodeRec=record
  1799. tok : ttoken;
  1800. nod : ttreetyp;
  1801. end;
  1802. const
  1803. tok2nodes=23;
  1804. tok2node:array[1..tok2nodes] of ttok2noderec=(
  1805. (tok:_PLUS ;nod:addn),
  1806. (tok:_MINUS ;nod:subn),
  1807. (tok:_STAR ;nod:muln),
  1808. (tok:_SLASH ;nod:slashn),
  1809. (tok:_EQUAL ;nod:equaln),
  1810. (tok:_GT ;nod:gtn),
  1811. (tok:_LT ;nod:ltn),
  1812. (tok:_GTE ;nod:gten),
  1813. (tok:_LTE ;nod:lten),
  1814. (tok:_SYMDIF ;nod:symdifn),
  1815. (tok:_STARSTAR;nod:starstarn),
  1816. (tok:_CARET ;nod:caretn),
  1817. (tok:_UNEQUAL ;nod:unequaln),
  1818. (tok:_AS ;nod:asn),
  1819. (tok:_IN ;nod:inn),
  1820. (tok:_IS ;nod:isn),
  1821. (tok:_OR ;nod:orn),
  1822. (tok:_AND ;nod:andn),
  1823. (tok:_DIV ;nod:divn),
  1824. (tok:_MOD ;nod:modn),
  1825. (tok:_SHL ;nod:shln),
  1826. (tok:_SHR ;nod:shrn),
  1827. (tok:_XOR ;nod:xorn)
  1828. );
  1829. operator_levels:array[Toperator_precedence] of set of Ttoken=
  1830. ([_LT,_LTE,_GT,_GTE,_EQUAL,_UNEQUAL,_IN,_IS],
  1831. [_PLUS,_MINUS,_OR,_XOR],
  1832. [_CARET,_SYMDIF,_STARSTAR,_STAR,_SLASH,_DIV,_MOD,_AND,_SHL,_SHR,_AS]);
  1833. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):Ptree;
  1834. {Reads a subexpression while the operators are of the current precedence
  1835. level, or any higher level. Replaces the old term, simpl_expr and
  1836. simpl2_expr.}
  1837. var
  1838. low,high,mid : longint;
  1839. p1,p2 : Ptree;
  1840. oldt : Ttoken;
  1841. filepos : tfileposinfo;
  1842. begin
  1843. if pred_level=opmultiply then
  1844. p1:=factor(false)
  1845. else
  1846. p1:=sub_expr(succ(pred_level),true);
  1847. repeat
  1848. if (token in operator_levels[pred_level]) and
  1849. ((token<>_EQUAL) or accept_equal) then
  1850. begin
  1851. oldt:=token;
  1852. filepos:=tokenpos;
  1853. consume(token);
  1854. if pred_level=opmultiply then
  1855. p2:=factor(false)
  1856. else
  1857. p2:=sub_expr(succ(pred_level),true);
  1858. low:=1;
  1859. high:=tok2nodes;
  1860. while (low<high) do
  1861. begin
  1862. mid:=(low+high+1) shr 1;
  1863. if oldt<tok2node[mid].tok then
  1864. high:=mid-1
  1865. else
  1866. low:=mid;
  1867. end;
  1868. if tok2node[high].tok=oldt then
  1869. p1:=gennode(tok2node[high].nod,p1,p2)
  1870. else
  1871. p1:=gennode(nothingn,p1,p2);
  1872. set_tree_filepos(p1,filepos);
  1873. end
  1874. else
  1875. break;
  1876. until false;
  1877. sub_expr:=p1;
  1878. end;
  1879. function comp_expr(accept_equal : boolean):Ptree;
  1880. var
  1881. oldafterassignment : boolean;
  1882. p1 : ptree;
  1883. begin
  1884. oldafterassignment:=afterassignment;
  1885. afterassignment:=true;
  1886. p1:=sub_expr(opcompare,accept_equal);
  1887. afterassignment:=oldafterassignment;
  1888. comp_expr:=p1;
  1889. end;
  1890. function expr : ptree;
  1891. var
  1892. p1,p2 : ptree;
  1893. oldafterassignment : boolean;
  1894. oldp1 : ptree;
  1895. filepos : tfileposinfo;
  1896. begin
  1897. oldafterassignment:=afterassignment;
  1898. p1:=sub_expr(opcompare,true);
  1899. filepos:=tokenpos;
  1900. if (m_tp_procvar in aktmodeswitches) and
  1901. (token<>_ASSIGNMENT) then
  1902. check_tp_procvar(p1);
  1903. if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
  1904. afterassignment:=true;
  1905. oldp1:=p1;
  1906. case token of
  1907. _POINTPOINT : begin
  1908. consume(_POINTPOINT);
  1909. p2:=sub_expr(opcompare,true);
  1910. p1:=gennode(rangen,p1,p2);
  1911. end;
  1912. _ASSIGNMENT : begin
  1913. consume(_ASSIGNMENT);
  1914. { avoid a firstpass of a procedure if
  1915. it must be assigned to a procvar }
  1916. { should be recursive for a:=b:=c !!! }
  1917. if (p1^.resulttype<>nil) and (p1^.resulttype^.deftype=procvardef) then
  1918. begin
  1919. getprocvar:=true;
  1920. getprocvardef:=pprocvardef(p1^.resulttype);
  1921. end;
  1922. p2:=sub_expr(opcompare,true);
  1923. if getprocvar then
  1924. handle_procvar(getprocvardef,p2);
  1925. getprocvar:=false;
  1926. p1:=gennode(assignn,p1,p2);
  1927. end;
  1928. { this is the code for C like assignements }
  1929. { from an improvement of Peter Schaefer }
  1930. _PLUSASN : begin
  1931. consume(_PLUSASN );
  1932. p2:=sub_expr(opcompare,true);
  1933. p1:=gennode(assignn,p1,gennode(addn,getcopy(p1),p2));
  1934. { was first
  1935. p1:=gennode(assignn,p1,gennode(addn,p1,p2));
  1936. but disposetree assumes that we have a real
  1937. *** tree *** }
  1938. end;
  1939. _MINUSASN : begin
  1940. consume(_MINUSASN );
  1941. p2:=sub_expr(opcompare,true);
  1942. p1:=gennode(assignn,p1,gennode(subn,getcopy(p1),p2));
  1943. end;
  1944. _STARASN : begin
  1945. consume(_STARASN );
  1946. p2:=sub_expr(opcompare,true);
  1947. p1:=gennode(assignn,p1,gennode(muln,getcopy(p1),p2));
  1948. end;
  1949. _SLASHASN : begin
  1950. consume(_SLASHASN );
  1951. p2:=sub_expr(opcompare,true);
  1952. p1:=gennode(assignn,p1,gennode(slashn,getcopy(p1),p2));
  1953. end;
  1954. end;
  1955. afterassignment:=oldafterassignment;
  1956. if p1<>oldp1 then
  1957. set_tree_filepos(p1,filepos);
  1958. expr:=p1;
  1959. end;
  1960. function get_intconst:longint;
  1961. {Reads an expression, tries to evalute it and check if it is an integer
  1962. constant. Then the constant is returned.}
  1963. var
  1964. p:Ptree;
  1965. begin
  1966. p:=comp_expr(true);
  1967. do_firstpass(p);
  1968. if not codegenerror then
  1969. begin
  1970. if (p^.treetype<>ordconstn) and
  1971. (p^.resulttype^.deftype=orddef) and
  1972. not(Porddef(p^.resulttype)^.typ in [uvoid,uchar,bool8bit,bool16bit,bool32bit]) then
  1973. Message(cg_e_illegal_expression)
  1974. else
  1975. get_intconst:=p^.value;
  1976. end;
  1977. disposetree(p);
  1978. end;
  1979. function get_stringconst:string;
  1980. {Reads an expression, tries to evaluate it and checks if it is a string
  1981. constant. Then the constant is returned.}
  1982. var
  1983. p:Ptree;
  1984. begin
  1985. get_stringconst:='';
  1986. p:=comp_expr(true);
  1987. do_firstpass(p);
  1988. if p^.treetype<>stringconstn then
  1989. begin
  1990. if (p^.treetype=ordconstn) and is_char(p^.resulttype) then
  1991. get_stringconst:=char(p^.value)
  1992. else
  1993. Message(cg_e_illegal_expression);
  1994. end
  1995. else
  1996. get_stringconst:=strpas(p^.value_str);
  1997. disposetree(p);
  1998. end;
  1999. end.
  2000. {
  2001. $Log$
  2002. Revision 1.152 1999-10-27 16:06:19 peter
  2003. * check for object in extended new
  2004. Revision 1.151 1999/10/26 12:30:44 peter
  2005. * const parameter is now checked
  2006. * better and generic check if a node can be used for assigning
  2007. * export fixes
  2008. * procvar equal works now (it never had worked at least from 0.99.8)
  2009. * defcoll changed to linkedlist with pparaitem so it can easily be
  2010. walked both directions
  2011. Revision 1.150 1999/10/22 14:37:30 peter
  2012. * error when properties are passed to var parameters
  2013. Revision 1.149 1999/10/22 10:39:34 peter
  2014. * split type reading from pdecl to ptype unit
  2015. * parameter_dec routine is now used for procedure and procvars
  2016. Revision 1.148 1999/10/14 14:57:52 florian
  2017. - removed the hcodegen use in the new cg, use cgbase instead
  2018. Revision 1.147 1999/09/28 11:03:54 peter
  2019. * fixed result access in 'if result = XXX then'
  2020. * fixed const cr=chr(13)
  2021. Revision 1.146 1999/09/27 23:44:54 peter
  2022. * procinfo is now a pointer
  2023. * support for result setting in sub procedure
  2024. Revision 1.145 1999/09/27 11:59:42 peter
  2025. * fix for pointer reading in const with @type.method
  2026. Revision 1.144 1999/09/26 21:30:19 peter
  2027. + constant pointer support which can happend with typecasting like
  2028. const p=pointer(1)
  2029. * better procvar parsing in typed consts
  2030. Revision 1.143 1999/09/15 20:35:41 florian
  2031. * small fix to operator overloading when in MMX mode
  2032. + the compiler uses now fldz and fld1 if possible
  2033. + some fixes to floating point registers
  2034. + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
  2035. * .... ???
  2036. Revision 1.142 1999/09/13 16:26:32 peter
  2037. * fix crash with empty object as childs
  2038. Revision 1.141 1999/09/11 19:47:26 florian
  2039. * bug fix for @tobject.method, fixes bug 557, 605 and 606
  2040. Revision 1.140 1999/09/11 09:08:33 florian
  2041. * fixed bug 596
  2042. * fixed some problems with procedure variables and procedures of object,
  2043. especially in TP mode. Procedure of object doesn't apply only to classes,
  2044. it is also allowed for objects !!
  2045. Revision 1.139 1999/09/10 18:48:07 florian
  2046. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  2047. * most things for stored properties fixed
  2048. Revision 1.138 1999/09/07 08:01:20 peter
  2049. * @(<x>) support
  2050. Revision 1.137 1999/09/01 22:08:58 peter
  2051. * fixed crash with assigned()
  2052. Revision 1.136 1999/08/15 22:47:45 peter
  2053. * fixed property writeaccess which was buggy after my previous
  2054. subscribed property access
  2055. Revision 1.135 1999/08/14 00:38:56 peter
  2056. * hack to support property with record fields
  2057. Revision 1.134 1999/08/09 22:16:29 peter
  2058. * fixed crash after wrong para's with class contrustor
  2059. Revision 1.133 1999/08/05 16:53:04 peter
  2060. * V_Fatal=1, all other V_ are also increased
  2061. * Check for local procedure when assigning procvar
  2062. * fixed comment parsing because directives
  2063. * oldtp mode directives better supported
  2064. * added some messages to errore.msg
  2065. Revision 1.132 1999/08/04 13:49:45 florian
  2066. * new(...)^. is now allowed
  2067. Revision 1.131 1999/08/04 13:02:55 jonas
  2068. * all tokens now start with an underscore
  2069. * PowerPC compiles!!
  2070. Revision 1.130 1999/08/04 00:23:12 florian
  2071. * renamed i386asm and i386base to cpuasm and cpubase
  2072. Revision 1.129 1999/08/03 22:02:59 peter
  2073. * moved bitmask constants to sets
  2074. * some other type/const renamings
  2075. Revision 1.128 1999/08/03 13:50:17 michael
  2076. + Changes for alpha
  2077. Revision 1.127 1999/08/01 18:28:13 florian
  2078. * modifications for the new code generator
  2079. Revision 1.126 1999/07/30 12:28:40 peter
  2080. * fixed crash with unknown id and colon parameter in write
  2081. Revision 1.125 1999/07/27 23:42:14 peter
  2082. * indirect type referencing is now allowed
  2083. Revision 1.124 1999/07/23 21:31:42 peter
  2084. * fixed crash with resourcestring
  2085. Revision 1.123 1999/07/23 11:37:46 peter
  2086. * error for illegal type reference, instead of 10998
  2087. Revision 1.122 1999/07/22 09:37:52 florian
  2088. + resourcestring implemented
  2089. + start of longstring support
  2090. Revision 1.121 1999/07/16 10:04:35 peter
  2091. * merged
  2092. Revision 1.120 1999/07/06 22:38:11 florian
  2093. * another fix for TP/Delphi styled procedure variables
  2094. Revision 1.119 1999/07/05 20:13:16 peter
  2095. * removed temp defines
  2096. Revision 1.118 1999/07/01 21:33:57 peter
  2097. * merged
  2098. Revision 1.117 1999/06/30 15:43:20 florian
  2099. * two bugs regarding method variables fixed
  2100. - if you take in a method the address of another method
  2101. don't need self anymore
  2102. - if the class pointer was in a register, wrong code for a method
  2103. variable load was generated
  2104. Revision 1.116 1999/06/26 00:24:53 pierre
  2105. * mereg from fixes-0_99_12 branch
  2106. Revision 1.112.2.8 1999/07/16 09:54:57 peter
  2107. * @procvar support in tp7 mode works again
  2108. Revision 1.112.2.7 1999/07/07 07:53:10 michael
  2109. + Merged patches from florian
  2110. Revision 1.112.2.6 1999/07/01 21:31:59 peter
  2111. * procvar fixes again
  2112. Revision 1.112.2.5 1999/07/01 15:17:17 peter
  2113. * methoidpointer fixes from florian
  2114. Revision 1.112.2.4 1999/06/26 00:22:30 pierre
  2115. * wrong warnings in -So mode suppressed
  2116. Revision 1.112.2.3 1999/06/17 12:51:44 pierre
  2117. * changed is_assignment_overloaded into
  2118. function assignment_overloaded : pprocdef
  2119. to allow overloading of assignment with only different result type
  2120. Revision 1.112.2.2 1999/06/15 18:54:52 peter
  2121. * more procvar fixes
  2122. Revision 1.112.2.1 1999/06/13 22:38:09 peter
  2123. * tp_procvar check for loading of procvars when getaddr=false
  2124. Revision 1.112 1999/06/02 22:44:11 pierre
  2125. * previous wrong log corrected
  2126. Revision 1.111 1999/06/02 22:25:43 pierre
  2127. * changed $ifdef FPC @ into $ifndef TP
  2128. * changes for correct procvar handling under tp mode
  2129. Revision 1.110 1999/06/01 19:27:55 peter
  2130. * better checks for procvar and methodpointer
  2131. Revision 1.109 1999/05/27 19:44:46 peter
  2132. * removed oldasm
  2133. * plabel -> pasmlabel
  2134. * -a switches to source writing automaticly
  2135. * assembler readers OOPed
  2136. * asmsymbol automaticly external
  2137. * jumptables and other label fixes for asm readers
  2138. Revision 1.108 1999/05/18 14:15:54 peter
  2139. * containsself fixes
  2140. * checktypes()
  2141. Revision 1.107 1999/05/18 09:52:18 peter
  2142. * procedure of object and addrn fixes
  2143. Revision 1.106 1999/05/16 17:06:31 peter
  2144. * remove firstcallparan which looks obsolete
  2145. Revision 1.105 1999/05/12 22:36:09 florian
  2146. * override isn't allowed in objects!
  2147. Revision 1.104 1999/05/07 10:35:23 florian
  2148. * first fix for a problem with method pointer properties, still doesn't work
  2149. with WITH
  2150. Revision 1.103 1999/05/06 21:40:16 peter
  2151. * fixed crash
  2152. Revision 1.101 1999/05/06 09:05:21 peter
  2153. * generic write_float and str_float
  2154. * fixed constant float conversions
  2155. Revision 1.100 1999/05/04 21:44:57 florian
  2156. * changes to compile it with Delphi 4.0
  2157. Revision 1.99 1999/05/01 13:24:31 peter
  2158. * merged nasm compiler
  2159. * old asm moved to oldasm/
  2160. Revision 1.98 1999/04/26 18:29:56 peter
  2161. * farpointerdef moved into pointerdef.is_far
  2162. Revision 1.97 1999/04/19 09:27:48 peter
  2163. * removed my property fix
  2164. Revision 1.96 1999/04/19 09:13:47 peter
  2165. * class property without write support
  2166. Revision 1.95 1999/04/19 06:10:08 florian
  2167. * property problem fixed: a propertysym is only a write
  2168. access if it is followed by a assignment token
  2169. Revision 1.94 1999/04/17 13:12:17 peter
  2170. * addr() internal
  2171. Revision 1.93 1999/04/15 09:00:08 peter
  2172. * fixed property write
  2173. Revision 1.92 1999/04/08 20:59:43 florian
  2174. * fixed problem with default properties which are a class
  2175. * case bug (from the mailing list with -O2) fixed, the
  2176. distance of the case labels can be greater than the positive
  2177. range of a longint => it is now a dword for fpc
  2178. Revision 1.91 1999/04/06 11:21:56 peter
  2179. * more use of ttoken
  2180. Revision 1.90 1999/03/31 13:55:12 peter
  2181. * assembler inlining working for ag386bin
  2182. Revision 1.89 1999/03/26 00:05:36 peter
  2183. * released valintern
  2184. + deffile is now removed when compiling is finished
  2185. * ^( compiles now correct
  2186. + static directive
  2187. * shrd fixed
  2188. Revision 1.88 1999/03/24 23:17:15 peter
  2189. * fixed bugs 212,222,225,227,229,231,233
  2190. Revision 1.87 1999/03/16 17:52:52 jonas
  2191. * changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
  2192. * in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
  2193. * in cgai386: also small fixes to emitrangecheck
  2194. Revision 1.86 1999/03/04 13:55:44 pierre
  2195. * some m68k fixes (still not compilable !)
  2196. * new(tobj) does not give warning if tobj has no VMT !
  2197. Revision 1.85 1999/02/22 15:09:39 florian
  2198. * behaviaor of PROTECTED and PRIVATE fixed, works now like TP/Delphi
  2199. Revision 1.84 1999/02/22 02:15:26 peter
  2200. * updates for ag386bin
  2201. Revision 1.83 1999/02/11 09:46:25 pierre
  2202. * fix for normal method calls inside static methods :
  2203. WARNING there were both parser and codegen errors !!
  2204. added static_call boolean to calln tree
  2205. Revision 1.82 1999/01/28 14:06:47 florian
  2206. * small fix for method pointers
  2207. * found the annoying strpas bug, mainly nested call to type cast which
  2208. use ansistrings crash
  2209. Revision 1.81 1999/01/27 00:13:55 florian
  2210. * "procedure of object"-stuff fixed
  2211. Revision 1.80 1999/01/21 16:41:01 pierre
  2212. * fix for constructor inside with statements
  2213. Revision 1.79 1998/12/30 22:15:48 peter
  2214. + farpointer type
  2215. * absolutesym now also stores if its far
  2216. Revision 1.78 1998/12/11 00:03:32 peter
  2217. + globtype,tokens,version unit splitted from globals
  2218. Revision 1.77 1998/12/04 10:18:09 florian
  2219. * some stuff for procedures of object added
  2220. * bug with overridden virtual constructors fixed (reported by Italo Gomes)
  2221. Revision 1.76 1998/11/27 14:50:40 peter
  2222. + open strings, $P switch support
  2223. Revision 1.75 1998/11/25 19:12:51 pierre
  2224. * var:=new(pointer_type) support added
  2225. Revision 1.74 1998/11/13 10:18:11 peter
  2226. + nil constants
  2227. Revision 1.73 1998/11/05 12:02:52 peter
  2228. * released useansistring
  2229. * removed -Sv, its now available in fpc modes
  2230. Revision 1.72 1998/11/04 10:11:41 peter
  2231. * ansistring fixes
  2232. Revision 1.71 1998/10/22 23:57:29 peter
  2233. * fixed filedef for typenodetype
  2234. Revision 1.70 1998/10/21 15:12:54 pierre
  2235. * bug fix for IOCHECK inside a procedure with iocheck modifier
  2236. * removed the GPF for unexistant overloading
  2237. (firstcall was called with procedinition=nil !)
  2238. * changed typen to what Florian proposed
  2239. gentypenode(p : pdef) sets the typenodetype field
  2240. and resulttype is only set if inside bt_type block !
  2241. Revision 1.69 1998/10/20 15:10:19 pierre
  2242. * type ptree only allowed inside expression
  2243. if following sizeof typeof low high or as first arg of new !!
  2244. Revision 1.68 1998/10/20 11:15:44 pierre
  2245. * calling of private method allowed inside child object method
  2246. Revision 1.67 1998/10/19 08:54:57 pierre
  2247. * wrong stabs info corrected once again !!
  2248. + variable vmt offset with vmt field only if required
  2249. implemented now !!!
  2250. Revision 1.66 1998/10/15 15:13:28 pierre
  2251. + added oo_hasconstructor and oo_hasdestructor
  2252. for objects options
  2253. Revision 1.65 1998/10/13 13:10:24 peter
  2254. * new style for m68k/i386 infos and enums
  2255. Revision 1.64 1998/10/12 12:20:55 pierre
  2256. + added tai_const_symbol_offset
  2257. for r : pointer = @var.field;
  2258. * better message for different arg names on implementation
  2259. of function
  2260. Revision 1.63 1998/10/12 10:28:30 florian
  2261. + auto dereferencing of pointers to structured types in delphi mode
  2262. Revision 1.62 1998/10/12 10:05:41 peter
  2263. * fixed mem leak with arrayconstrutor
  2264. Revision 1.61 1998/10/05 13:57:15 peter
  2265. * crash preventions
  2266. Revision 1.60 1998/10/05 12:32:46 peter
  2267. + assert() support
  2268. Revision 1.59 1998/10/01 14:56:24 peter
  2269. * crash preventions
  2270. Revision 1.58 1998/09/30 07:40:35 florian
  2271. * better error recovering
  2272. Revision 1.57 1998/09/28 16:18:16 florian
  2273. * two fixes to get ansi strings work
  2274. Revision 1.56 1998/09/26 17:45:36 peter
  2275. + idtoken and only one token table
  2276. Revision 1.55 1998/09/24 23:49:10 peter
  2277. + aktmodeswitches
  2278. Revision 1.54 1998/09/23 15:46:39 florian
  2279. * problem with with and classes fixed
  2280. Revision 1.53 1998/09/23 09:58:54 peter
  2281. * first working array of const things
  2282. Revision 1.52 1998/09/20 09:38:45 florian
  2283. * hasharray for defs fixed
  2284. * ansistring code generation corrected (init/final, assignement)
  2285. Revision 1.51 1998/09/18 16:03:43 florian
  2286. * some changes to compile with Delphi
  2287. Revision 1.50 1998/09/17 13:41:18 pierre
  2288. sizeof(TPOINT) problem
  2289. Revision 1.49.2.1 1998/09/17 08:42:31 pierre
  2290. TPOINT sizeof fix
  2291. Revision 1.49 1998/09/09 11:50:53 pierre
  2292. * forward def are not put in record or objects
  2293. + added check for forwards also in record and objects
  2294. * dummy parasymtable for unit initialization removed from
  2295. symtable stack
  2296. Revision 1.48 1998/09/07 22:25:53 peter
  2297. * fixed str(boolean,string) which was allowed
  2298. * fixed write(' ':<int expression>) only constants where allowed :(
  2299. Revision 1.47 1998/09/07 18:46:10 peter
  2300. * update smartlinking, uses getdatalabel
  2301. * renamed ptree.value vars to value_str,value_real,value_set
  2302. Revision 1.46 1998/09/04 08:42:03 peter
  2303. * updated some error messages
  2304. Revision 1.45 1998/09/01 17:39:49 peter
  2305. + internal constant functions
  2306. Revision 1.44 1998/08/28 10:54:24 peter
  2307. * fixed smallset generation from elements, it has never worked before!
  2308. Revision 1.43 1998/08/23 16:07:24 florian
  2309. * internalerror with mod/div fixed
  2310. Revision 1.42 1998/08/21 14:08:50 pierre
  2311. + TEST_FUNCRET now default (old code removed)
  2312. works also for m68k (at least compiles)
  2313. Revision 1.41 1998/08/20 21:36:39 peter
  2314. * fixed 'with object do' bug
  2315. Revision 1.40 1998/08/20 09:26:41 pierre
  2316. + funcret setting in underproc testing
  2317. compile with _dTEST_FUNCRET
  2318. Revision 1.39 1998/08/18 16:48:48 pierre
  2319. * bug for -So proc assignment to p^rocvar fixed
  2320. Revision 1.38 1998/08/18 14:17:09 pierre
  2321. * bug about assigning the return value of a function to
  2322. a procvar fixed : warning
  2323. assigning a proc to a procvar need @ in FPC mode !!
  2324. * missing file/line info restored
  2325. Revision 1.37 1998/08/18 09:24:43 pierre
  2326. * small warning position bug fixed
  2327. * support_mmx switches splitting was missing
  2328. * rhide error and warning output corrected
  2329. Revision 1.36 1998/08/15 16:50:29 peter
  2330. * fixed proc()=expr which was not allowed anymore by my previous fix
  2331. Revision 1.35 1998/08/14 18:18:46 peter
  2332. + dynamic set contruction
  2333. * smallsets are now working (always longint size)
  2334. Revision 1.34 1998/08/13 11:00:12 peter
  2335. * fixed procedure<>procedure construct
  2336. Revision 1.33 1998/08/11 15:31:39 peter
  2337. * write extended to ppu file
  2338. * new version 0.99.7
  2339. Revision 1.32 1998/08/11 14:05:32 peter
  2340. * fixed sizeof(array of char)
  2341. Revision 1.31 1998/08/10 14:50:11 peter
  2342. + localswitches, moduleswitches, globalswitches splitting
  2343. Revision 1.30 1998/07/28 21:52:54 florian
  2344. + implementation of raise and try..finally
  2345. + some misc. exception stuff
  2346. Revision 1.29 1998/07/27 21:57:13 florian
  2347. * fix to allow tv like stream registration:
  2348. @tmenu.load doesn't work if load had parameters or if load was only
  2349. declared in an anchestor class of tmenu
  2350. Revision 1.28 1998/07/14 21:46:51 peter
  2351. * updated messages file
  2352. Revision 1.27 1998/06/25 14:04:23 peter
  2353. + internal inc/dec
  2354. Revision 1.26 1998/06/09 16:01:46 pierre
  2355. + added procedure directive parsing for procvars
  2356. (accepted are popstack cdecl and pascal)
  2357. + added C vars with the following syntax
  2358. var C calias 'true_c_name';(can be followed by external)
  2359. reason is that you must add the Cprefix
  2360. which is target dependent
  2361. Revision 1.25 1998/06/05 14:37:33 pierre
  2362. * fixes for inline for operators
  2363. * inline procedure more correctly restricted
  2364. Revision 1.24 1998/06/04 23:51:52 peter
  2365. * m68k compiles
  2366. + .def file creation moved to gendef.pas so it could also be used
  2367. for win32
  2368. Revision 1.23 1998/06/04 09:55:40 pierre
  2369. * demangled name of procsym reworked to become independant of the mangling scheme
  2370. Revision 1.22 1998/06/02 17:03:03 pierre
  2371. * with node corrected for objects
  2372. * small bugs for SUPPORT_MMX fixed
  2373. Revision 1.21 1998/05/27 19:45:05 peter
  2374. * symtable.pas splitted into includefiles
  2375. * symtable adapted for $ifdef NEWPPU
  2376. Revision 1.20 1998/05/26 07:53:59 pierre
  2377. * bug fix for empty sets (nil pd was dereferenced )
  2378. Revision 1.19 1998/05/25 17:11:43 pierre
  2379. * firstpasscount bug fixed
  2380. now all is already set correctly the first time
  2381. under EXTDEBUG try -gp to skip all other firstpasses
  2382. it works !!
  2383. * small bug fixes
  2384. - for smallsets with -dTESTSMALLSET
  2385. - some warnings removed (by correcting code !)
  2386. Revision 1.18 1998/05/23 01:21:20 peter
  2387. + aktasmmode, aktoptprocessor, aktoutputformat
  2388. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  2389. + $LIBNAME to set the library name where the unit will be put in
  2390. * splitted cgi386 a bit (codeseg to large for bp7)
  2391. * nasm, tasm works again. nasm moved to ag386nsm.pas
  2392. Revision 1.17 1998/05/22 12:37:03 carl
  2393. * crash bugfix (patched msanually to main branch)
  2394. Revision 1.16 1998/05/21 19:33:32 peter
  2395. + better procedure directive handling and only one table
  2396. Revision 1.15 1998/05/20 09:42:35 pierre
  2397. + UseTokenInfo now default
  2398. * unit in interface uses and implementation uses gives error now
  2399. * only one error for unknown symbol (uses lastsymknown boolean)
  2400. the problem came from the label code !
  2401. + first inlined procedures and function work
  2402. (warning there might be allowed cases were the result is still wrong !!)
  2403. * UseBrower updated gives a global list of all position of all used symbols
  2404. with switch -gb
  2405. Revision 1.14 1998/05/11 13:07:56 peter
  2406. + $ifdef NEWPPU for the new ppuformat
  2407. + $define GDB not longer required
  2408. * removed all warnings and stripped some log comments
  2409. * no findfirst/findnext anymore to remove smartlink *.o files
  2410. Revision 1.13 1998/05/06 08:38:45 pierre
  2411. * better position info with UseTokenInfo
  2412. UseTokenInfo greatly simplified
  2413. + added check for changed tree after first time firstpass
  2414. (if we could remove all the cases were it happen
  2415. we could skip all firstpass if firstpasscount > 1)
  2416. Only with ExtDebug
  2417. Revision 1.12 1998/05/05 12:05:42 florian
  2418. * problems with properties fixed
  2419. * crash fixed: i:=l when i and l are undefined, was a problem with
  2420. implementation of private/protected
  2421. Revision 1.11 1998/05/04 11:22:26 florian
  2422. * problem with DOM solved: it crashes when accessing a property in a method
  2423. Revision 1.10 1998/05/01 16:38:45 florian
  2424. * handling of private and protected fixed
  2425. + change_keywords_to_tp implemented to remove
  2426. keywords which aren't supported by tp
  2427. * break and continue are now symbols of the system unit
  2428. + widestring, longstring and ansistring type released
  2429. Revision 1.9 1998/04/29 10:33:58 pierre
  2430. + added some code for ansistring (not complete nor working yet)
  2431. * corrected operator overloading
  2432. * corrected nasm output
  2433. + started inline procedures
  2434. + added starstarn : use ** for exponentiation (^ gave problems)
  2435. + started UseTokenInfo cond to get accurate positions
  2436. Revision 1.8 1998/04/14 23:27:03 florian
  2437. + exclude/include with constant second parameter added
  2438. Revision 1.7 1998/04/09 23:02:15 florian
  2439. * small problems solved to get remake3 work
  2440. Revision 1.6 1998/04/09 22:16:35 florian
  2441. * problem with previous REGALLOC solved
  2442. * improved property support
  2443. Revision 1.5 1998/04/08 10:26:09 florian
  2444. * correct error handling of virtual constructors
  2445. * problem with new type declaration handling fixed
  2446. Revision 1.4 1998/04/07 22:45:05 florian
  2447. * bug0092, bug0115 and bug0121 fixed
  2448. + packed object/class/array
  2449. Revision 1.3 1998/04/07 13:19:46 pierre
  2450. * bugfixes for reset_gdb_info
  2451. in MEM parsing for go32v2
  2452. better external symbol creation
  2453. support for rhgdb.exe (lowercase file names)
  2454. }