fix a bug of REPL

This commit is contained in:
blueloveTH 2022-11-08 21:52:44 +08:00
parent a7f3cab132
commit 84cdb20687
4 changed files with 23 additions and 13 deletions

View File

@ -67,6 +67,7 @@ struct CodeObject {
int prev_line = -1;
for(int i=0; i<co_code.size(); i++){
const ByteCode& byte = co_code[i];
if(byte.op == OP_NO_OP) continue;
_Str line = std::to_string(byte.line);
if(byte.line == prev_line) line = "";
else{

View File

@ -44,6 +44,8 @@ public:
std::stack<_Code> codes;
std::stack<Loop> 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<Parser>(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;

View File

@ -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:

View File

@ -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<buffer.size(); i++){
if(buffer[i] != '\n') goto __NOT_ENOUGH_LINES;
}
need_more_lines = 0;
line = buffer;
mode = EXEC_MODE; // tmp set to EXEC_MODE
buffer.clear();
}else{
__NOT_ENOUGH_LINES:
continue;
}
}else{
@ -74,9 +79,10 @@ void REPL(){
#else
}catch(std::exception& e){
#endif
if(need_more_lines = dynamic_cast<NeedMoreLines*>(&e)){
if(dynamic_cast<NeedMoreLines*>(&e)){
buffer += line;
buffer += '\n';
need_more_lines = e.isClassDef ? 3 : 2;
}else{
vm->printFn(e.what());
vm->printFn("\n");