From 84cdb2068763ab87bce98662fa316c5a4f8fdac8 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 8 Nov 2022 21:52:44 +0800 Subject: [PATCH] fix a bug of REPL --- src/codeobject.h | 1 + src/compiler.h | 15 +++++++-------- src/error.h | 6 +++++- src/main.cpp | 14 ++++++++++---- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/codeobject.h b/src/codeobject.h index 77a05389..576990d3 100644 --- a/src/codeobject.h +++ b/src/codeobject.h @@ -67,6 +67,7 @@ struct CodeObject { int prev_line = -1; for(int i=0; i codes; std::stack loops; + CompileMode mode; + bool isCompilingClass = false; _Str path = ""; @@ -59,13 +61,10 @@ public: return loops.top(); } - CompileMode mode() { - return getCode()->mode; - } - Compiler(VM* vm, const char* source, _Code code){ this->vm = vm; this->codes.push(code); + this->mode = code->mode; if (!code->co_filename.empty()) path = code->co_filename; this->parser = std::make_unique(source); @@ -281,7 +280,7 @@ public: consumed = true; } if (repl_throw && peek() == TK("@eof")){ - throw NeedMoreLines(); + throw NeedMoreLines(isCompilingClass); } return consumed; } @@ -579,7 +578,7 @@ __LISTCOMP: void __compileBlockBody(CompilerAction action) { consume(TK(":")); - if(!matchNewLines(mode()==SINGLE_MODE)){ + if(!matchNewLines(mode==SINGLE_MODE)){ throw SyntaxError(path, parser->previous, "expected a new line after ':'"); } consume(TK("@indent")); @@ -745,7 +744,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); @@ -853,7 +852,7 @@ __LITERAL_EXIT: lexToken(); matchNewLines(); - if(mode() == EVAL_MODE) { + if(mode == EVAL_MODE) { EXPR_TUPLE(); consume(TK("@eof")); return; diff --git a/src/error.h b/src/error.h index 3231238f..5a246ac1 100644 --- a/src/error.h +++ b/src/error.h @@ -7,7 +7,11 @@ #include "parser.h" -class NeedMoreLines : public std::exception {}; +class NeedMoreLines : public std::exception { +public: + NeedMoreLines(bool isClassDef) : isClassDef(isClassDef) {} + bool isClassDef; +}; class SyntaxError : public std::exception { private: diff --git a/src/main.cpp b/src/main.cpp index bd5d82f4..c5cae79a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,7 +40,8 @@ VM* newVM(){ void REPL(){ std::cout << "pocketpy 0.1.0" << std::endl; - bool need_more_lines = false; + int need_more_lines = 0; + std::string buffer; VM* vm = newVM(); @@ -54,12 +55,16 @@ void REPL(){ buffer += line; buffer += '\n'; int n = buffer.size(); - if(n>=2 && buffer[n-1]=='\n' && buffer[n-2]=='\n'){ - need_more_lines = false; + if(n>=need_more_lines){ + for(int i=buffer.size()-need_more_lines; i(&e)){ + if(dynamic_cast(&e)){ buffer += line; buffer += '\n'; + need_more_lines = e.isClassDef ? 3 : 2; }else{ vm->printFn(e.what()); vm->printFn("\n");