mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
some rename
Update vm.h some change up Update compiler.h
This commit is contained in:
parent
c447886a36
commit
9d341d2ffa
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
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();
|
||||
}
|
||||
if(match(TK("finally"))){
|
||||
consume(TK(":"));
|
||||
syntaxError("finally is not supported yet");
|
||||
}
|
||||
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;
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
24
src/vm.h
24
src/vm.h
@ -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->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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user