mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +00:00
improve error report
This commit is contained in:
parent
24f3628b8d
commit
fa3e46bc46
@ -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;
|
||||||
|
@ -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;
|
||||||
|
12
src/error.h
12
src/error.h
@ -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){
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user