pbase.pas 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. interface
  20. uses
  21. cobjects,tokens,globals,symtable
  22. {$ifdef fixLeaksOnError}
  23. ,comphook
  24. {$endif fixLeaksOnError}
  25. ;
  26. const
  27. { true, if we are after an assignement }
  28. afterassignment : boolean = false;
  29. { sspecial for handling procedure vars }
  30. getprocvar : boolean = false;
  31. getprocvardef : pprocvardef = nil;
  32. var
  33. { size of data segment, set by proc_unit or proc_program }
  34. datasize : longint;
  35. { for operators }
  36. optoken : ttoken;
  37. opsym : pvarsym;
  38. { symtable were unit references are stored }
  39. refsymtable : psymtable;
  40. { true, if only routine headers should be parsed }
  41. parse_only : boolean;
  42. { true, if we should ignore an equal in const x : 1..2=2 }
  43. ignore_equal : boolean;
  44. {$ifdef fixLeaksOnError}
  45. { not worth it to make a pstack, there's only one data field (a pointer). }
  46. { in the interface, because pmodules and psub also use it for their names }
  47. var strContStack: TStack;
  48. pbase_old_do_stop: tstopprocedure;
  49. {$endif fixLeaksOnError}
  50. function tokenstring(i : ttoken):string;
  51. { consumes token i, if the current token is unequal i }
  52. { a syntax error is written }
  53. procedure consume(i : ttoken);
  54. {Tries to consume the token i, and returns true if it was consumed:
  55. if token=i.}
  56. function try_to_consume(i:Ttoken):boolean;
  57. { consumes all tokens til atoken (for error recovering }
  58. procedure consume_all_until(atoken : ttoken);
  59. { consumes tokens while they are semicolons }
  60. procedure emptystats;
  61. { reads a list of identifiers into a string container }
  62. function idlist : pstringcontainer;
  63. { just for an accurate position of the end of a procedure (PM) }
  64. var
  65. last_endtoken_filepos: tfileposinfo;
  66. implementation
  67. uses
  68. files,scanner,systems,verbose;
  69. function tokenstring(i : ttoken):string;
  70. begin
  71. tokenstring:=tokeninfo^[i].str;
  72. end;
  73. { consumes token i, write error if token is different }
  74. procedure consume(i : ttoken);
  75. begin
  76. if (token<>i) and (idtoken<>i) then
  77. if token=_id then
  78. Message2(scan_f_syn_expected,tokeninfo^[i].str,'identifier '+pattern)
  79. else
  80. Message2(scan_f_syn_expected,tokeninfo^[i].str,tokeninfo^[token].str)
  81. else
  82. begin
  83. if token=_END then
  84. last_endtoken_filepos:=tokenpos;
  85. current_scanner^.readtoken;
  86. end;
  87. end;
  88. function try_to_consume(i:Ttoken):boolean;
  89. begin
  90. try_to_consume:=false;
  91. if (token=i) or (idtoken=i) then
  92. begin
  93. try_to_consume:=true;
  94. if token=_END then
  95. last_endtoken_filepos:=tokenpos;
  96. current_scanner^.readtoken;
  97. end;
  98. end;
  99. procedure consume_all_until(atoken : ttoken);
  100. begin
  101. while (token<>atoken) and (idtoken<>atoken) do
  102. begin
  103. Consume(token);
  104. if token=_EOF then
  105. begin
  106. Consume(atoken);
  107. Message(scan_f_end_of_file);
  108. exit;
  109. end;
  110. end;
  111. end;
  112. procedure emptystats;
  113. begin
  114. repeat
  115. until not try_to_consume(_SEMICOLON);
  116. end;
  117. { reads a list of identifiers into a string container }
  118. function idlist : pstringcontainer;
  119. var
  120. sc : pstringcontainer;
  121. begin
  122. sc:=new(pstringcontainer,init);
  123. repeat
  124. sc^.insert_with_tokeninfo(pattern,
  125. tokenpos);
  126. consume(_id);
  127. if token=_COMMA then consume(_COMMA)
  128. else break
  129. until false;
  130. idlist:=sc;
  131. end;
  132. {$ifdef fixLeaksOnError}
  133. procedure pbase_do_stop; {$ifdef tp} far; {$endif tp}
  134. var names: PStringContainer;
  135. begin
  136. names := PStringContainer(strContStack.pop);
  137. while names <> nil do
  138. begin
  139. dispose(names,done);
  140. names := PStringContainer(strContStack.pop);
  141. end;
  142. strContStack.done;
  143. do_stop := pbase_old_do_stop;
  144. {$ifdef tp}
  145. do_stop;
  146. {$else tp}
  147. do_stop();
  148. {$endif tp}
  149. end;
  150. begin
  151. strContStack.init;
  152. pbase_old_do_stop := do_stop;
  153. do_stop := {$ifndef tp}@{$endif}pbase_do_stop;
  154. {$endif fixLeaksOnError}
  155. end.
  156. {
  157. $Log$
  158. Revision 1.30 2000-02-09 13:22:56 peter
  159. * log truncated
  160. Revision 1.29 2000/01/11 17:16:04 jonas
  161. * removed a lot of memory leaks when an error is encountered (caused by
  162. procinfo and pstringcontainers). There are still plenty left though :)
  163. Revision 1.28 2000/01/07 01:14:28 peter
  164. * updated copyright to 2000
  165. Revision 1.27 1999/11/06 14:34:21 peter
  166. * truncated log to 20 revs
  167. Revision 1.26 1999/10/01 08:02:46 peter
  168. * forward type declaration rewritten
  169. Revision 1.25 1999/09/02 18:47:44 daniel
  170. * Could not compile with TP, some arrays moved to heap
  171. * NOAG386BIN default for TP
  172. * AG386* files were not compatible with TP, fixed.
  173. Revision 1.24 1999/08/04 13:02:50 jonas
  174. * all tokens now start with an underscore
  175. * PowerPC compiles!!
  176. Revision 1.23 1999/07/27 23:42:10 peter
  177. * indirect type referencing is now allowed
  178. Revision 1.22 1999/07/26 09:42:10 florian
  179. * bugs 494-496 fixed
  180. }