improve error report

This commit is contained in:
blueloveTH 2022-11-09 19:19:22 +08:00
parent 24f3628b8d
commit fa3e46bc46
6 changed files with 27 additions and 27 deletions

View File

@ -26,21 +26,13 @@ _Str pad(const _Str& s, const int n){
return s + _Str(n - s.size(), ' '); return s + _Str(n - s.size(), ' ');
} }
enum CompileMode {
EXEC_MODE,
EVAL_MODE,
SINGLE_MODE
};
struct CodeObject { struct CodeObject {
_Source src; _Source src;
_Str co_name; _Str co_name;
CompileMode mode;
CodeObject(_Source src, _Str co_name, CompileMode mode=EXEC_MODE) { CodeObject(_Source src, _Str co_name, CompileMode mode=EXEC_MODE) {
this->src = src; this->src = src;
this->co_name = co_name; this->co_name = co_name;
this->mode = mode;
} }
std::vector<ByteCode> co_code; std::vector<ByteCode> co_code;

View File

@ -43,12 +43,7 @@ public:
std::unique_ptr<Parser> parser; std::unique_ptr<Parser> parser;
std::stack<_Code> codes; std::stack<_Code> codes;
std::stack<Loop> loops; std::stack<Loop> loops;
CompileMode mode;
bool isCompilingClass = false; bool isCompilingClass = false;
_Str path = "<?>";
VM* vm; VM* vm;
std::unordered_map<_TokenType, GrammarRule> rules; std::unordered_map<_TokenType, GrammarRule> rules;
@ -57,14 +52,19 @@ public:
return codes.top(); return codes.top();
} }
CompileMode mode() {
return parser->src->mode;
}
Loop& getLoop() { Loop& getLoop() {
return loops.top(); return loops.top();
} }
Compiler(VM* vm, const char* source, _Str filename, CompileMode mode){ Compiler(VM* vm, const char* source, _Str filename, CompileMode mode){
this->vm = vm; this->vm = vm;
this->mode = mode; this->parser = std::make_unique<Parser>(
this->parser = std::make_unique<Parser>(filename, source); std::make_shared<SourceMetadata>(source, filename, mode)
);
// http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
#define METHOD(name) &Compiler::name #define METHOD(name) &Compiler::name
@ -584,7 +584,7 @@ __LISTCOMP:
void __compileBlockBody(CompilerAction action) { void __compileBlockBody(CompilerAction action) {
consume(TK(":")); consume(TK(":"));
if(!matchNewLines(mode==SINGLE_MODE)){ if(!matchNewLines(mode()==SINGLE_MODE)){
syntaxError("expected a new line after ':'"); syntaxError("expected a new line after ':'");
} }
consume(TK("@indent")); consume(TK("@indent"));
@ -746,7 +746,7 @@ __LISTCOMP:
// If last op is not an assignment, pop the result. // If last op is not an assignment, pop the result.
uint8_t lastOp = getCode()->co_code.back().op; uint8_t lastOp = getCode()->co_code.back().op;
if( lastOp != OP_STORE_NAME_PTR && lastOp != OP_STORE_PTR){ 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_PRINT_EXPR);
} }
emitCode(OP_POP_TOP); emitCode(OP_POP_TOP);
@ -848,7 +848,7 @@ __LITERAL_EXIT:
} }
_Code __fillCode(){ _Code __fillCode(){
_Code code = std::make_shared<CodeObject>(parser->src, _Str("<module>"), mode); _Code code = std::make_shared<CodeObject>(parser->src, _Str("<module>"), mode());
codes.push(code); codes.push(code);
// Lex initial tokens. current <-- next. // Lex initial tokens. current <-- next.
@ -856,7 +856,7 @@ __LITERAL_EXIT:
lexToken(); lexToken();
matchNewLines(); matchNewLines();
if(mode == EVAL_MODE) { if(mode()==EVAL_MODE) {
EXPR_TUPLE(); EXPR_TUPLE();
consume(TK("@eof")); consume(TK("@eof"));
return code; return code;

View File

@ -12,10 +12,17 @@ public:
bool isClassDef; bool isClassDef;
}; };
enum CompileMode {
EXEC_MODE,
EVAL_MODE,
SINGLE_MODE
};
struct SourceMetadata { struct SourceMetadata {
_Str filename;
const char* source; const char* source;
_Str filename;
std::vector<const char*> lineStarts; std::vector<const char*> lineStarts;
CompileMode mode;
_Str getLine(int lineno) const { _Str getLine(int lineno) const {
if(lineno == -1) return "<?>"; if(lineno == -1) return "<?>";
@ -25,12 +32,13 @@ struct SourceMetadata {
return _Str(_start, i-_start); 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. // Skip utf8 BOM if there is any.
if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3; if (strncmp(source, "\xEF\xBB\xBF", 3) == 0) source += 3;
this->filename = filename; this->filename = filename;
this->source = source; this->source = source;
lineStarts.push_back(source); lineStarts.push_back(source);
this->mode = mode;
} }
_Str snapshot(int lineno){ _Str snapshot(int lineno){

View File

@ -228,10 +228,10 @@ struct Parser {
else setNextToken(one); else setNextToken(one);
} }
Parser(_Str filename, const char* source) { Parser(_Source src) {
this->src = std::make_shared<SourceMetadata>(filename, source); this->src = src;
this->token_start = source; this->token_start = src->source;
this->current_char = source; this->current_char = src->source;
this->nexts.push(Token{TK("@sof"), token_start, 0, current_line}); this->nexts.push(Token{TK("@sof"), token_start, 0, current_line});
this->indents.push(0); this->indents.push(0);
} }

View File

@ -53,7 +53,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
if (args.size() != 1) vm->typeError("eval() takes exactly one argument"); 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"); if (!args[0]->isType(vm->_tp_str)) vm->typeError("eval() argument must be a string");
const _Str& expr = vm->PyStr_AS_C(args[0]); const _Str& expr = vm->PyStr_AS_C(args[0]);
_Code code = compile(vm, expr, "<f-string>", EVAL_MODE); _Code code = compile(vm, expr, "<eval>", EVAL_MODE);
return vm->exec(code); // not working in function return vm->exec(code); // not working in function
}); });

View File

@ -392,7 +392,7 @@ public:
} }
} }
if(frame->code->mode == EVAL_MODE) { if(frame->code->src->mode == EVAL_MODE) {
if(frame->stackSize() != 1) { if(frame->stackSize() != 1) {
systemError("stack size is not 1 in EVAL_MODE"); systemError("stack size is not 1 in EVAL_MODE");
} }