pbase.pas 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. Contains some helper routines for the parser
  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 pbase;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cutils,cclasses,
  23. tokens,globals,
  24. symconst,symbase,symtype,symdef,symsym,symtable
  25. ;
  26. const
  27. { tokens that end a block or statement. And don't require
  28. a ; on the statement before }
  29. endtokens = [_SEMICOLON,_END,_ELSE,_UNTIL];
  30. { true, if we are after an assignement }
  31. afterassignment : boolean = false;
  32. { true, if we are parsing arguments }
  33. in_args : boolean = false;
  34. { true, if we got an @ to get the address }
  35. got_addrn : boolean = false;
  36. { special for handling procedure vars }
  37. getprocvardef : tprocvardef = nil;
  38. var
  39. { for operators }
  40. optoken : ttoken;
  41. { symtable were unit references are stored }
  42. refsymtable : tsymtable;
  43. { true, if only routine headers should be parsed }
  44. parse_only : boolean;
  45. { true, if we should ignore an equal in const x : 1..2=2 }
  46. ignore_equal : boolean;
  47. procedure identifier_not_found(const s:string);
  48. function tokenstring(i : ttoken):string;
  49. { consumes token i, if the current token is unequal i }
  50. { a syntax error is written }
  51. procedure consume(i : ttoken);
  52. {Tries to consume the token i, and returns true if it was consumed:
  53. if token=i.}
  54. function try_to_consume(i:Ttoken):boolean;
  55. { consumes all tokens til atoken (for error recovering }
  56. procedure consume_all_until(atoken : ttoken);
  57. { consumes tokens while they are semicolons }
  58. procedure consume_emptystats;
  59. { reads a list of identifiers into a string list }
  60. { consume a symbol, if not found give an error and
  61. and return an errorsym }
  62. function consume_sym(var srsym:tsym;var srsymtable:tsymtable):boolean;
  63. function try_consume_hintdirective(var symopt:tsymoptions):boolean;
  64. procedure check_hints(const srsym: tsym);
  65. { just for an accurate position of the end of a procedure (PM) }
  66. var
  67. last_endtoken_filepos: tfileposinfo;
  68. implementation
  69. uses
  70. globtype,scanner,systems,verbose;
  71. {****************************************************************************
  72. Token Parsing
  73. ****************************************************************************}
  74. procedure identifier_not_found(const s:string);
  75. begin
  76. Message1(sym_e_id_not_found,s);
  77. { show a fatal that you need -S2 or -Sd, but only
  78. if we just parsed the a token that has m_class }
  79. if not(m_class in aktmodeswitches) and
  80. (Upper(s)=pattern) and
  81. (tokeninfo^[idtoken].keyword=m_class) then
  82. Message(parser_f_need_objfpc_or_delphi_mode);
  83. end;
  84. function tokenstring(i : ttoken):string;
  85. begin
  86. tokenstring:=tokeninfo^[i].str;
  87. end;
  88. { consumes token i, write error if token is different }
  89. procedure consume(i : ttoken);
  90. begin
  91. if (token<>i) and (idtoken<>i) then
  92. if token=_id then
  93. Message2(scan_f_syn_expected,tokeninfo^[i].str,'identifier '+pattern)
  94. else
  95. Message2(scan_f_syn_expected,tokeninfo^[i].str,tokeninfo^[token].str)
  96. else
  97. begin
  98. if token=_END then
  99. last_endtoken_filepos:=akttokenpos;
  100. current_scanner.readtoken;
  101. end;
  102. end;
  103. function try_to_consume(i:Ttoken):boolean;
  104. begin
  105. try_to_consume:=false;
  106. if (token=i) or (idtoken=i) then
  107. begin
  108. try_to_consume:=true;
  109. if token=_END then
  110. last_endtoken_filepos:=akttokenpos;
  111. current_scanner.readtoken;
  112. end;
  113. end;
  114. procedure consume_all_until(atoken : ttoken);
  115. begin
  116. while (token<>atoken) and (idtoken<>atoken) do
  117. begin
  118. Consume(token);
  119. if token=_EOF then
  120. begin
  121. Consume(atoken);
  122. Message(scan_f_end_of_file);
  123. exit;
  124. end;
  125. end;
  126. end;
  127. procedure consume_emptystats;
  128. begin
  129. repeat
  130. until not try_to_consume(_SEMICOLON);
  131. end;
  132. { check if a symbol contains the hint directive, and if so gives out a hint
  133. if required.
  134. }
  135. procedure check_hints(const srsym: tsym);
  136. begin
  137. if not assigned(srsym) then
  138. exit;
  139. if sp_hint_deprecated in srsym.symoptions then
  140. Message1(sym_w_deprecated_symbol,srsym.realname);
  141. if sp_hint_platform in srsym.symoptions then
  142. Message1(sym_w_non_portable_symbol,srsym.realname);
  143. if sp_hint_unimplemented in srsym.symoptions then
  144. Message1(sym_w_non_implemented_symbol,srsym.realname);
  145. end;
  146. function consume_sym(var srsym:tsym;var srsymtable:tsymtable):boolean;
  147. begin
  148. { first check for identifier }
  149. if token<>_ID then
  150. begin
  151. consume(_ID);
  152. srsym:=generrorsym;
  153. srsymtable:=nil;
  154. consume_sym:=false;
  155. exit;
  156. end;
  157. searchsym(pattern,srsym,srsymtable);
  158. check_hints(srsym);
  159. if assigned(srsym) then
  160. begin
  161. if (srsym.typ=unitsym) then
  162. begin
  163. { only allow unit.symbol access if the name was
  164. found in the current module }
  165. if srsym.owner.unitid=0 then
  166. begin
  167. consume(_ID);
  168. consume(_POINT);
  169. srsymtable:=tunitsym(srsym).unitsymtable;
  170. srsym:=searchsymonlyin(srsymtable,pattern);
  171. end
  172. else
  173. srsym:=nil;
  174. end;
  175. end;
  176. { if nothing found give error and return errorsym }
  177. if srsym=nil then
  178. begin
  179. identifier_not_found(orgpattern);
  180. srsym:=generrorsym;
  181. srsymtable:=nil;
  182. end;
  183. consume(_ID);
  184. consume_sym:=assigned(srsym);
  185. end;
  186. function try_consume_hintdirective(var symopt:tsymoptions):boolean;
  187. begin
  188. try_consume_hintdirective:=false;
  189. if not(m_hintdirective in aktmodeswitches) then
  190. exit;
  191. repeat
  192. case idtoken of
  193. _LIBRARY :
  194. begin
  195. include(symopt,sp_hint_library);
  196. try_consume_hintdirective:=true;
  197. end;
  198. _DEPRECATED :
  199. begin
  200. include(symopt,sp_hint_deprecated);
  201. try_consume_hintdirective:=true;
  202. end;
  203. _PLATFORM :
  204. begin
  205. include(symopt,sp_hint_platform);
  206. try_consume_hintdirective:=true;
  207. end;
  208. _UNIMPLEMENTED :
  209. begin
  210. include(symopt,sp_hint_unimplemented);
  211. try_consume_hintdirective:=true;
  212. end;
  213. else
  214. break;
  215. end;
  216. consume(Token);
  217. until false;
  218. end;
  219. end.
  220. {
  221. $Log$
  222. Revision 1.25 2003-09-23 17:56:05 peter
  223. * locals and paras are allocated in the code generation
  224. * tvarsym.localloc contains the location of para/local when
  225. generating code for the current procedure
  226. Revision 1.24 2003/05/15 18:58:53 peter
  227. * removed selfpointer_offset, vmtpointer_offset
  228. * tvarsym.adjusted_address
  229. * address in localsymtable is now in the real direction
  230. * removed some obsolete globals
  231. Revision 1.23 2003/03/17 18:55:30 peter
  232. * allow more tokens instead of only semicolon after inherited
  233. Revision 1.22 2002/12/05 19:28:05 carl
  234. - remove lower in hint
  235. Revision 1.21 2002/11/30 11:12:48 carl
  236. + checking for symbols used with hint directives is done mostly in pexpr
  237. only now
  238. Revision 1.20 2002/11/29 22:31:19 carl
  239. + unimplemented hint directive added
  240. * hint directive parsing implemented
  241. * warning on these directives
  242. Revision 1.19 2002/09/09 17:34:15 peter
  243. * tdicationary.replace added to replace and item in a dictionary. This
  244. is only allowed for the same name
  245. * varsyms are inserted in symtable before the types are parsed. This
  246. fixes the long standing "var longint : longint" bug
  247. - consume_idlist and idstringlist removed. The loops are inserted
  248. at the callers place and uses the symtable for duplicate id checking
  249. Revision 1.18 2002/08/17 09:23:38 florian
  250. * first part of procinfo rewrite
  251. Revision 1.17 2002/05/18 13:34:11 peter
  252. * readded missing revisions
  253. Revision 1.16 2002/05/16 19:46:42 carl
  254. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  255. + try to fix temp allocation (still in ifdef)
  256. + generic constructor calls
  257. + start of tassembler / tmodulebase class cleanup
  258. Revision 1.14 2002/01/06 21:47:32 peter
  259. * removed getprocvar, use only getprocvardef
  260. }