Pol  Revision:cb584c9
compiler.h
Go to the documentation of this file.
1 
7 #ifndef H_COMPILER_H
8 #define H_COMPILER_H
9 
10 #include "../clib/compilerspecifics.h"
11 #include "compctx.h"
12 #include "tokens.h"
13 #include "userfunc.h"
14 
15 #ifndef __PARSER_H
16 #include "parser.h"
17 #endif
18 
19 #include <iosfwd>
20 #include <map>
21 #include <stddef.h>
22 #include <string>
23 #include <vector>
24 
25 #include "../clib/maputil.h"
26 #include "../clib/refptr.h"
27 
28 namespace Pol
29 {
30 namespace Bscript
31 {
32 class ModuleFunction;
33 class Token;
34 class UserFunction;
35 } // namespace Bscript
36 } // namespace Pol
37 
38 namespace Pol
39 {
40 namespace Bscript
41 {
42 class EScriptProgram;
43 class EScriptProgramCheckpoint;
44 class FunctionalityModule;
45 /*
46  ack, this is a misnomer.
47  "CanBeLabelled" means "break or continue can happen here."
48  enum eb_type { CanBeLabelled = true, CanNotBeLabelled = false };
49  */
50 
52 {
53  CanBeLabelled = true,
55 };
57 {
58  BreakOk = true,
59  BreakNotOk = false
60 };
62 {
63  ContinueOk = true,
64  ContinueNotOk = false
65 };
66 
67 struct BlockDesc
68 {
69  unsigned varcount; // how many variables in this block?
70  unsigned valcount; // how many values on the stack should be removed?
71 
75 
76  std::string label; // label of construct
77 
78  // addresses of tokens whos offset needs to be patched with
79  // the final break/continue jump addresses.
80  typedef std::vector<unsigned> TokenAddrs;
81  TokenAddrs break_tokens;
82  TokenAddrs continue_tokens;
83 
84  unsigned blockidx;
85 };
86 
87 struct Variable
88 {
89  std::string name;
90  mutable bool used = false;
91  mutable bool unused = false;
93 };
94 typedef std::vector<Variable> Variables;
95 
96 class Scope
97 {
98 public:
99  BlockDesc& pushblock();
100  void popblock( bool varsOnly );
101  void addvar( const std::string& varname, const CompilerContext& ctx, bool warn_on_notused = true,
102  bool unused = false );
103  void addvalue();
104  bool inblock() const { return !blockdescs_.empty(); }
105  unsigned numVarsInBlock() const { return blockdescs_.back().varcount; }
106  const BlockDesc& blockdesc() const { return blockdescs_.back(); }
107  bool varexists( const std::string& varname, unsigned& idx ) const;
108  bool varexists( const std::string& varname ) const;
109  unsigned int numVariables() const { return static_cast<unsigned int>( variables_.size() ); }
110 
111 private:
112  Variables variables_;
113 
114  // we may need a blocktag, too, in which case this
115  // should be a stack/vector of a struct.
116  std::vector<BlockDesc> blockdescs_;
117  friend class Compiler;
118 };
119 
120 class Compiler : public SmartParser
121 {
122 public:
123  static bool check_filecase_;
124  static int verbosity_level_;
125  static void setCheckFileCase( bool check ) { check_filecase_ = check; }
126  static void setVerbosityLevel( int vlev ) { verbosity_level_ = vlev; }
127 
128 private:
129  std::string current_file_path;
130 
131 
134  char curLine[80];
135  int inExpr;
139  unsigned programPos;
140  unsigned nProgramArgs;
141 
144 
145  typedef std::set<std::string, Clib::ci_cmp_pred> INCLUDES;
146  INCLUDES included;
147 
148  std::vector<std::string> referencedPathnames;
149 
151  typedef std::map<std::string, UserFunction, Clib::ci_cmp_pred> UserFunctions;
152  UserFunctions userFunctions;
153 
154  int findLabel( Token& tok, unsigned& posn );
155  int enterLabel( Token& tok );
156 
157  typedef std::map<std::string, Token> Constants;
158  Constants constants;
159 
160  /*
161  scopes:
162  because functions don't nest, a stack of block scopes isn't necessary.
163  when we enter a function, we'll enter a scope.
164  exiting the function automatically removes its "locals"
165  we'll still end up inserting a "leave block", but that
166  could be optimized out, I suppose.
167  */
168  Variables globals_;
169 
170  bool globalexists( const std::string& varname, unsigned& idx,
171  CompilerContext* atctx = NULL ) const;
172 
174 
175  bool varexists( const std::string& varname ) const;
176 
177  bool inGlobalScope() const { return localscope.inblock() == false; }
178  /*
179  special note on latest_label, enterblock, and leaveblock
180  latest_label is a hidden parameter to enterblock, set up
181  by getStatement processing a label ("tag:").
182  note, getStatement checks to make sure the label is
183  followed by a WHILE or DO statement.
184  */
185  std::string latest_label;
186  void enterblock( eb_label_ok eblabel, eb_break_ok ebbreak, eb_continue_ok ebcontinue );
187  void enterblock( eb_label_ok et );
188  int readblock( CompilerContext& ctx, int level, BTokenId endtokenid,
189  BTokenId* last_statement_id = NULL, Token* block_end = NULL );
190  void leaveblock( unsigned breakPC, unsigned continuePC );
191  void emit_leaveblock();
192  void patchblock_continues( unsigned continuePC );
193  void patchblock_breaks( unsigned breakPC );
194 
195  void rollback( EScriptProgram& prog, const EScriptProgramCheckpoint& checkpoint );
196  bool substitute_constant( Token* tkn ) const; // returns true if a constant was found.
197  void substitute_constants( Expression& expr ) const;
198  void convert_variables( Expression& expr ) const;
199  int validate( const Expression& expr, CompilerContext& ctx ) const;
200  int readexpr( Expression& expr, CompilerContext& ctx, unsigned flags );
201  void inject( Expression& expr );
202  int insertBreak( const std::string& label );
203 
204 public:
205  Compiler();
206  ~Compiler();
207 
208  void dump( std::ostream& os );
209  void setIncludeCompileMode() { compiling_include = true; }
210  void addModule( FunctionalityModule* module );
211  int useModule( const char* modulename );
212  int includeModule( const std::string& modulename );
213  virtual int isFunc( Token& tok, ModuleFunction** v ) POL_OVERRIDE;
214  virtual int isUserFunc( Token& tok, UserFunction** userfunc ) POL_OVERRIDE;
215 
216  void patchoffset( unsigned instruc, unsigned newoffset );
217  void addToken( Token& tok );
218 
219  virtual int isLegal( Token& tok ) POL_OVERRIDE;
220 
221  virtual int getUserArgs( Expression& ex, CompilerContext& ctx, bool inject_jsr ) POL_OVERRIDE;
222  virtual int getArrayElements( Expression& expr, CompilerContext& ctx ) POL_OVERRIDE;
223  virtual int getNewArrayElements( Expression& expr, CompilerContext& ctx ) POL_OVERRIDE;
224  virtual int getStructMembers( Expression& expr, CompilerContext& ctx ) POL_OVERRIDE;
225  virtual int getDictionaryMembers( Expression& expr, CompilerContext& ctx ) POL_OVERRIDE;
226  virtual int getMethodArguments( Expression& expr, CompilerContext& ctx, int& nargs ) POL_OVERRIDE;
227  virtual int getFunctionPArgument( Expression& expr, CompilerContext& ctx,
228  Token* tok ) POL_OVERRIDE;
229 
230  int eatToken( CompilerContext& ctx, BTokenId tokenid );
231  int getExpr( CompilerContext& ctx, unsigned expr_flags, size_t* exprlen = NULL,
232  Expression* ex = NULL );
233  int getExpr2( CompilerContext& ctx, unsigned expr_flags, Expression* ex = NULL );
234  int getExprInParens( CompilerContext& ctx, Expression* ex = NULL );
235  int getSimpleExpr( CompilerContext& ctx );
236 
237  int handleProgram( CompilerContext& ctx, int level );
238  int handleProgram2( CompilerContext& ctx, int level );
239  int readFunctionDeclaration( CompilerContext& ctx, UserFunction& userfunc );
240  int handleDoClause( CompilerContext& ctx, int level );
241  int handleRepeatUntil( CompilerContext& ctx, int level );
242  int handleForEach( CompilerContext& ctx, int level );
243  int handleGotoGosub( CompilerContext& ctx, unsigned save_id );
244  int handleReturn( CompilerContext& ctx );
245  int handleExit( CompilerContext& ctx );
246  int handleBreak( CompilerContext& ctx );
247  int handleContinue( CompilerContext& ctx );
248  int handleBlock( CompilerContext& ctx, int level );
249  int handleIf( CompilerContext& ctx, int level );
250  int handleBracketedIf( CompilerContext& ctx, int level );
251  int handleWhile( CompilerContext& ctx, int level );
252  int handleBracketedWhile( CompilerContext& ctx, int level );
253  int handleVarDeclare( CompilerContext& ctx, unsigned save_id );
254  int handleConstDeclare( CompilerContext& ctx );
255  int handleEnumDeclare( CompilerContext& ctx );
256  int handleDeclare( CompilerContext& ctx );
257  int handleFunction( CompilerContext& ctx );
258  int handleBracketedFunction( CompilerContext& ctx );
259  int handleUse( CompilerContext& ctx );
260  int handleInclude( CompilerContext& ctx );
261  int handleFor( CompilerContext& ctx );
262  int handleFor_c( CompilerContext& ctx );
263  int handleFor_basic( CompilerContext& ctx );
264  int handleBracketedFor_c( CompilerContext& ctx );
265  int handleBracketedFor_basic( CompilerContext& ctx );
266  int handleForEach( CompilerContext& ctx );
267  int handleSwitch( CompilerContext& ctx, int level );
268 
269  void emitFileLine( CompilerContext& ctx );
270  void emitFileLineIfFileChanged( CompilerContext& ctx );
271  void readCurLine( CompilerContext& ctx );
272  void savesourceline();
273 
274  int getStatement( CompilerContext& ctx /*char **s */, int level );
275  int _getStatement( CompilerContext& ctx /*char **s */, int level );
276 
277  int getFileContents( const char* filename, char** contents );
278  int compileFile( const char* fname );
279  int compileContext( CompilerContext& ctx );
280  int compile( CompilerContext& ctx /* char *s */ );
281 
282  int write( const char* fname );
283  int write_dbg( const char* fname, bool generate_txtfile );
284  void writeIncludedFilenames( const char* fname ) const;
285 
286  // phase 0: determining bracket syntax
287 
288  // phase 1: read function declarations, constants (but clear constants)
289  int forward_read_function( CompilerContext& ctx );
290  bool read_function_declarations( const CompilerContext& ctx );
291  bool read_function_declarations_in_included_file( const char* modulename );
292  bool inner_read_function_declarations( const CompilerContext& ctx );
293 
294  // phase 2: compile the source
295  int handleBracketedFunction2( CompilerContext& ctx, int level, int tokentype );
296 
297  // phase 3: emit functions that are actually used.
298  int handleBracketedFunction3( UserFunction& userfunc, CompilerContext& ctx );
299  int emit_function( UserFunction& uf );
300  int emit_functions();
301  void patch_callers( UserFunction& uf );
302 
303 private:
304  std::vector<char*> delete_these_arrays;
305 };
306 }
307 }
308 #endif // H_COMPILER_H
#define POL_OVERRIDE
static bool check_filecase_
Definition: compiler.h:123
unsigned numVarsInBlock() const
Definition: compiler.h:105
std::set< std::string, Clib::ci_cmp_pred > INCLUDES
Definition: compiler.h:145
std::vector< BlockDesc > blockdescs_
Definition: compiler.h:116
TokenAddrs continue_tokens
Definition: compiler.h:82
std::map< std::string, UserFunction, Clib::ci_cmp_pred > UserFunctions
Definition: compiler.h:151
void setIncludeCompileMode()
Definition: compiler.h:209
std::vector< unsigned > TokenAddrs
Definition: compiler.h:80
std::vector< std::string > referencedPathnames
Definition: compiler.h:148
bool inblock() const
Definition: compiler.h:104
Variables variables_
Definition: compiler.h:112
UserFunctions userFunctions
Definition: compiler.h:152
static int verbosity_level_
Definition: compiler.h:124
void checkpoint(const char *msg, unsigned short minlvl)
Definition: checkpnt.cpp:17
std::string label
Definition: compiler.h:76
Definition: refptr.h:65
eb_label_ok label_ok
Definition: compiler.h:72
unsigned int numVariables() const
Definition: compiler.h:109
std::vector< char * > delete_these_arrays
Definition: compiler.h:304
static void setVerbosityLevel(int vlev)
Definition: compiler.h:126
TokenAddrs break_tokens
Definition: compiler.h:81
std::map< std::string, Token > Constants
Definition: compiler.h:157
static void setCheckFileCase(bool check)
Definition: compiler.h:125
std::string current_file_path
Definition: compiler.h:129
bool inGlobalScope() const
Definition: compiler.h:177
CompilerContext ctx
Definition: compiler.h:92
std::string name
Definition: compiler.h:89
eb_break_ok break_ok
Definition: compiler.h:73
eb_continue_ok continue_ok
Definition: compiler.h:74
CompilerContext program_ctx
Definition: compiler.h:142
ref_ptr< EScriptProgram > program
Definition: compiler.h:150
const BlockDesc & blockdesc() const
Definition: compiler.h:106
Definition: berror.cpp:12
std::string latest_label
Definition: compiler.h:185
std::vector< Variable > Variables
Definition: compiler.h:94