|
@@ -16,12 +16,25 @@ struct PrattRule{
|
|
|
Precedence precedence;
|
|
Precedence precedence;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-class Compiler: public CompilerBase {
|
|
|
|
|
|
|
+class Compiler {
|
|
|
inline static PrattRule rules[kTokenCount];
|
|
inline static PrattRule rules[kTokenCount];
|
|
|
|
|
+ std::unique_ptr<Lexer> lexer;
|
|
|
stack<CodeEmitContext> contexts;
|
|
stack<CodeEmitContext> contexts;
|
|
|
VM* vm;
|
|
VM* vm;
|
|
|
bool unknown_global_scope; // for eval/exec() call
|
|
bool unknown_global_scope; // for eval/exec() call
|
|
|
bool used;
|
|
bool used;
|
|
|
|
|
+ // for parsing token stream
|
|
|
|
|
+ int i = 0;
|
|
|
|
|
+ std::vector<Token> tokens;
|
|
|
|
|
+
|
|
|
|
|
+ const Token& prev() const{ return tokens.at(i-1); }
|
|
|
|
|
+ const Token& curr() const{ return tokens.at(i); }
|
|
|
|
|
+ const Token& next() const{ return tokens.at(i+1); }
|
|
|
|
|
+ const Token& err() const{
|
|
|
|
|
+ if(i >= tokens.size()) return prev();
|
|
|
|
|
+ return curr();
|
|
|
|
|
+ }
|
|
|
|
|
+ void advance(int delta=1) { i += delta; }
|
|
|
|
|
|
|
|
CodeEmitContext* ctx() { return &contexts.top(); }
|
|
CodeEmitContext* ctx() { return &contexts.top(); }
|
|
|
CompileMode mode() const{ return lexer->src->mode; }
|
|
CompileMode mode() const{ return lexer->src->mode; }
|
|
@@ -32,7 +45,10 @@ class Compiler: public CompilerBase {
|
|
|
|
|
|
|
|
static void init_pratt_rules();
|
|
static void init_pratt_rules();
|
|
|
|
|
|
|
|
|
|
+ bool match(TokenIndex expected);
|
|
|
|
|
+ void consume(TokenIndex expected);
|
|
|
bool match_newlines_repl();
|
|
bool match_newlines_repl();
|
|
|
|
|
+
|
|
|
bool match_newlines(bool repl_throw=false);
|
|
bool match_newlines(bool repl_throw=false);
|
|
|
bool match_end_stmt();
|
|
bool match_end_stmt();
|
|
|
void consume_end_stmt();
|
|
void consume_end_stmt();
|
|
@@ -109,9 +125,17 @@ class Compiler: public CompilerBase {
|
|
|
|
|
|
|
|
PyObject* to_object(const TokenValue& value);
|
|
PyObject* to_object(const TokenValue& value);
|
|
|
PyObject* read_literal();
|
|
PyObject* read_literal();
|
|
|
|
|
+
|
|
|
|
|
+ void SyntaxError(Str msg){ lexer->throw_err("SyntaxError", msg, err().line, err().start); }
|
|
|
|
|
+ void SyntaxError(){ lexer->throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
|
|
|
|
|
+ void IndentationError(Str msg){ lexer->throw_err("IndentationError", msg, err().line, err().start); }
|
|
|
|
|
+
|
|
|
public:
|
|
public:
|
|
|
Compiler(VM* vm, const Str& source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
|
|
Compiler(VM* vm, const Str& source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
|
|
|
CodeObject_ compile();
|
|
CodeObject_ compile();
|
|
|
|
|
+
|
|
|
|
|
+ Compiler(const Compiler&) = delete;
|
|
|
|
|
+ Compiler& operator=(const Compiler&) = delete;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
} // namespace pkpy
|
|
} // namespace pkpy
|