pexpr.pas 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791
  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(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. cobjects,globals,scanner,aasm,pass_1,systems,
  35. hcodegen,types,verbose
  36. { parser specific stuff }
  37. ,pbase,pdecl
  38. { processor specific stuff }
  39. {$ifdef i386}
  40. ,i386
  41. {$endif}
  42. {$ifdef m68k}
  43. ,m68k
  44. {$endif}
  45. ;
  46. function parse_paras(_colon,in_prop_paras : boolean) : ptree;
  47. var
  48. p1,p2 : ptree;
  49. end_of_paras : ttoken;
  50. begin
  51. if in_prop_paras then
  52. end_of_paras:=RECKKLAMMER
  53. else
  54. end_of_paras:=RKLAMMER;
  55. if token=end_of_paras then
  56. begin
  57. parse_paras:=nil;
  58. exit;
  59. end;
  60. p2:=nil;
  61. inc(parsing_para_level);
  62. while true do
  63. begin
  64. p1:=expr;
  65. p2:=gencallparanode(p1,p2);
  66. { it's for the str(l:5,s); }
  67. if _colon and (token=COLON) then
  68. begin
  69. consume(COLON);
  70. p1:=expr;
  71. p2:=gencallparanode(p1,p2);
  72. p2^.is_colon_para:=true;
  73. if token=COLON then
  74. begin
  75. consume(COLON);
  76. p1:=expr;
  77. p2:=gencallparanode(p1,p2);
  78. p2^.is_colon_para:=true;
  79. end
  80. end;
  81. if token=COMMA then
  82. consume(COMMA)
  83. else
  84. break;
  85. end;
  86. dec(parsing_para_level);
  87. parse_paras:=p2;
  88. end;
  89. function statement_syssym(l : longint;var pd : pdef) : ptree;
  90. { const regnames:array[R_EAX..R_EDI] of string[3]=
  91. ('EAX','ECX','EDX','EBX','','','ESI','EDI'); }
  92. var
  93. p1,p2 : ptree;
  94. paras : ptree;
  95. prev_in_args : boolean;
  96. Store_valid : boolean;
  97. begin
  98. prev_in_args:=in_args;
  99. Store_valid:=Must_be_valid;
  100. case l of
  101. in_ord_x :
  102. begin
  103. consume(LKLAMMER);
  104. in_args:=true;
  105. Must_be_valid:=true;
  106. p1:=expr;
  107. consume(RKLAMMER);
  108. do_firstpass(p1);
  109. p1:=geninlinenode(in_ord_x,p1);
  110. do_firstpass(p1);
  111. statement_syssym := p1;
  112. pd:=p1^.resulttype;
  113. end;
  114. in_typeof_x : begin
  115. consume(LKLAMMER);
  116. in_args:=true;
  117. p1:=expr;
  118. consume(RKLAMMER);
  119. pd:=voidpointerdef;
  120. if p1^.treetype=typen then
  121. begin
  122. if (p1^.resulttype=nil) then
  123. begin
  124. Message(sym_e_type_mismatch);
  125. statement_syssym:=genzeronode(errorn);
  126. end
  127. else
  128. if p1^.resulttype^.deftype=objectdef then
  129. statement_syssym:=geninlinenode(in_typeof_x,p1)
  130. else
  131. begin
  132. Message(sym_e_type_mismatch);
  133. statement_syssym:=genzeronode(errorn);
  134. end;
  135. end
  136. else
  137. begin
  138. Must_be_valid:=false;
  139. do_firstpass(p1);
  140. if (p1^.resulttype=nil) then
  141. begin
  142. Message(sym_e_type_mismatch);
  143. statement_syssym:=genzeronode(errorn)
  144. end
  145. else
  146. if p1^.resulttype^.deftype=objectdef then
  147. statement_syssym:=geninlinenode(in_typeof_x,p1)
  148. else
  149. begin
  150. Message(sym_e_type_mismatch);
  151. statement_syssym:=genzeronode(errorn)
  152. end;
  153. end;
  154. end;
  155. in_sizeof_x : begin
  156. consume(LKLAMMER);
  157. in_args:=true;
  158. p1:=expr;
  159. consume(RKLAMMER);
  160. pd:=s32bitdef;
  161. if p1^.treetype=typen then
  162. begin
  163. statement_syssym:=genordinalconstnode(
  164. p1^.resulttype^.size,pd);
  165. { p1 not needed !}
  166. disposetree(p1);
  167. end
  168. else
  169. begin
  170. Must_be_valid:=false;
  171. do_firstpass(p1);
  172. if p1^.resulttype^.deftype<>objectdef then
  173. begin
  174. statement_syssym:=genordinalconstnode(
  175. p1^.resulttype^.size,pd);
  176. { p1 not needed !}
  177. disposetree(p1);
  178. end
  179. else
  180. begin
  181. statement_syssym:=geninlinenode(in_sizeof_x,p1);
  182. end;
  183. end;
  184. end;
  185. in_assigned_x : begin
  186. consume(LKLAMMER);
  187. in_args:=true;
  188. p1:=expr;
  189. Must_be_valid:=true;
  190. do_firstpass(p1);
  191. case p1^.resulttype^.deftype of
  192. pointerdef,procvardef,
  193. classrefdef:
  194. ;
  195. objectdef:
  196. if not(pobjectdef(p1^.resulttype)^.isclass) then
  197. Message(parser_e_illegal_parameter_list);
  198. else Message(parser_e_illegal_parameter_list);
  199. end;
  200. p2:=gencallparanode(p1,nil);
  201. p2:=geninlinenode(in_assigned_x,p2);
  202. consume(RKLAMMER);
  203. pd:=booldef;
  204. statement_syssym:=p2;
  205. end;
  206. in_ofs_x : begin
  207. consume(LKLAMMER);
  208. in_args:=true;
  209. p1:=expr;
  210. p1:=gensinglenode(addrn,p1);
  211. Must_be_valid:=false;
  212. do_firstpass(p1);
  213. { Ofs() returns a longint, not a pointer }
  214. p1^.resulttype:=u32bitdef;
  215. pd:=p1^.resulttype;
  216. consume(RKLAMMER);
  217. statement_syssym:=p1;
  218. end;
  219. in_seg_x : begin
  220. consume(LKLAMMER);
  221. in_args:=true;
  222. p1:=expr;
  223. do_firstpass(p1);
  224. if p1^.location.loc<>LOC_REFERENCE then
  225. Message(cg_e_illegal_expression);
  226. p1:=genordinalconstnode(0,s32bitdef);
  227. Must_be_valid:=false;
  228. pd:=s32bitdef;
  229. consume(RKLAMMER);
  230. statement_syssym:=p1;
  231. end;
  232. in_high_x,
  233. in_low_x : begin
  234. consume(LKLAMMER);
  235. in_args:=true;
  236. p1:=expr;
  237. do_firstpass(p1);
  238. Must_be_valid:=false;
  239. p2:=geninlinenode(l,p1);
  240. consume(RKLAMMER);
  241. pd:=s32bitdef;
  242. statement_syssym:=p2;
  243. end;
  244. in_succ_x,
  245. in_pred_x : begin
  246. consume(LKLAMMER);
  247. in_args:=true;
  248. p1:=expr;
  249. do_firstpass(p1);
  250. Must_be_valid:=false;
  251. p2:=geninlinenode(l,p1);
  252. consume(RKLAMMER);
  253. pd:=p1^.resulttype;
  254. statement_syssym:=p2;
  255. end;
  256. in_inc_x,
  257. in_dec_x : begin
  258. consume(LKLAMMER);
  259. in_args:=true;
  260. p1:=expr;
  261. p2:=gencallparanode(p1,nil);
  262. Must_be_valid:=false;
  263. if token=COMMA then
  264. begin
  265. consume(COMMA);
  266. p1:=expr;
  267. p2:=gencallparanode(p1,p2);
  268. end;
  269. statement_syssym:=geninlinenode(l,p2);
  270. consume(RKLAMMER);
  271. pd:=voiddef;
  272. end;
  273. in_concat_x : begin
  274. consume(LKLAMMER);
  275. in_args:=true;
  276. p2:=nil;
  277. while true do
  278. begin
  279. p1:=expr;
  280. Must_be_valid:=true;
  281. do_firstpass(p1);
  282. if not((p1^.resulttype^.deftype=stringdef) or
  283. ((p1^.resulttype^.deftype=orddef) and
  284. (porddef(p1^.resulttype)^.typ=uchar)
  285. )
  286. ) then Message(parser_e_illegal_parameter_list);
  287. if p2<>nil then
  288. p2:=gennode(addn,p2,p1)
  289. else p2:=p1;
  290. if token=COMMA then
  291. consume(COMMA)
  292. else break;
  293. end;
  294. consume(RKLAMMER);
  295. pd:=cstringdef;
  296. statement_syssym:=p2;
  297. end;
  298. in_read_x,
  299. in_readln_x : begin
  300. if token=LKLAMMER then
  301. begin
  302. consume(LKLAMMER);
  303. in_args:=true;
  304. Must_be_valid:=false;
  305. paras:=parse_paras(false,false);
  306. consume(RKLAMMER);
  307. end
  308. else
  309. paras:=nil;
  310. pd:=voiddef;
  311. p1:=geninlinenode(l,paras);
  312. do_firstpass(p1);
  313. statement_syssym := p1;
  314. end;
  315. in_write_x,
  316. in_writeln_x : begin
  317. if token=LKLAMMER then
  318. begin
  319. consume(LKLAMMER);
  320. in_args:=true;
  321. Must_be_valid:=true;
  322. paras:=parse_paras(true,false);
  323. consume(RKLAMMER);
  324. end
  325. else
  326. paras:=nil;
  327. pd:=voiddef;
  328. p1 := geninlinenode(l,paras);
  329. do_firstpass(p1);
  330. statement_syssym := p1;
  331. end;
  332. in_str_x_string : begin
  333. consume(LKLAMMER);
  334. in_args:=true;
  335. paras:=parse_paras(true,false);
  336. consume(RKLAMMER);
  337. p1 := geninlinenode(l,paras);
  338. do_firstpass(p1);
  339. statement_syssym := p1;
  340. pd:=voiddef;
  341. end;
  342. in_include_x_y,
  343. in_exclude_x_y:
  344. begin
  345. consume(LKLAMMER);
  346. in_args:=true;
  347. p1:=expr;
  348. Must_be_valid:=false;
  349. consume(COMMA);
  350. p2:=expr;
  351. { just a bit lisp feeling }
  352. statement_syssym:=geninlinenode(l,
  353. gencallparanode(p1,gencallparanode(p2,nil)));
  354. consume(RKLAMMER);
  355. pd:=voiddef;
  356. end;
  357. {in_val_x : begin
  358. consume(LKLAMMER);
  359. paras:=parse_paras(false);
  360. consume(RKLAMMER);
  361. p1 := geninlinenode(l,paras);
  362. do_firstpass(p1);
  363. statement_syssym := p1;
  364. pd:=voiddef;
  365. end; }
  366. else internalerror(15);
  367. end;
  368. in_args:=prev_in_args;
  369. Must_be_valid:=Store_valid;
  370. end;
  371. { reads the parameter for a subroutine call }
  372. procedure do_proc_call(getaddr : boolean;var again : boolean;var p1:Ptree;var pd:Pdef);
  373. var
  374. prev_in_args : boolean;
  375. prevafterassn : boolean;
  376. begin
  377. prev_in_args:=in_args;
  378. prevafterassn:=afterassignment;
  379. afterassignment:=false;
  380. { want we only determine the address of }
  381. { a subroutine }
  382. if not(getaddr) then
  383. begin
  384. if token=LKLAMMER then
  385. begin
  386. consume(LKLAMMER);
  387. in_args:=true;
  388. p1^.left:=parse_paras(false,false);
  389. consume(RKLAMMER);
  390. end
  391. else p1^.left:=nil;
  392. { do firstpass because we need the }
  393. { result type }
  394. do_firstpass(p1);
  395. end
  396. else
  397. begin
  398. { address operator @: }
  399. p1^.left:=nil;
  400. { forget pd }
  401. pd:=nil;
  402. { no postfix operators }
  403. again:=false;
  404. end;
  405. pd:=p1^.resulttype;
  406. in_args:=prev_in_args;
  407. afterassignment:=prevafterassn;
  408. end;
  409. { the following procedure handles the access to a property symbol }
  410. procedure handle_propertysym(sym : psym;var p1 : ptree;
  411. var pd : pdef);
  412. var
  413. paras : ptree;
  414. oldafterassignment : boolean;
  415. p2 : ptree;
  416. begin
  417. paras:=nil;
  418. { property parameters? }
  419. if token=LECKKLAMMER then
  420. begin
  421. consume(LECKKLAMMER);
  422. paras:=parse_paras(false,true);
  423. consume(RECKKLAMMER);
  424. end;
  425. { indexed property }
  426. if (ppropertysym(sym)^.options and ppo_indexed)<>0 then
  427. begin
  428. p2:=genordinalconstnode(ppropertysym(sym)^.index,s32bitdef);
  429. paras:=gencallparanode(p2,paras);
  430. end;
  431. if not(afterassignment) and not(in_args) then
  432. begin
  433. { write property: }
  434. { no result }
  435. pd:=voiddef;
  436. if assigned(ppropertysym(sym)^.writeaccesssym) then
  437. begin
  438. if ppropertysym(sym)^.writeaccesssym^.typ=procsym then
  439. begin
  440. { generate the method call }
  441. p1:=genmethodcallnode(pprocsym(
  442. ppropertysym(sym)^.writeaccesssym),
  443. ppropertysym(sym)^.writeaccesssym^.owner,p1);
  444. { we know the procedure to call, so
  445. force the usage of that procedure }
  446. p1^.procdefinition:=pprocdef(ppropertysym(sym)^.writeaccessdef);
  447. p1^.left:=paras;
  448. { to be on the save side }
  449. oldafterassignment:=afterassignment;
  450. consume(ASSIGNMENT);
  451. { read the expression }
  452. afterassignment:=true;
  453. p2:=expr;
  454. p1^.left:=gencallparanode(p2,p1^.left);
  455. afterassignment:=oldafterassignment;
  456. end
  457. else if ppropertysym(sym)^.writeaccesssym^.typ=varsym then
  458. begin
  459. if assigned(paras) then
  460. message(parser_e_no_paras_allowed);
  461. p1:=gensubscriptnode(pvarsym(
  462. ppropertysym(sym)^.readaccesssym),p1);
  463. { to be on the save side }
  464. oldafterassignment:=afterassignment;
  465. consume(ASSIGNMENT);
  466. { read the expression }
  467. afterassignment:=true;
  468. p2:=expr;
  469. p1:=gennode(assignn,p1,p2);
  470. afterassignment:=oldafterassignment;
  471. end
  472. else
  473. begin
  474. p1:=genzeronode(errorn);
  475. Message(parser_e_no_procedure_to_access_property);
  476. end;
  477. end
  478. else
  479. begin
  480. p1:=genzeronode(errorn);
  481. Message(parser_e_no_procedure_to_access_property);
  482. end;
  483. end
  484. else
  485. begin
  486. { read property: }
  487. pd:=ppropertysym(sym)^.proptype;
  488. if assigned(ppropertysym(sym)^.readaccesssym) then
  489. begin
  490. if ppropertysym(sym)^.readaccesssym^.typ=varsym then
  491. begin
  492. if assigned(paras) then
  493. message(parser_e_no_paras_allowed);
  494. p1:=gensubscriptnode(pvarsym(
  495. ppropertysym(sym)^.readaccesssym),p1);
  496. end
  497. else if ppropertysym(sym)^.readaccesssym^.typ=procsym then
  498. begin
  499. { generate the method call }
  500. p1:=genmethodcallnode(pprocsym(
  501. ppropertysym(sym)^.readaccesssym),
  502. ppropertysym(sym)^.readaccesssym^.owner,p1);
  503. { we know the procedure to call, so
  504. force the usage of that procedure }
  505. p1^.procdefinition:=pprocdef(ppropertysym(sym)^.readaccessdef);
  506. { insert paras }
  507. p1^.left:=paras;
  508. { if we should be delphi compatible }
  509. { then force type conversion }
  510. { }
  511. { isn't neccessary, the result types }
  512. { have to match excatly }
  513. {if cs_delphi2_compatible in aktswitches then
  514. p1:=gentypeconvnode(p1,pd);
  515. }
  516. end
  517. else
  518. begin
  519. p1:=genzeronode(errorn);
  520. Message(sym_e_type_mismatch);
  521. end;
  522. end
  523. else
  524. begin
  525. { error, no function to read property }
  526. p1:=genzeronode(errorn);
  527. Message(parser_e_no_procedure_to_access_property);
  528. end;
  529. end;
  530. end;
  531. { the ID token has to be consumed before calling this function }
  532. procedure do_member_read(const sym : psym;var p1 : ptree;
  533. var pd : pdef;var again : boolean);
  534. var
  535. static_name : string;
  536. isclassref : boolean;
  537. begin
  538. if sym=nil then
  539. begin
  540. Message(sym_e_id_no_member);
  541. disposetree(p1);
  542. p1:=genzeronode(errorn);
  543. { try to clean up }
  544. pd:=generrordef;
  545. again:=false;
  546. end
  547. else
  548. begin
  549. isclassref:=pd^.deftype=classrefdef;
  550. { we assume, that only procsyms and varsyms are in an object }
  551. { symbol table, for classes, properties are allowed }
  552. case sym^.typ of
  553. procsym:
  554. begin
  555. p1:=genmethodcallnode(pprocsym(sym),srsymtable,p1);
  556. do_proc_call(false,again,p1,pd);
  557. { now we know the real method e.g. we can check for }
  558. { a class method }
  559. if isclassref and ((p1^.procdefinition^.options and (poclassmethod or poconstructor))=0) then
  560. Message(parser_e_only_class_methods_via_class_ref);
  561. end;
  562. varsym:
  563. begin
  564. if isclassref then
  565. Message(parser_e_only_class_methods_via_class_ref);
  566. if (sym^.properties and sp_static)<>0 then
  567. begin
  568. static_name:=lowercase(srsymtable^.name^)+'_'+sym^.name;
  569. getsym(static_name,true);
  570. disposetree(p1);
  571. p1:=genloadnode(pvarsym(srsym),srsymtable);
  572. end
  573. else
  574. p1:=gensubscriptnode(pvarsym(sym),p1);
  575. pd:=pvarsym(sym)^.definition;
  576. end;
  577. propertysym:
  578. begin
  579. if isclassref then
  580. Message(parser_e_only_class_methods_via_class_ref);
  581. handle_propertysym(sym,p1,pd);
  582. end;
  583. else internalerror(16);
  584. end;
  585. end;
  586. end;
  587. function factor(getaddr : boolean) : ptree;
  588. var
  589. l : longint;
  590. p1,p2,p3 : ptree;
  591. code : word;
  592. pd,pd2 : pdef;
  593. unit_specific, again : boolean;
  594. static_name : string;
  595. sym : pvarsym;
  596. classh : pobjectdef;
  597. d : bestreal;
  598. constset : pconstset;
  599. propsym : ppropertysym;
  600. { p1 and p2 must contain valid values }
  601. procedure postfixoperators;
  602. begin
  603. while again do
  604. begin
  605. case token of
  606. CARET:
  607. begin
  608. consume(CARET);
  609. if pd^.deftype<>pointerdef then
  610. begin
  611. { ^ as binary operator is a problem!!!! (FK) }
  612. again:=false;
  613. Message(cg_e_invalid_qualifier);
  614. disposetree(p1);
  615. p1:=genzeronode(errorn);
  616. end
  617. else
  618. begin
  619. p1:=gensinglenode(derefn,p1);
  620. pd:=ppointerdef(pd)^.definition;
  621. end;
  622. end;
  623. LECKKLAMMER:
  624. begin
  625. if (pd^.deftype=objectdef) and
  626. pobjectdef(pd)^.isclass then
  627. begin
  628. { default property }
  629. propsym:=search_default_property(pobjectdef(pd));
  630. if not(assigned(propsym)) then
  631. begin
  632. disposetree(p1);
  633. p1:=genzeronode(errorn);
  634. again:=false;
  635. message(parser_e_no_default_property_available);
  636. end
  637. else
  638. begin
  639. p1:=nil;
  640. handle_propertysym(propsym,p1,pd);
  641. end;
  642. end
  643. else
  644. begin
  645. consume(LECKKLAMMER);
  646. repeat
  647. if (pd^.deftype<>arraydef) and
  648. (pd^.deftype<>stringdef) and
  649. (pd^.deftype<>pointerdef) then
  650. begin
  651. Message(cg_e_invalid_qualifier);
  652. disposetree(p1);
  653. p1:=genzeronode(errorn);
  654. again:=false;
  655. end
  656. else if (pd^.deftype=pointerdef) then
  657. begin
  658. p2:=expr;
  659. p1:=gennode(vecn,p1,p2);
  660. pd:=ppointerdef(pd)^.definition;
  661. end
  662. else
  663. begin
  664. p2:=expr;
  665. { support SEG:OFS for go32v2 Mem[] }
  666. if (target_info.target=target_GO32V2) and
  667. (p1^.treetype=loadn) and
  668. assigned(p1^.symtableentry) and
  669. assigned(p1^.symtableentry^.owner^.name) and
  670. (p1^.symtableentry^.owner^.name^='SYSTEM') and
  671. ((p1^.symtableentry^.name='MEM') or
  672. (p1^.symtableentry^.name='MEMW') or
  673. (p1^.symtableentry^.name='MEML')) then
  674. begin
  675. if (token=COLON) then
  676. begin
  677. consume(COLON);
  678. p3:=gennode(muln,genordinalconstnode($10,s32bitdef),p2);
  679. p2:=expr;
  680. p2:=gennode(addn,p2,p3);
  681. p1:=gennode(vecn,p1,p2);
  682. p1^.memseg:=true;
  683. p1^.memindex:=true;
  684. end
  685. else
  686. begin
  687. p1:=gennode(vecn,p1,p2);
  688. p1^.memindex:=true;
  689. end;
  690. end
  691. { else
  692. if (target_info.target=target_GO32V2) and
  693. assigned(p1^.symtableentry) and
  694. assigned(p1^.symtableentry^.owner^.name) and
  695. (p1^.symtableentry^.owner^.name^='SYSTEM') and
  696. ((p1^.symtableentry^.name='PORT') or
  697. (p1^.symtableentry^.name='PORTW') or
  698. (p1^.symtableentry^.name='PORTL')) then
  699. begin
  700. p1:=gennode(vecn,p1,p2);
  701. p1^.portindex:=true;
  702. p
  703. end;
  704. end }
  705. else
  706. p1:=gennode(vecn,p1,p2);
  707. if pd^.deftype=stringdef then
  708. pd:=cchardef
  709. else
  710. pd:=parraydef(pd)^.definition;
  711. end;
  712. if token=COMMA then consume(COMMA)
  713. else break;
  714. until false;
  715. consume(RECKKLAMMER);
  716. end;
  717. end;
  718. POINT:
  719. begin
  720. consume(POINT);
  721. case pd^.deftype of
  722. recorddef:
  723. begin
  724. sym:=pvarsym(precdef(pd)^.symtable^.search(pattern));
  725. consume(ID);
  726. if sym=nil then
  727. begin
  728. Message(sym_e_illegal_field);
  729. disposetree(p1);
  730. p1:=genzeronode(errorn);
  731. end
  732. else
  733. begin
  734. p1:=gensubscriptnode(sym,p1);
  735. pd:=sym^.definition;
  736. end;
  737. end;
  738. classrefdef:
  739. begin
  740. classh:=pobjectdef(pclassrefdef(pd)^.definition);
  741. sym:=nil;
  742. while assigned(classh) do
  743. begin
  744. sym:=pvarsym(classh^.publicsyms^.search(pattern));
  745. srsymtable:=classh^.publicsyms;
  746. if assigned(sym) then
  747. break;
  748. classh:=classh^.childof;
  749. end;
  750. consume(ID);
  751. do_member_read(sym,p1,pd,again);
  752. end;
  753. objectdef:
  754. begin
  755. classh:=pobjectdef(pd);
  756. sym:=nil;
  757. while assigned(classh) do
  758. begin
  759. sym:=pvarsym(classh^.publicsyms^.search(pattern));
  760. srsymtable:=classh^.publicsyms;
  761. if assigned(sym) then
  762. break;
  763. classh:=classh^.childof;
  764. end;
  765. consume(ID);
  766. do_member_read(sym,p1,pd,again);
  767. end;
  768. pointerdef:
  769. begin
  770. if ppointerdef(pd)^.definition^.deftype
  771. in [recorddef,objectdef,classrefdef] then
  772. begin
  773. Message(cg_e_invalid_qualifier);
  774. { exterror:=strpnew(' may be pointer deref ^ is missing');
  775. error(invalid_qualifizier); }
  776. Comment(V_hint,' may be pointer deref ^ is missing');
  777. end
  778. else
  779. Message(cg_e_invalid_qualifier);
  780. end
  781. else
  782. begin
  783. Message(cg_e_invalid_qualifier);
  784. disposetree(p1);
  785. p1:=genzeronode(errorn);
  786. end;
  787. end;
  788. end;
  789. else
  790. begin
  791. { is this a procedure variable ? }
  792. if assigned(pd) then
  793. begin
  794. if (pd^.deftype=procvardef) then
  795. begin
  796. if getprocvar then
  797. again:=false
  798. else
  799. if (token=LKLAMMER) or
  800. ((pprocvardef(pd)^.para1=nil) and
  801. (token<>ASSIGNMENT) and (not in_args)) then
  802. begin
  803. { do this in a strange way }
  804. { it's not a clean solution }
  805. p2:=p1;
  806. p1:=gencallnode(nil,
  807. nil);
  808. p1^.right:=p2;
  809. p1^.unit_specific:=unit_specific;
  810. if token=LKLAMMER then
  811. begin
  812. consume(LKLAMMER);
  813. p1^.left:=parse_paras(false,false);
  814. consume(RKLAMMER);
  815. end;
  816. pd:=pprocvardef(pd)^.retdef;
  817. p1^.resulttype:=pd;
  818. end
  819. else again:=false;
  820. p1^.resulttype:=pd;
  821. end
  822. else again:=false;
  823. end
  824. else again:=false;
  825. end;
  826. end;
  827. end;
  828. end;
  829. procedure do_set(p : pconstset;pos : longint);
  830. var
  831. l : longint;
  832. begin
  833. if (pos>255) or
  834. (pos<0) then
  835. Message(parser_e_illegal_set_expr);
  836. l:=pos div 8;
  837. { do we allow the same twice }
  838. if (p^[l] and (1 shl (pos mod 8)))<>0 then
  839. Message(parser_e_illegal_set_expr);
  840. p^[l]:=p^[l] or (1 shl (pos mod 8));
  841. end;
  842. var
  843. possible_error : boolean;
  844. storesymtablestack : psymtable;
  845. actprocsym : pprocsym;
  846. begin
  847. case token of
  848. ID:
  849. begin
  850. { allow post fix operators }
  851. again:=true;
  852. if (cs_delphi2_compatible in aktswitches) and
  853. (pattern='RESULT') and
  854. assigned(aktprocsym) and
  855. (procinfo.retdef<>pdef(voiddef)) then
  856. begin
  857. consume(ID);
  858. p1:=genzeronode(funcretn);
  859. pd:=procinfo.retdef;
  860. {$ifdef TEST_FUNCRET}
  861. p1^.funcretprocinfo:=pointer(@procinfo);
  862. p1^.retdef:=pd;
  863. {$endif TEST_FUNCRET}
  864. end
  865. else
  866. begin
  867. getsym(pattern,true);
  868. consume(ID);
  869. { is this an access to a function result ? }
  870. if assigned(aktprocsym) and
  871. ((srsym^.name=aktprocsym^.name) or
  872. ((pvarsym(srsym)=opsym) and
  873. ((pprocdef(aktprocsym^.definition)^.options and pooperator)<>0))) and
  874. (procinfo.retdef<>pdef(voiddef)) and
  875. (token<>LKLAMMER) and
  876. (not ((cs_tp_compatible in aktswitches) and
  877. (afterassignment or in_args))) then
  878. begin
  879. p1:=genzeronode(funcretn);
  880. pd:=procinfo.retdef;
  881. {$ifdef TEST_FUNCRET}
  882. p1^.funcretprocinfo:=pointer(@procinfo);
  883. p1^.retdef:=pd;
  884. {$endif TEST_FUNCRET}
  885. end
  886. else
  887. { else it's a normal symbol }
  888. begin
  889. if srsym^.typ=unitsym then
  890. begin
  891. consume(POINT);
  892. getsymonlyin(punitsym(srsym)^.unitsymtable,pattern);
  893. unit_specific:=true;
  894. consume(ID);
  895. end
  896. else
  897. unit_specific:=false;
  898. case srsym^.typ of
  899. absolutesym:
  900. begin
  901. p1:=genloadnode(pvarsym(srsym),srsymtable);
  902. pd:=pabsolutesym(srsym)^.definition;
  903. end;
  904. varsym:
  905. begin
  906. { are we in a class method ? }
  907. if (srsymtable^.symtabletype=objectsymtable) and
  908. assigned(aktprocsym) and
  909. ((aktprocsym^.definition^.options and poclassmethod)<>0) then
  910. Message(parser_e_only_class_methods);
  911. if (srsym^.properties and sp_static)<>0 then
  912. begin
  913. static_name:=lowercase(srsymtable^.name^)+'_'+srsym^.name;
  914. getsym(static_name,true);
  915. end;
  916. p1:=genloadnode(pvarsym(srsym),srsymtable);
  917. if pvarsym(srsym)^.is_valid=0 then
  918. begin
  919. p1^.is_first := true;
  920. { set special between first loaded
  921. until checked in firstpass }
  922. pvarsym(srsym)^.is_valid:=2;
  923. end;
  924. pd:=pvarsym(srsym)^.definition;
  925. end;
  926. typedconstsym:
  927. begin
  928. p1:=gentypedconstloadnode(ptypedconstsym(srsym),srsymtable);
  929. pd:=ptypedconstsym(srsym)^.definition;
  930. end;
  931. syssym:
  932. p1:=statement_syssym(psyssym(srsym)^.number,pd);
  933. typesym:
  934. begin
  935. pd:=ptypesym(srsym)^.definition;
  936. { if we read a type declaration }
  937. { we have to return the type and }
  938. { nothing else }
  939. if block_type=bt_type then
  940. begin
  941. p1:=genzeronode(typen);
  942. p1^.resulttype:=pd;
  943. pd:=voiddef;
  944. end
  945. else
  946. begin
  947. if token=LKLAMMER then
  948. begin
  949. consume(LKLAMMER);
  950. p1:=expr;
  951. consume(RKLAMMER);
  952. p1:=gentypeconvnode(p1,pd);
  953. p1^.explizit:=true;
  954. end
  955. else if (token=POINT) and
  956. (pd^.deftype=objectdef) and
  957. ((pobjectdef(pd)^.options and oois_class)=0) then
  958. begin
  959. consume(POINT);
  960. if assigned(procinfo._class) then
  961. begin
  962. if procinfo._class^.isrelated(pobjectdef(pd)) then
  963. begin
  964. p1:=genzeronode(typen);
  965. p1^.resulttype:=pd;
  966. srsymtable:=pobjectdef(pd)^.publicsyms;
  967. sym:=pvarsym(srsymtable^.search(pattern));
  968. consume(ID);
  969. do_member_read(sym,p1,pd,again);
  970. end
  971. else
  972. begin
  973. Message(parser_e_no_super_class);
  974. pd:=generrordef;
  975. again:=false;
  976. end;
  977. end
  978. else
  979. begin
  980. { allows @TObject.Load }
  981. { also allows static methods and variables }
  982. p1:=genzeronode(typen);
  983. p1^.resulttype:=pd;
  984. srsymtable:=pobjectdef(pd)^.publicsyms;
  985. sym:=pvarsym(srsymtable^.search(pattern));
  986. if not(getaddr) and
  987. ((sym^.properties and sp_static)=0) then
  988. Message(sym_e_only_static_in_static)
  989. else
  990. begin
  991. consume(ID);
  992. do_member_read(sym,p1,pd,again);
  993. end;
  994. end
  995. end
  996. else
  997. begin
  998. { class reference ? }
  999. if (pd^.deftype=objectdef)
  1000. and ((pobjectdef(pd)^.options and oois_class)<>0) then
  1001. begin
  1002. p1:=genzeronode(typen);
  1003. p1^.resulttype:=pd;
  1004. pd:=new(pclassrefdef,init(pd));
  1005. p1:=gensinglenode(loadvmtn,p1);
  1006. p1^.resulttype:=pd;
  1007. end
  1008. else
  1009. begin
  1010. { generate a type node }
  1011. { (for typeof etc) }
  1012. p1:=genzeronode(typen);
  1013. p1^.resulttype:=pd;
  1014. pd:=voiddef;
  1015. end;
  1016. end;
  1017. end;
  1018. end;
  1019. enumsym:
  1020. begin
  1021. p1:=genenumnode(penumsym(srsym));
  1022. pd:=p1^.resulttype;
  1023. end;
  1024. constsym:
  1025. begin
  1026. case pconstsym(srsym)^.consttype of
  1027. constint:
  1028. p1:=genordinalconstnode(pconstsym(srsym)^.value,s32bitdef);
  1029. conststring:
  1030. p1:=genstringconstnode(pstring(pconstsym(srsym)^.value)^);
  1031. constchar:
  1032. p1:=genordinalconstnode(pconstsym(srsym)^.value,cchardef);
  1033. constreal:
  1034. p1:=genrealconstnode(pdouble(pconstsym(srsym)^.value)^);
  1035. constbool:
  1036. p1:=genordinalconstnode(pconstsym(srsym)^.value,booldef);
  1037. constseta:
  1038. p1:=gensetconstruktnode(pconstset(pconstsym(srsym)^.value),
  1039. psetdef(pconstsym(srsym)^.definition));
  1040. constord:
  1041. p1:=genordinalconstnode(pconstsym(srsym)^.value,
  1042. pconstsym(srsym)^.definition);
  1043. end;
  1044. pd:=p1^.resulttype;
  1045. end;
  1046. procsym:
  1047. begin
  1048. { are we in a class method ? }
  1049. possible_error:=(srsymtable^.symtabletype=objectsymtable) and
  1050. assigned(aktprocsym) and
  1051. ((aktprocsym^.definition^.options and poclassmethod)<>0);
  1052. p1:=gencallnode(pprocsym(srsym),srsymtable);
  1053. p1^.unit_specific:=unit_specific;
  1054. do_proc_call(getaddr,again,p1,pd);
  1055. if possible_error and
  1056. ((p1^.procdefinition^.options and poclassmethod)=0) then
  1057. Message(parser_e_only_class_methods);
  1058. end;
  1059. propertysym:
  1060. begin
  1061. { access to property in a method }
  1062. { are we in a class method ? }
  1063. if (srsymtable^.symtabletype=objectsymtable) and
  1064. assigned(aktprocsym) and
  1065. ((aktprocsym^.definition^.options and poclassmethod)<>0) then
  1066. Message(parser_e_only_class_methods);
  1067. { no method pointer }
  1068. p1:=nil;
  1069. handle_propertysym(srsym,p1,pd);
  1070. end;
  1071. errorsym:
  1072. begin
  1073. p1:=genzeronode(errorn);
  1074. pd:=generrordef;
  1075. if token=LKLAMMER then
  1076. begin
  1077. consume(LKLAMMER);
  1078. parse_paras(false,false);
  1079. consume(RKLAMMER);
  1080. end;
  1081. end;
  1082. else
  1083. begin
  1084. p1:=genzeronode(errorn);
  1085. pd:=generrordef;
  1086. Message(cg_e_illegal_expression);
  1087. end;
  1088. end;
  1089. end;
  1090. end;
  1091. { handle post fix operators }
  1092. postfixoperators;
  1093. end;
  1094. _NEW : begin
  1095. consume(_NEW);
  1096. consume(LKLAMMER);
  1097. p1:=factor(false);
  1098. if p1^.treetype<>typen then
  1099. Message(sym_e_type_id_expected);
  1100. pd:=p1^.resulttype;
  1101. pd2:=pd;
  1102. if (pd^.deftype<>pointerdef) or
  1103. (ppointerdef(pd)^.definition^.deftype<>objectdef) then
  1104. begin
  1105. Message(parser_e_pointer_to_class_expected);
  1106. { if an error occurs, read til the end of the new }
  1107. { statement }
  1108. p1:=genzeronode(errorn);
  1109. l:=1;
  1110. while true do
  1111. begin
  1112. case token of
  1113. LKLAMMER : inc(l);
  1114. RKLAMMER : dec(l);
  1115. end;
  1116. consume(token);
  1117. if l=0 then
  1118. break;
  1119. end;
  1120. end
  1121. else
  1122. begin
  1123. disposetree(p1);
  1124. p1:=genzeronode(hnewn);
  1125. p1^.resulttype:=ppointerdef(pd)^.definition;
  1126. consume(COMMA);
  1127. afterassignment:=false;
  1128. { determines the current object defintion }
  1129. classh:=pobjectdef(ppointerdef(pd)^.definition);
  1130. { check for an abstract class }
  1131. if (classh^.options and oois_abstract)<>0 then
  1132. Message(sym_e_no_instance_of_abstract_object);
  1133. { search the constructor also in the symbol tables of }
  1134. { the parents }
  1135. { no constructor found }
  1136. sym:=nil;
  1137. while assigned(classh) do
  1138. begin
  1139. sym:=pvarsym(classh^.publicsyms^.search(pattern));
  1140. srsymtable:=classh^.publicsyms;
  1141. if assigned(sym) then
  1142. break;
  1143. classh:=classh^.childof;
  1144. end;
  1145. consume(ID);
  1146. do_member_read(sym,p1,pd,again);
  1147. if (p1^.treetype<>calln) or
  1148. (assigned(p1^.procdefinition) and
  1149. ((p1^.procdefinition^.options and poconstructor)=0)) then
  1150. Message(parser_e_expr_have_to_be_constructor_call);
  1151. p1:=gensinglenode(newn,p1);
  1152. { set the resulttype }
  1153. p1^.resulttype:=pd2;
  1154. consume(RKLAMMER);
  1155. end;
  1156. end;
  1157. _SELF:
  1158. begin
  1159. again:=true;
  1160. consume(_SELF);
  1161. if not assigned(procinfo._class) then
  1162. begin
  1163. p1:=genzeronode(errorn);
  1164. pd:=generrordef;
  1165. again:=false;
  1166. Message(parser_e_self_not_in_method);
  1167. end
  1168. else
  1169. begin
  1170. if (aktprocsym^.definition^.options and poclassmethod)<>0 then
  1171. begin
  1172. { self in class methods is a class reference type }
  1173. pd:=new(pclassrefdef,init(procinfo._class));
  1174. p1:=genselfnode(pd);
  1175. p1^.resulttype:=pd;
  1176. end
  1177. else
  1178. begin
  1179. p1:=genselfnode(procinfo._class);
  1180. p1^.resulttype:=procinfo._class;
  1181. end;
  1182. pd:=p1^.resulttype;
  1183. postfixoperators;
  1184. end;
  1185. end;
  1186. _INHERITED : begin
  1187. again:=true;
  1188. consume(_INHERITED);
  1189. if assigned(procinfo._class) then
  1190. begin
  1191. classh:=procinfo._class^.childof;
  1192. while assigned(classh) do
  1193. begin
  1194. srsymtable:=pobjectdef(classh)^.publicsyms;
  1195. sym:=pvarsym(srsymtable^.search(pattern));
  1196. if assigned(sym) then
  1197. begin
  1198. p1:=genzeronode(typen);
  1199. p1^.resulttype:=classh;
  1200. pd:=p1^.resulttype;
  1201. consume(ID);
  1202. do_member_read(sym,p1,pd,again);
  1203. break;
  1204. end;
  1205. classh:=classh^.childof;
  1206. end;
  1207. if classh=nil then
  1208. begin
  1209. Message1(sym_e_id_no_member,pattern);
  1210. again:=false;
  1211. pd:=generrordef;
  1212. p1:=genzeronode(errorn);
  1213. end;
  1214. end
  1215. else
  1216. Message(parser_e_generic_methods_only_in_methods);
  1217. postfixoperators;
  1218. end;
  1219. INTCONST : begin
  1220. valint(pattern,l,code);
  1221. if code<>0 then
  1222. begin
  1223. val(pattern,d,code);
  1224. if code<>0 then
  1225. begin
  1226. Message(cg_e_invalid_integer);
  1227. l:=1;
  1228. consume(INTCONST);
  1229. p1:=genordinalconstnode(l,s32bitdef);
  1230. end
  1231. else
  1232. begin
  1233. consume(INTCONST);
  1234. p1:=genrealconstnode(d);
  1235. end;
  1236. end
  1237. else
  1238. begin
  1239. consume(INTCONST);
  1240. p1:=genordinalconstnode(l,s32bitdef);
  1241. end;
  1242. end;
  1243. REALNUMBER : begin
  1244. val(pattern,d,code);
  1245. if code<>0 then
  1246. begin
  1247. Message(parser_e_error_in_real);
  1248. d:=1.0;
  1249. end;
  1250. consume(REALNUMBER);
  1251. p1:=genrealconstnode(d);
  1252. end;
  1253. { FILE and STRING can be also a type cast }
  1254. _STRING:
  1255. begin
  1256. pd:=stringtype;
  1257. consume(LKLAMMER);
  1258. p1:=expr;
  1259. consume(RKLAMMER);
  1260. p1:=gentypeconvnode(p1,pd);
  1261. p1^.explizit:=true;
  1262. { handle postfix operators here e.g. string(a)[10] }
  1263. again:=true;
  1264. postfixoperators;
  1265. end;
  1266. _FILE:
  1267. begin
  1268. pd:=cfiledef;
  1269. consume(_FILE);
  1270. consume(LKLAMMER);
  1271. p1:=expr;
  1272. consume(RKLAMMER);
  1273. p1:=gentypeconvnode(p1,pd);
  1274. p1^.explizit:=true;
  1275. { handle postfix operators here e.g. string(a)[10] }
  1276. again:=true;
  1277. postfixoperators;
  1278. end;
  1279. CSTRING:
  1280. begin
  1281. p1:=genstringconstnode(pattern);
  1282. consume(CSTRING);
  1283. end;
  1284. CCHAR:
  1285. begin
  1286. p1:=genordinalconstnode(ord(pattern[1]),cchardef);
  1287. consume(CCHAR);
  1288. end;
  1289. KLAMMERAFFE : begin
  1290. consume(KLAMMERAFFE);
  1291. p1:=factor(true);
  1292. p1:=gensinglenode(addrn,p1);
  1293. end;
  1294. LKLAMMER : begin
  1295. consume(LKLAMMER);
  1296. p1:=expr;
  1297. consume(RKLAMMER);
  1298. { it's not a good solution }
  1299. { but (a+b)^ makes some problems }
  1300. case token of
  1301. CARET,POINT,LECKKLAMMER:
  1302. begin
  1303. { we need the resulttype }
  1304. { of the expression in pd }
  1305. do_firstpass(p1);
  1306. pd:=p1^.resulttype;
  1307. again:=true;
  1308. postfixoperators;
  1309. end;
  1310. end;
  1311. end;
  1312. LECKKLAMMER : begin
  1313. consume(LECKKLAMMER);
  1314. new(constset);
  1315. for l:=0 to 31 do
  1316. constset^[l]:=0;
  1317. p2:=nil;
  1318. pd:=nil;
  1319. if token<>RECKKLAMMER then
  1320. while true do
  1321. begin
  1322. p1:=expr;
  1323. do_firstpass(p1);
  1324. case p1^.treetype of
  1325. ordconstn : begin
  1326. if pd=nil then
  1327. pd:=p1^.resulttype;
  1328. if not(is_equal(pd,p1^.resulttype)) then
  1329. Message(parser_e_typeconflict_in_set)
  1330. else
  1331. do_set(constset,p1^.value);
  1332. disposetree(p1);
  1333. end;
  1334. rangen : begin
  1335. if pd=nil then
  1336. pd:=p1^.left^.resulttype;
  1337. if not(is_equal(pd,p1^.left^.resulttype)) then
  1338. Message(parser_e_typeconflict_in_set)
  1339. else
  1340. for l:=p1^.left^.value to p1^.right^.value do
  1341. do_set(constset,l);
  1342. disposetree(p1);
  1343. end;
  1344. stringconstn : begin
  1345. if pd=nil then
  1346. pd:=cchardef;
  1347. if not(is_equal(pd,cchardef)) then
  1348. Message(parser_e_typeconflict_in_set)
  1349. else
  1350. for l:=1 to length(pstring(p1^.values)^) do
  1351. do_set(constset,ord(pstring(p1^.values)^[l]));
  1352. disposetree(p1);
  1353. end;
  1354. else
  1355. begin
  1356. if pd=nil then
  1357. pd:=p1^.resulttype;
  1358. if not(is_equal(pd,p1^.resulttype)) then
  1359. Message(parser_e_typeconflict_in_set);
  1360. p2:=gennode(setelen,p1,p2);
  1361. end;
  1362. end;
  1363. if token=COMMA then
  1364. consume(COMMA)
  1365. else break;
  1366. end;
  1367. consume(RECKKLAMMER);
  1368. p1:=gensinglenode(setconstrn,p2);
  1369. p1^.resulttype:=new(psetdef,init(pd,255));
  1370. p1^.constset:=constset;
  1371. end;
  1372. PLUS : begin
  1373. consume(PLUS);
  1374. p1:=factor(false);
  1375. end;
  1376. MINUS : begin
  1377. consume(MINUS);
  1378. p1:=factor(false);
  1379. p1:=gensinglenode(umminusn,p1);
  1380. end;
  1381. _NOT : begin
  1382. consume(_NOT);
  1383. p1:=factor(false);
  1384. p1:=gensinglenode(notn,p1);
  1385. end;
  1386. _TRUE : begin
  1387. consume(_TRUE);
  1388. p1:=genordinalconstnode(1,booldef);
  1389. end;
  1390. _FALSE : begin
  1391. consume(_FALSE);
  1392. p1:=genordinalconstnode(0,booldef);
  1393. end;
  1394. _NIL : begin
  1395. consume(_NIL);
  1396. p1:=genzeronode(niln);
  1397. end;
  1398. else
  1399. begin
  1400. p1:=genzeronode(errorn);
  1401. consume(token);
  1402. Message(cg_e_illegal_expression);
  1403. end;
  1404. end;
  1405. factor:=p1;
  1406. end;
  1407. type Toperator_precedence=(opcompare,opaddition,opmultiply);
  1408. const tok2node:array[PLUS.._XOR] of Ttreetyp=
  1409. (addn,subn,muln,slashn,equaln,gtn,ltn,gten,lten,
  1410. isn,asn,inn,
  1411. nothingn,caretn,nothingn,unequaln,nothingn,
  1412. nothingn,nothingn,nothingn,nothingn,nothingn,
  1413. nothingn,nothingn,nothingn,nothingn,nothingn,
  1414. nothingn,nothingn,nothingn,nothingn,nothingn,
  1415. nothingn,andn,nothingn,nothingn,nothingn,
  1416. nothingn,nothingn,nothingn,nothingn,nothingn,
  1417. nothingn,nothingn,divn,nothingn,nothingn,
  1418. nothingn,nothingn,nothingn,nothingn,nothingn,
  1419. nothingn,nothingn,nothingn,nothingn,nothingn,
  1420. nothingn,nothingn,nothingn,nothingn,nothingn,
  1421. modn,nothingn,nothingn,nothingn,nothingn,
  1422. nothingn,nothingn,orn,
  1423. nothingn,nothingn,nothingn,nothingn,nothingn,
  1424. nothingn,nothingn,shln,shrn,
  1425. nothingn,nothingn,nothingn,nothingn,nothingn,
  1426. nothingn,nothingn,nothingn,nothingn,nothingn,
  1427. nothingn,xorn);
  1428. operator_levels:array[Toperator_precedence] of set of Ttoken=
  1429. ([LT,LTE,GT,GTE,EQUAL,UNEQUAL,_IN,_IS],
  1430. [PLUS,MINUS,_OR,_XOR],
  1431. [CARET,SYMDIF,STAR,SLASH,_DIV,_MOD,_AND,_SHL,_SHR,_AS]);
  1432. function sub_expr(pred_level:Toperator_precedence;accept_equal : boolean):Ptree;
  1433. {Reads a subexpression while the operators are of the current precedence
  1434. level, or any higher level. Replaces the old term, simpl_expr and
  1435. simpl2_expr.}
  1436. var p1,p2:Ptree;
  1437. oldt:Ttoken;
  1438. begin
  1439. { if pred_level=high(Toperator_precedence) then }
  1440. if pred_level=opmultiply then
  1441. p1:=factor(getprocvar)
  1442. else
  1443. p1:=sub_expr(succ(pred_level),true);
  1444. repeat
  1445. { aweful hack to support const a : 1..2=1; }
  1446. { disadvantage of tables :) FK }
  1447. if (token in operator_levels[pred_level]) and
  1448. ((token<>EQUAL) or accept_equal) then
  1449. begin
  1450. oldt:=token;
  1451. consume(token);
  1452. { if pred_level=high(Toperator_precedence) then }
  1453. if pred_level=opmultiply then
  1454. p2:=factor(getprocvar)
  1455. else
  1456. p2:=sub_expr(succ(pred_level),true);
  1457. p1:=gennode(tok2node[oldt],p1,p2);
  1458. end
  1459. else
  1460. break;
  1461. until false;
  1462. sub_expr:=p1;
  1463. end;
  1464. function comp_expr(accept_equal : boolean):Ptree;
  1465. begin
  1466. comp_expr:=sub_expr(opcompare,accept_equal);
  1467. end;
  1468. function expr : ptree;
  1469. var
  1470. p1,p2 : ptree;
  1471. oldafterassignment : boolean;
  1472. begin
  1473. oldafterassignment:=afterassignment;
  1474. p1:=sub_expr(opcompare,true);
  1475. if token in [ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
  1476. afterassignment:=true;
  1477. case token of
  1478. POINTPOINT : begin
  1479. consume(POINTPOINT);
  1480. p2:=sub_expr(opcompare,true);
  1481. p1:=gennode(rangen,p1,p2);
  1482. end;
  1483. ASSIGNMENT : begin
  1484. consume(ASSIGNMENT);
  1485. { avoid a firstpass of a procedure if
  1486. it must be assigned to a procvar }
  1487. { should be recursive for a:=b:=c !!! }
  1488. if (p1^.resulttype<>nil) and (p1^.resulttype^.deftype=procvardef) then
  1489. getprocvar:=true;
  1490. p2:=sub_expr(opcompare,true);
  1491. if getprocvar and (p2^.treetype=calln) then
  1492. begin
  1493. p2^.treetype:=loadn;
  1494. p2^.resulttype:=pprocsym(p2^.symtableprocentry)^.definition;
  1495. p2^.symtableentry:=p2^.symtableprocentry;
  1496. end;
  1497. getprocvar:=false;
  1498. p1:=gennode(assignn,p1,p2);
  1499. end;
  1500. { this is the code for C like assignements }
  1501. { from an improvement of Peter Schaefer }
  1502. _PLUSASN : begin
  1503. consume(_PLUSASN );
  1504. p2:=sub_expr(opcompare,true);
  1505. p1:=gennode(assignn,p1,gennode(addn,getcopy(p1),p2));
  1506. { was first
  1507. p1:=gennode(assignn,p1,gennode(addn,p1,p2));
  1508. but disposetree assumes that we have a real
  1509. *** tree *** }
  1510. end;
  1511. _MINUSASN : begin
  1512. consume(_MINUSASN );
  1513. p2:=sub_expr(opcompare,true);
  1514. p1:=gennode(assignn,p1,gennode(subn,getcopy(p1),p2));
  1515. end;
  1516. _STARASN : begin
  1517. consume(_STARASN );
  1518. p2:=sub_expr(opcompare,true);
  1519. p1:=gennode(assignn,p1,gennode(muln,getcopy(p1),p2));
  1520. end;
  1521. _SLASHASN : begin
  1522. consume(_SLASHASN );
  1523. p2:=sub_expr(opcompare,true);
  1524. p1:=gennode(assignn,p1,gennode(slashn,getcopy(p1),p2));
  1525. end;
  1526. end;
  1527. afterassignment:=oldafterassignment;
  1528. expr:=p1;
  1529. end;
  1530. function get_intconst:longint;
  1531. {Reads an expression, tries to evalute it and check if it is an integer
  1532. constant. Then the constant is returned.}
  1533. var p:Ptree;
  1534. begin
  1535. p:=expr;
  1536. do_firstpass(p);
  1537. if (p^.treetype<>ordconstn) and
  1538. (p^.resulttype^.deftype=orddef) and
  1539. not (Porddef(p^.resulttype)^.typ in
  1540. [uvoid,uchar,bool8bit]) then
  1541. Message(cg_e_illegal_expression)
  1542. else
  1543. get_intconst:=p^.value;
  1544. disposetree(p);
  1545. end;
  1546. function get_stringconst:string;
  1547. {Reads an expression, tries to evaluate it and checks if it is a string
  1548. constant. Then the constant is returned.}
  1549. var p:Ptree;
  1550. begin
  1551. get_stringconst:='';
  1552. p:=expr;
  1553. do_firstpass(p);
  1554. if p^.treetype<>stringconstn then
  1555. if (p^.treetype=ordconstn) and
  1556. (p^.resulttype^.deftype=orddef) and
  1557. (Porddef(p^.resulttype)^.typ=uchar) then
  1558. get_stringconst:=char(p^.value)
  1559. else
  1560. Message(cg_e_illegal_expression)
  1561. else
  1562. get_stringconst:=p^.values^;
  1563. disposetree(p);
  1564. end;
  1565. end.
  1566. {
  1567. $Log$
  1568. Revision 1.8 1998-04-14 23:27:03 florian
  1569. + exclude/include with constant second parameter added
  1570. Revision 1.7 1998/04/09 23:02:15 florian
  1571. * small problems solved to get remake3 work
  1572. Revision 1.6 1998/04/09 22:16:35 florian
  1573. * problem with previous REGALLOC solved
  1574. * improved property support
  1575. Revision 1.5 1998/04/08 10:26:09 florian
  1576. * correct error handling of virtual constructors
  1577. * problem with new type declaration handling fixed
  1578. Revision 1.4 1998/04/07 22:45:05 florian
  1579. * bug0092, bug0115 and bug0121 fixed
  1580. + packed object/class/array
  1581. Revision 1.3 1998/04/07 13:19:46 pierre
  1582. * bugfixes for reset_gdb_info
  1583. in MEM parsing for go32v2
  1584. better external symbol creation
  1585. support for rhgdb.exe (lowercase file names)
  1586. Revision 1.2 1998/03/26 11:18:31 florian
  1587. - switch -Sa removed
  1588. - support of a:=b:=0 removed
  1589. Revision 1.1.1.1 1998/03/25 11:18:14 root
  1590. * Restored version
  1591. Revision 1.26 1998/03/24 21:48:33 florian
  1592. * just a couple of fixes applied:
  1593. - problem with fixed16 solved
  1594. - internalerror 10005 problem fixed
  1595. - patch for assembler reading
  1596. - small optimizer fix
  1597. - mem is now supported
  1598. Revision 1.25 1998/03/21 23:59:39 florian
  1599. * indexed properties fixed
  1600. * ppu i/o of properties fixed
  1601. * field can be also used for write access
  1602. * overriding of properties
  1603. Revision 1.24 1998/03/16 22:42:21 florian
  1604. * some fixes of Peter applied:
  1605. ofs problem, profiler support
  1606. Revision 1.23 1998/03/11 11:23:57 florian
  1607. * bug0081 and bug0109 fixed
  1608. Revision 1.22 1998/03/10 16:27:42 pierre
  1609. * better line info in stabs debug
  1610. * symtabletype and lexlevel separated into two fields of tsymtable
  1611. + ifdef MAKELIB for direct library output, not complete
  1612. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  1613. working
  1614. + ifdef TESTFUNCRET for setting func result in underfunction, not
  1615. working
  1616. Revision 1.21 1998/03/10 01:17:24 peter
  1617. * all files have the same header
  1618. * messages are fully implemented, EXTDEBUG uses Comment()
  1619. + AG... files for the Assembler generation
  1620. Revision 1.20 1998/03/06 00:52:44 peter
  1621. * replaced all old messages from errore.msg, only ExtDebug and some
  1622. Comment() calls are left
  1623. * fixed options.pas
  1624. Revision 1.19 1998/03/02 01:49:02 peter
  1625. * renamed target_DOS to target_GO32V1
  1626. + new verbose system, merged old errors and verbose units into one new
  1627. verbose.pas, so errors.pas is obsolete
  1628. Revision 1.18 1998/03/01 22:46:18 florian
  1629. + some win95 linking stuff
  1630. * a couple of bugs fixed:
  1631. bug0055,bug0058,bug0059,bug0064,bug0072,bug0093,bug0095,bug0098
  1632. Revision 1.17 1998/02/27 21:24:06 florian
  1633. * dll support changed (dll name can be also a string contants)
  1634. Revision 1.16 1998/02/24 00:19:17 peter
  1635. * makefile works again (btw. linux does like any char after a \ )
  1636. * removed circular unit with assemble and files
  1637. * fixed a sigsegv in pexpr
  1638. * pmodule init unit/program is the almost the same, merged them
  1639. Revision 1.15 1998/02/13 10:35:24 daniel
  1640. * Made Motorola version compilable.
  1641. * Fixed optimizer
  1642. Revision 1.14 1998/02/12 17:19:20 florian
  1643. * fixed to get remake3 work, but needs additional fixes (output, I don't like
  1644. also that aktswitches isn't a pointer)
  1645. Revision 1.13 1998/02/12 11:50:26 daniel
  1646. Yes! Finally! After three retries, my patch!
  1647. Changes:
  1648. Complete rewrite of psub.pas.
  1649. Added support for DLL's.
  1650. Compiler requires less memory.
  1651. Platform units for each platform.
  1652. Revision 1.12 1998/02/11 21:56:37 florian
  1653. * bugfixes: bug0093, bug0053, bug0088, bug0087, bug0089
  1654. Revision 1.11 1998/02/01 22:41:11 florian
  1655. * clean up
  1656. + system.assigned([class])
  1657. + system.assigned([class of xxxx])
  1658. * first fixes of as and is-operator
  1659. Revision 1.10 1998/02/01 15:04:15 florian
  1660. * better error recovering
  1661. * some clean up
  1662. Revision 1.9 1998/01/30 21:27:05 carl
  1663. * partial bugfix #88, #89 and typeof and other inline functions
  1664. (these bugs have a deeper nesting level, and therefore i only fixed
  1665. the parser crashes - there is also a tree crash).
  1666. Revision 1.8 1998/01/26 17:31:01 florian
  1667. * stupid bug with self in class methods fixed
  1668. Revision 1.7 1998/01/25 22:29:02 florian
  1669. * a lot bug fixes on the DOM
  1670. Revision 1.6 1998/01/23 10:46:41 florian
  1671. * small problems with FCL object model fixed, objpas?.inc is compilable
  1672. Revision 1.5 1998/01/16 22:34:42 michael
  1673. * Changed 'conversation' to 'conversion'. Waayyy too much chatting going on
  1674. in this compiler :)
  1675. Revision 1.4 1998/01/16 18:03:15 florian
  1676. * small bug fixes, some stuff of delphi styled constructores added
  1677. Revision 1.3 1998/01/13 23:11:14 florian
  1678. + class methods
  1679. Revision 1.2 1998/01/09 09:09:59 michael
  1680. + Initial implementation, second try
  1681. }