mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 04:50: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(), ' ');
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
|
12
src/error.h
12
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<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){
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user