diff --git a/src/codeobject.h b/src/codeobject.h index 2fb6f5a6..805061db 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -26,21 +26,13 @@ _Str pad(const _Str& s, const int n){ return s + _Str(n - s.size(), ' '); } -enum CompileMode { - EXEC_MODE, - EVAL_MODE, - SINGLE_MODE -}; - struct CodeObject { _Source src; _Str co_name; - CompileMode mode; CodeObject(_Source src, _Str co_name, CompileMode mode=EXEC_MODE) { this->src = src; this->co_name = co_name; - this->mode = mode; } std::vector co_code; diff --git a/src/compiler.h b/src/compiler.h index 4ce3ea79..ef81dcfc 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -43,12 +43,7 @@ public: std::unique_ptr parser; std::stack<_Code> codes; std::stack loops; - - CompileMode mode; - bool isCompilingClass = false; - - _Str path = ""; VM* vm; std::unordered_map<_TokenType, GrammarRule> rules; @@ -57,14 +52,19 @@ public: return codes.top(); } + CompileMode mode() { + return parser->src->mode; + } + Loop& getLoop() { return loops.top(); } Compiler(VM* vm, const char* source, _Str filename, CompileMode mode){ this->vm = vm; - this->mode = mode; - this->parser = std::make_unique(filename, source); + this->parser = std::make_unique( + std::make_shared(source, filename, mode) + ); // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ #define METHOD(name) &Compiler::name @@ -584,7 +584,7 @@ __LISTCOMP: void __compileBlockBody(CompilerAction action) { consume(TK(":")); - if(!matchNewLines(mode==SINGLE_MODE)){ + if(!matchNewLines(mode()==SINGLE_MODE)){ syntaxError("expected a new line after ':'"); } consume(TK("@indent")); @@ -746,7 +746,7 @@ __LISTCOMP: // If last op is not an assignment, pop the result. uint8_t lastOp = getCode()->co_code.back().op; if( lastOp != OP_STORE_NAME_PTR && lastOp != OP_STORE_PTR){ - if(mode==SINGLE_MODE && parser->indents.top() == 0){ + if(mode()==SINGLE_MODE && parser->indents.top() == 0){ emitCode(OP_PRINT_EXPR); } emitCode(OP_POP_TOP); @@ -848,7 +848,7 @@ __LITERAL_EXIT: } _Code __fillCode(){ - _Code code = std::make_shared(parser->src, _Str(""), mode); + _Code code = std::make_shared(parser->src, _Str(""), mode()); codes.push(code); // Lex initial tokens. current <-- next. @@ -856,7 +856,7 @@ __LITERAL_EXIT: lexToken(); matchNewLines(); - if(mode == EVAL_MODE) { + if(mode()==EVAL_MODE) { EXPR_TUPLE(); consume(TK("@eof")); return code; diff --git a/src/error.h b/src/error.h index e28d4b28..71338343 100644 --- a/src/error.h +++ b/src/error.h @@ -12,10 +12,17 @@ public: bool isClassDef; }; +enum CompileMode { + EXEC_MODE, + EVAL_MODE, + SINGLE_MODE +}; + struct SourceMetadata { - _Str filename; const char* source; + _Str filename; std::vector lineStarts; + CompileMode mode; _Str getLine(int lineno) const { if(lineno == -1) return ""; @@ -25,12 +32,13 @@ struct SourceMetadata { return _Str(_start, i-_start); } - SourceMetadata(_Str filename, const char* source) { + SourceMetadata(const char* source, _Str filename, CompileMode mode) { // Skip utf8 BOM if there is any. if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3; this->filename = filename; this->source = source; lineStarts.push_back(source); + this->mode = mode; } _Str snapshot(int lineno){ diff --git a/src/parser.h b/src/parser.h index 0fe9ea6e..dee0f82a 100644 --- a/src/parser.h +++ b/src/parser.h @@ -228,10 +228,10 @@ struct Parser { else setNextToken(one); } - Parser(_Str filename, const char* source) { - this->src = std::make_shared(filename, source); - this->token_start = source; - this->current_char = source; + Parser(_Source src) { + this->src = src; + this->token_start = src->source; + this->current_char = src->source; this->nexts.push(Token{TK("@sof"), token_start, 0, current_line}); this->indents.push(0); } diff --git a/src/pocketpy.h b/src/pocketpy.h index cb7d2fe9..b4a834c4 100644 --- a/src/pocketpy.h +++ b/src/pocketpy.h @@ -53,7 +53,7 @@ void __initializeBuiltinFunctions(VM* _vm) { if (args.size() != 1) vm->typeError("eval() takes exactly one argument"); if (!args[0]->isType(vm->_tp_str)) vm->typeError("eval() argument must be a string"); const _Str& expr = vm->PyStr_AS_C(args[0]); - _Code code = compile(vm, expr, "", EVAL_MODE); + _Code code = compile(vm, expr, "", EVAL_MODE); return vm->exec(code); // not working in function }); diff --git a/src/vm.h b/src/vm.h index 0b9e6a51..ba5d4153 100644 --- a/src/vm.h +++ b/src/vm.h @@ -392,7 +392,7 @@ public: } } - if(frame->code->mode == EVAL_MODE) { + if(frame->code->src->mode == EVAL_MODE) { if(frame->stackSize() != 1) { systemError("stack size is not 1 in EVAL_MODE"); }