some rename

Update vm.h

some change

up

Update compiler.h
This commit is contained in:
blueloveTH 2023-02-03 16:52:50 +08:00
parent c447886a36
commit 9d341d2ffa
6 changed files with 71 additions and 70 deletions

View File

@ -420,13 +420,10 @@ class Random:
return self.extract_number() / 2 ** 32 return self.extract_number() / 2 ** 32
def randint(self, a, b): def randint(self, a, b):
assert type(a) is int and type(b) is int
assert a <= b assert a <= b
return int(self.random() * (b - a + 1)) + a return int(self.random() * (b - a + 1)) + a
def uniform(self, a, b): def uniform(self, a, b):
assert type(a) is int or type(a) is float
assert type(b) is int or type(b) is float
if a > b: if a > b:
a, b = b, a a, b = b, a
return self.random() * (b - a) + a return self.random() * (b - a) + a

View File

@ -84,7 +84,7 @@ struct CodeObject {
return co_blocks[_currBlockIndex].type == FOR_LOOP || co_blocks[_currBlockIndex].type == WHILE_LOOP; return co_blocks[_currBlockIndex].type == FOR_LOOP || co_blocks[_currBlockIndex].type == WHILE_LOOP;
} }
void __enterBlock(CodeBlockType type){ void __enter_block(CodeBlockType type){
const CodeBlock& currBlock = co_blocks[_currBlockIndex]; const CodeBlock& currBlock = co_blocks[_currBlockIndex];
std::vector<int> copy(currBlock.id); std::vector<int> copy(currBlock.id);
copy.push_back(-1); copy.push_back(-1);
@ -99,7 +99,7 @@ struct CodeObject {
_currBlockIndex = co_blocks.size()-1; _currBlockIndex = co_blocks.size()-1;
} }
void __exitBlock(){ void __exit_block(){
co_blocks[_currBlockIndex].end = co_code.size(); co_blocks[_currBlockIndex].end = co_code.size();
_currBlockIndex = co_blocks[_currBlockIndex].parent; _currBlockIndex = co_blocks[_currBlockIndex].parent;
if(_currBlockIndex < 0) UNREACHABLE(); if(_currBlockIndex < 0) UNREACHABLE();
@ -242,6 +242,7 @@ public:
inline void push(T&& obj){ s_data.push_back(std::forward<T>(obj)); } inline void push(T&& obj){ s_data.push_back(std::forward<T>(obj)); }
inline void jump_abs(int i){ next_ip = i; } inline void jump_abs(int i){ next_ip = i; }
inline void jump_rel(int i){ next_ip = ip + i; }
void jump_abs_safe(int target){ void jump_abs_safe(int target){
const Bytecode& prev = code->co_code[ip]; const Bytecode& prev = code->co_code[ip];

View File

@ -323,7 +323,7 @@ public:
} }
} }
bool matchNewLines(bool repl_throw=false) { bool match_newlines(bool repl_throw=false) {
bool consumed = false; bool consumed = false;
if (peek() == TK("@eol")) { if (peek() == TK("@eol")) {
while (peek() == TK("@eol")) lexToken(); while (peek() == TK("@eol")) lexToken();
@ -336,8 +336,8 @@ public:
} }
bool matchEndStatement() { bool matchEndStatement() {
if (match(TK(";"))) { matchNewLines(); return true; } if (match(TK(";"))) { match_newlines(); return true; }
if (matchNewLines() || peek()==TK("@eof")) return true; if (match_newlines() || peek()==TK("@eof")) return true;
if (peek() == TK("@dedent")) return true; if (peek() == TK("@dedent")) return true;
return false; return false;
} }
@ -497,9 +497,9 @@ public:
} }
void exprGrouping() { void exprGrouping() {
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
EXPR_TUPLE(); EXPR_TUPLE();
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
consume(TK(")")); consume(TK(")"));
} }
@ -508,13 +508,13 @@ public:
int _body_start = co()->co_code.size(); int _body_start = co()->co_code.size();
int ARGC = 0; int ARGC = 0;
do { do {
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
if (peek() == TK("]")) break; if (peek() == TK("]")) break;
EXPR(); ARGC++; EXPR(); ARGC++;
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
if(ARGC == 1 && match(TK("for"))) goto __LISTCOMP; if(ARGC == 1 && match(TK("for"))) goto __LISTCOMP;
} while (match(TK(","))); } while (match(TK(",")));
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
consume(TK("]")); consume(TK("]"));
emit(OP_BUILD_LIST, ARGC); emit(OP_BUILD_LIST, ARGC);
return; return;
@ -526,7 +526,7 @@ __LISTCOMP:
co()->co_code[_patch].arg = _body_end; co()->co_code[_patch].arg = _body_end;
emit(OP_BUILD_LIST, 0); emit(OP_BUILD_LIST, 0);
EXPR_FOR_VARS();consume(TK("in"));EXPR_TUPLE(); EXPR_FOR_VARS();consume(TK("in"));EXPR_TUPLE();
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
int _skipPatch = emit(OP_JUMP_ABSOLUTE); int _skipPatch = emit(OP_JUMP_ABSOLUTE);
int _cond_start = co()->co_code.size(); int _cond_start = co()->co_code.size();
@ -538,7 +538,7 @@ __LISTCOMP:
patch_jump(_skipPatch); patch_jump(_skipPatch);
emit(OP_GET_ITER); emit(OP_GET_ITER);
co()->__enterBlock(FOR_LOOP); co()->__enter_block(FOR_LOOP);
emit(OP_FOR_ITER); emit(OP_FOR_ITER);
if(_cond_end_return != -1) { // there is an if condition if(_cond_end_return != -1) { // there is an if condition
@ -556,8 +556,8 @@ __LISTCOMP:
} }
emit(OP_LOOP_CONTINUE, -1, true); emit(OP_LOOP_CONTINUE, -1, true);
co()->__exitBlock(); co()->__exit_block();
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
consume(TK("]")); consume(TK("]"));
} }
@ -565,7 +565,7 @@ __LISTCOMP:
bool parsing_dict = false; bool parsing_dict = false;
int size = 0; int size = 0;
do { do {
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
if (peek() == TK("}")) break; if (peek() == TK("}")) break;
EXPR(); EXPR();
if(peek() == TK(":")) parsing_dict = true; if(peek() == TK(":")) parsing_dict = true;
@ -574,7 +574,7 @@ __LISTCOMP:
EXPR(); EXPR();
} }
size++; size++;
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
} while (match(TK(","))); } while (match(TK(",")));
consume(TK("}")); consume(TK("}"));
@ -586,7 +586,7 @@ __LISTCOMP:
int ARGC = 0; int ARGC = 0;
int KWARGC = 0; int KWARGC = 0;
do { do {
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
if (peek() == TK(")")) break; if (peek() == TK(")")) break;
if(peek() == TK("@id") && peek_next() == TK("=")) { if(peek() == TK("@id") && peek_next() == TK("=")) {
consume(TK("@id")); consume(TK("@id"));
@ -600,7 +600,7 @@ __LISTCOMP:
EXPR(); EXPR();
ARGC++; ARGC++;
} }
matchNewLines(mode()==SINGLE_MODE); match_newlines(mode()==SINGLE_MODE);
} while (match(TK(","))); } while (match(TK(",")));
consume(TK(")")); consume(TK(")"));
emit(OP_CALL, (KWARGC << 16) | ARGC); emit(OP_CALL, (KWARGC << 16) | ARGC);
@ -648,7 +648,6 @@ __LISTCOMP:
consume(TK("]")); consume(TK("]"));
} }
} }
emit(OP_BUILD_INDEX_REF); emit(OP_BUILD_INDEX_REF);
} }
@ -684,14 +683,14 @@ __LISTCOMP:
void __compileBlockBody(CompilerAction action) { void __compileBlockBody(CompilerAction action) {
consume(TK(":")); consume(TK(":"));
if(!matchNewLines(mode()==SINGLE_MODE)){ if(!match_newlines(mode()==SINGLE_MODE)){
syntaxError("expected a new line after ':'"); syntaxError("expected a new line after ':'");
} }
consume(TK("@indent")); consume(TK("@indent"));
while (peek() != TK("@dedent")) { while (peek() != TK("@dedent")) {
matchNewLines(); match_newlines();
(this->*action)(); (this->*action)();
matchNewLines(); match_newlines();
} }
consume(TK("@dedent")); consume(TK("@dedent"));
} }
@ -699,7 +698,7 @@ __LISTCOMP:
Token compileImportPath() { Token compileImportPath() {
consume(TK("@id")); consume(TK("@id"));
Token tkmodule = parser->prev; Token tkmodule = parser->prev;
int index = co()->add_name(tkmodule.str(), NAME_GLOBAL); int index = co()->add_name(tkmodule.str(), NAME_SPECIAL);
emit(OP_IMPORT_NAME, index); emit(OP_IMPORT_NAME, index);
return tkmodule; return tkmodule;
} }
@ -726,7 +725,7 @@ __LISTCOMP:
emit(OP_DUP_TOP); emit(OP_DUP_TOP);
consume(TK("@id")); consume(TK("@id"));
Token tkname = parser->prev; Token tkname = parser->prev;
int index = co()->add_name(tkname.str(), NAME_GLOBAL); int index = co()->add_name(tkname.str(), NAME_ATTR);
emit(OP_BUILD_ATTR_REF, index); emit(OP_BUILD_ATTR_REF, index);
if (match(TK("as"))) { if (match(TK("as"))) {
consume(TK("@id")); consume(TK("@id"));
@ -754,7 +753,7 @@ __LISTCOMP:
} }
void compileIfStatement() { void compileIfStatement() {
matchNewLines(); match_newlines();
EXPR_TUPLE(); EXPR_TUPLE();
int ifpatch = emit(OP_POP_JUMP_IF_FALSE); int ifpatch = emit(OP_POP_JUMP_IF_FALSE);
@ -776,13 +775,13 @@ __LISTCOMP:
} }
void compileWhileLoop() { void compileWhileLoop() {
co()->__enterBlock(WHILE_LOOP); co()->__enter_block(WHILE_LOOP);
EXPR_TUPLE(); EXPR_TUPLE();
int patch = emit(OP_POP_JUMP_IF_FALSE); int patch = emit(OP_POP_JUMP_IF_FALSE);
compileBlockBody(); compileBlockBody();
emit(OP_LOOP_CONTINUE, -1, true); emit(OP_LOOP_CONTINUE, -1, true);
patch_jump(patch); patch_jump(patch);
co()->__exitBlock(); co()->__exit_block();
} }
void EXPR_FOR_VARS(){ void EXPR_FOR_VARS(){
@ -797,26 +796,31 @@ __LISTCOMP:
void compileForLoop() { void compileForLoop() {
EXPR_FOR_VARS();consume(TK("in")); EXPR_TUPLE(); EXPR_FOR_VARS();consume(TK("in")); EXPR_TUPLE();
emit(OP_GET_ITER); emit(OP_GET_ITER);
co()->__enterBlock(FOR_LOOP); co()->__enter_block(FOR_LOOP);
emit(OP_FOR_ITER); emit(OP_FOR_ITER);
compileBlockBody(); compileBlockBody();
emit(OP_LOOP_CONTINUE, -1, true); emit(OP_LOOP_CONTINUE, -1, true);
co()->__exitBlock(); co()->__exit_block();
} }
void compileTryExcept() { void compileTryExcept() {
co()->__enterBlock(TRY_EXCEPT); co()->__enter_block(TRY_EXCEPT);
compileBlockBody(); compileBlockBody();
int patch = emit(OP_JUMP_ABSOLUTE); int patch = emit(OP_JUMP_ABSOLUTE);
co()->__exitBlock(); co()->__exit_block();
consume(TK("except")); consume(TK("except"));
if(match(TK("@id"))){ // exception name if(match(TK("@id"))){
compileBlockBody(); int name_idx = co()->add_name(parser->prev.str(), NAME_SPECIAL);
} emit(OP_EXCEPTION_MATCH, name_idx);
if(match(TK("finally"))){ }else{
consume(TK(":")); emit(OP_LOAD_TRUE);
syntaxError("finally is not supported yet");
} }
int patch_2 = emit(OP_POP_JUMP_IF_FALSE);
emit(OP_POP_TOP); // pop the exception on match
compileBlockBody();
emit(OP_JUMP_RELATIVE, 1);
patch_jump(patch_2);
emit(OP_RE_RAISE); // no match, re-raise
patch_jump(patch); patch_jump(patch);
} }
@ -871,23 +875,21 @@ __LISTCOMP:
consume(TK(".")); consume(TK("@id")); consume(TK(".")); consume(TK("@id"));
co()->add_label(parser->prev.str()); co()->add_label(parser->prev.str());
consumeEndStatement(); consumeEndStatement();
} else if(match(TK("goto"))){ } else if(match(TK("goto"))){ // https://entrian.com/goto/
// https://entrian.com/goto/
if(mode() != EXEC_MODE) syntaxError("'goto' is only available in EXEC_MODE"); if(mode() != EXEC_MODE) syntaxError("'goto' is only available in EXEC_MODE");
consume(TK(".")); consume(TK("@id")); consume(TK(".")); consume(TK("@id"));
emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(parser->prev.str()))); emit(OP_GOTO, co()->add_name(parser->prev.str(), NAME_SPECIAL));
emit(OP_GOTO);
consumeEndStatement(); consumeEndStatement();
} else if(match(TK("raise"))){ } else if(match(TK("raise"))){
consume(TK("@id")); // dummy exception type consume(TK("@id"));
emit(OP_LOAD_CONST, co()->add_const(vm->PyStr(parser->prev.str()))); int dummy_t = co()->add_name(parser->prev.str(), NAME_SPECIAL);
if(match(TK("("))){ if(match(TK("("))){
EXPR(); EXPR();
consume(TK(")")); consume(TK(")"));
}else{ }else{
emit(OP_LOAD_NONE); // ...? emit(OP_LOAD_NONE);
} }
emit(OP_RAISE_ERROR); emit(OP_RAISE, dummy_t);
consumeEndStatement(); consumeEndStatement();
} else if(match(TK("del"))){ } else if(match(TK("del"))){
EXPR(); EXPR();
@ -917,8 +919,7 @@ __LISTCOMP:
consume(TK("@id")); consume(TK("@id"));
int clsNameIdx = co()->add_name(parser->prev.str(), NAME_GLOBAL); int clsNameIdx = co()->add_name(parser->prev.str(), NAME_GLOBAL);
int superClsNameIdx = -1; int superClsNameIdx = -1;
if(match(TK("("))){ if(match(TK("(")) && match(TK("@id"))){
consume(TK("@id"));
superClsNameIdx = co()->add_name(parser->prev.str(), NAME_GLOBAL); superClsNameIdx = co()->add_name(parser->prev.str(), NAME_GLOBAL);
consume(TK(")")); consume(TK(")"));
} }
@ -935,7 +936,7 @@ __LISTCOMP:
int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
do { do {
if(state == 3) syntaxError("**kwargs should be the last argument"); if(state == 3) syntaxError("**kwargs should be the last argument");
matchNewLines(); match_newlines();
if(match(TK("*"))){ if(match(TK("*"))){
if(state < 1) state = 1; if(state < 1) state = 1;
else syntaxError("*args should be placed before **kwargs"); else syntaxError("*args should be placed before **kwargs");
@ -1038,7 +1039,7 @@ __LISTCOMP:
// Lex initial tokens. current <-- next. // Lex initial tokens. current <-- next.
lexToken(); lexToken();
lexToken(); lexToken();
matchNewLines(); match_newlines();
if(mode()==EVAL_MODE) { if(mode()==EVAL_MODE) {
EXPR_TUPLE(); EXPR_TUPLE();
@ -1057,7 +1058,7 @@ __LISTCOMP:
while (!match(TK("@eof"))) { while (!match(TK("@eof"))) {
compileTopLevelStatement(); compileTopLevelStatement();
matchNewLines(); match_newlines();
} }
code->optimize(); code->optimize();
return code; return code;

View File

@ -42,6 +42,7 @@ OPCODE(JUMP_IF_TRUE_OR_POP)
OPCODE(JUMP_IF_FALSE_OR_POP) OPCODE(JUMP_IF_FALSE_OR_POP)
OPCODE(GOTO) OPCODE(GOTO)
OPCODE(JUMP_RELATIVE)
OPCODE(LOAD_CONST) OPCODE(LOAD_CONST)
OPCODE(LOAD_NONE) OPCODE(LOAD_NONE)
@ -54,7 +55,9 @@ OPCODE(LOAD_NAME)
OPCODE(LOAD_NAME_REF) OPCODE(LOAD_NAME_REF)
OPCODE(ASSERT) OPCODE(ASSERT)
OPCODE(RAISE_ERROR) OPCODE(EXCEPTION_MATCH)
OPCODE(RAISE)
OPCODE(RE_RAISE)
OPCODE(BUILD_INDEX_REF) OPCODE(BUILD_INDEX_REF)
OPCODE(BUILD_ATTR_REF) OPCODE(BUILD_ATTR_REF)

View File

@ -13,8 +13,9 @@ struct BaseRef {
enum NameScope { enum NameScope {
NAME_LOCAL = 0, NAME_LOCAL = 0,
NAME_GLOBAL = 1, NAME_GLOBAL,
NAME_ATTR = 2, NAME_ATTR,
NAME_SPECIAL,
}; };
struct NameRef : BaseRef { struct NameRef : BaseRef {

View File

@ -187,18 +187,18 @@ protected:
PyVar expr = frame->pop_value(this); PyVar expr = frame->pop_value(this);
if(asBool(expr) != True) _error("AssertionError", ""); if(asBool(expr) != True) _error("AssertionError", "");
} break; } break;
case OP_RAISE_ERROR: case OP_EXCEPTION_MATCH: break;
case OP_RAISE:
{ {
_Str msg = PyStr_AS_C(asRepr(frame->pop_value(this))); _Str msg = PyStr_AS_C(asStr(frame->pop_value(this)));
_Str type = PyStr_AS_C(frame->pop_value(this)); _Str type = frame->code->co_names[byte.arg].first;
_error(type, msg); _error(type, msg);
} break; } break;
case OP_RE_RAISE: break;
case OP_BUILD_LIST: case OP_BUILD_LIST:
{ frame->push(PyList(
frame->push(PyList( frame->pop_n_values_reversed(this, byte.arg).toList()));
frame->pop_n_values_reversed(this, byte.arg).toList() break;
));
} break;
case OP_BUILD_MAP: case OP_BUILD_MAP:
{ {
pkpy::ArgList items = frame->pop_n_values_reversed(this, byte.arg*2); pkpy::ArgList items = frame->pop_n_values_reversed(this, byte.arg*2);
@ -230,14 +230,12 @@ protected:
frame->push(std::move(ret)); frame->push(std::move(ret));
} break; } break;
case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); break; case OP_JUMP_ABSOLUTE: frame->jump_abs(byte.arg); break;
case OP_JUMP_RELATIVE: frame->jump_rel(byte.arg); break;
case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); break; case OP_SAFE_JUMP_ABSOLUTE: frame->jump_abs_safe(byte.arg); break;
case OP_GOTO: { case OP_GOTO: {
PyVar obj = frame->pop_value(this); const _Str& label = frame->code->co_names[byte.arg].first;
const _Str& label = PyStr_AS_C(obj);
int* target = frame->code->co_labels.try_get(label); int* target = frame->code->co_labels.try_get(label);
if(target == nullptr){ if(target == nullptr) _error("KeyError", "label '" + label + "' not found");
_error("KeyError", "label '" + label + "' not found");
}
frame->jump_abs_safe(*target); frame->jump_abs_safe(*target);
} break; } break;
case OP_GET_ITER: case OP_GET_ITER:
@ -326,7 +324,7 @@ protected:
} }
if(frame->code->src->mode == EVAL_MODE || frame->code->src->mode == JSON_MODE){ if(frame->code->src->mode == EVAL_MODE || frame->code->src->mode == JSON_MODE){
if(frame->stack_size() != 1) throw std::runtime_error("stack size is not 1 in EVAL_MODE/JSON_MODE"); if(frame->stack_size() != 1) throw std::runtime_error("stack size is not 1 in EVAL/JSON_MODE");
return frame->pop_value(this); return frame->pop_value(this);
} }