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(), ' ');
}
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<ByteCode> co_code;

View File

@ -43,12 +43,7 @@ public:
std::unique_ptr<Parser> parser;
std::stack<_Code> codes;
std::stack<Loop> 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<Parser>(filename, source);
this->parser = std::make_unique<Parser>(
std::make_shared<SourceMetadata>(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<CodeObject>(parser->src, _Str("<module>"), mode);
_Code code = std::make_shared<CodeObject>(parser->src, _Str("<module>"), 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;

View File

@ -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<const char*> 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){

View File

@ -228,10 +228,10 @@ struct Parser {
else setNextToken(one);
}
Parser(_Str filename, const char* source) {
this->src = std::make_shared<SourceMetadata>(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);
}

View File

@ -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, "<f-string>", EVAL_MODE);
_Code code = compile(vm, expr, "<eval>", EVAL_MODE);
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) {
systemError("stack size is not 1 in EVAL_MODE");
}