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

View File

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

View File

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

View File

@ -187,18 +187,18 @@ protected:
PyVar expr = frame->pop_value(this);
if(asBool(expr) != True) _error("AssertionError", "");
} break;
case OP_RAISE_ERROR:
case OP_EXCEPTION_MATCH: break;
case OP_RAISE:
{
_Str msg = PyStr_AS_C(asRepr(frame->pop_value(this)));
_Str type = PyStr_AS_C(frame->pop_value(this));
_Str msg = PyStr_AS_C(asStr(frame->pop_value(this)));
_Str type = frame->code->co_names[byte.arg].first;
_error(type, msg);
} break;
case OP_RE_RAISE: break;
case OP_BUILD_LIST:
{
frame->push(PyList(
frame->pop_n_values_reversed(this, byte.arg).toList()
));
} break;
frame->push(PyList(
frame->pop_n_values_reversed(this, byte.arg).toList()));
break;
case OP_BUILD_MAP:
{
pkpy::ArgList items = frame->pop_n_values_reversed(this, byte.arg*2);
@ -230,14 +230,12 @@ protected:
frame->push(std::move(ret));
} 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_GOTO: {
PyVar obj = frame->pop_value(this);
const _Str& label = PyStr_AS_C(obj);
const _Str& label = frame->code->co_names[byte.arg].first;
int* target = frame->code->co_labels.try_get(label);
if(target == nullptr){
_error("KeyError", "label '" + label + "' not found");
}
if(target == nullptr) _error("KeyError", "label '" + label + "' not found");
frame->jump_abs_safe(*target);
} break;
case OP_GET_ITER:
@ -326,7 +324,7 @@ protected:
}
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);
}