rename emit into emit_ to make QT happy

This commit is contained in:
blueloveTH 2023-10-16 13:56:07 +08:00
parent f3acafe44c
commit 901f702f00
3 changed files with 260 additions and 260 deletions

View File

@ -15,7 +15,7 @@ typedef std::unique_ptr<Expr> Expr_;
struct Expr{ struct Expr{
int line = 0; int line = 0;
virtual ~Expr() = default; virtual ~Expr() = default;
virtual void emit(CodeEmitContext* ctx) = 0; virtual void emit_(CodeEmitContext* ctx) = 0;
virtual bool is_literal() const { return false; } virtual bool is_literal() const { return false; }
virtual bool is_json_object() const { return false; } virtual bool is_json_object() const { return false; }
virtual bool is_attrib() const { return false; } virtual bool is_attrib() const { return false; }
@ -60,7 +60,7 @@ struct CodeEmitContext{
void exit_block(); void exit_block();
void emit_expr(); // clear the expression stack and generate bytecode void emit_expr(); // clear the expression stack and generate bytecode
std::string _log_s_expr(); std::string _log_s_expr();
int emit(Opcode opcode, uint16_t arg, int line); int emit_(Opcode opcode, uint16_t arg, int line);
void patch_jump(int index); void patch_jump(int index);
bool add_label(StrName name); bool add_label(StrName name);
int add_varname(StrName name); int add_varname(StrName name);
@ -73,7 +73,7 @@ struct NameExpr: Expr{
StrName name; StrName name;
NameScope scope; NameScope scope;
NameExpr(StrName name, NameScope scope): name(name), scope(scope) {} NameExpr(StrName name, NameScope scope): name(name), scope(scope) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
bool emit_del(CodeEmitContext* ctx) override; bool emit_del(CodeEmitContext* ctx) override;
bool emit_store(CodeEmitContext* ctx) override; bool emit_store(CodeEmitContext* ctx) override;
bool is_name() const override { return true; } bool is_name() const override { return true; }
@ -82,7 +82,7 @@ struct NameExpr: Expr{
struct InvertExpr: Expr{ struct InvertExpr: Expr{
Expr_ child; Expr_ child;
InvertExpr(Expr_&& child): child(std::move(child)) {} InvertExpr(Expr_&& child): child(std::move(child)) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct StarredExpr: Expr{ struct StarredExpr: Expr{
@ -90,26 +90,26 @@ struct StarredExpr: Expr{
Expr_ child; Expr_ child;
StarredExpr(int level, Expr_&& child): level(level), child(std::move(child)) {} StarredExpr(int level, Expr_&& child): level(level), child(std::move(child)) {}
int star_level() const override { return level; } int star_level() const override { return level; }
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
bool emit_store(CodeEmitContext* ctx) override; bool emit_store(CodeEmitContext* ctx) override;
}; };
struct NotExpr: Expr{ struct NotExpr: Expr{
Expr_ child; Expr_ child;
NotExpr(Expr_&& child): child(std::move(child)) {} NotExpr(Expr_&& child): child(std::move(child)) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct AndExpr: Expr{ struct AndExpr: Expr{
Expr_ lhs; Expr_ lhs;
Expr_ rhs; Expr_ rhs;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct OrExpr: Expr{ struct OrExpr: Expr{
Expr_ lhs; Expr_ lhs;
Expr_ rhs; Expr_ rhs;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
// [None, True, False, ...] // [None, True, False, ...]
@ -118,26 +118,26 @@ struct Literal0Expr: Expr{
Literal0Expr(TokenIndex token): token(token) {} Literal0Expr(TokenIndex token): token(token) {}
bool is_json_object() const override { return true; } bool is_json_object() const override { return true; }
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct LongExpr: Expr{ struct LongExpr: Expr{
Str s; Str s;
LongExpr(const Str& s): s(s) {} LongExpr(const Str& s): s(s) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct BytesExpr: Expr{ struct BytesExpr: Expr{
Str s; Str s;
BytesExpr(const Str& s): s(s) {} BytesExpr(const Str& s): s(s) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
// @num, @str which needs to invoke OP_LOAD_CONST // @num, @str which needs to invoke OP_LOAD_CONST
struct LiteralExpr: Expr{ struct LiteralExpr: Expr{
TokenValue value; TokenValue value;
LiteralExpr(TokenValue value): value(value) {} LiteralExpr(TokenValue value): value(value) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
bool is_literal() const override { return true; } bool is_literal() const override { return true; }
bool is_json_object() const override { return true; } bool is_json_object() const override { return true; }
}; };
@ -145,7 +145,7 @@ struct LiteralExpr: Expr{
struct NegatedExpr: Expr{ struct NegatedExpr: Expr{
Expr_ child; Expr_ child;
NegatedExpr(Expr_&& child): child(std::move(child)) {} NegatedExpr(Expr_&& child): child(std::move(child)) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
bool is_json_object() const override { return child->is_literal(); } bool is_json_object() const override { return child->is_literal(); }
}; };
@ -153,14 +153,14 @@ struct SliceExpr: Expr{
Expr_ start; Expr_ start;
Expr_ stop; Expr_ stop;
Expr_ step; Expr_ step;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct DictItemExpr: Expr{ struct DictItemExpr: Expr{
Expr_ key; // maybe nullptr if it is **kwargs Expr_ key; // maybe nullptr if it is **kwargs
Expr_ value; Expr_ value;
int star_level() const override { return value->star_level(); } int star_level() const override { return value->star_level(); }
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct SequenceExpr: Expr{ struct SequenceExpr: Expr{
@ -168,9 +168,9 @@ struct SequenceExpr: Expr{
SequenceExpr(std::vector<Expr_>&& items): items(std::move(items)) {} SequenceExpr(std::vector<Expr_>&& items): items(std::move(items)) {}
virtual Opcode opcode() const = 0; virtual Opcode opcode() const = 0;
void emit(CodeEmitContext* ctx) override { void emit_(CodeEmitContext* ctx) override {
for(auto& item: items) item->emit(ctx); for(auto& item: items) item->emit_(ctx);
ctx->emit(opcode(), items.size(), line); ctx->emit_(opcode(), items.size(), line);
} }
}; };
@ -223,7 +223,7 @@ struct CompExpr: Expr{
virtual Opcode op0() = 0; virtual Opcode op0() = 0;
virtual Opcode op1() = 0; virtual Opcode op1() = 0;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct ListCompExpr: CompExpr{ struct ListCompExpr: CompExpr{
@ -246,9 +246,9 @@ struct LambdaExpr: Expr{
LambdaExpr(FuncDecl_ decl): decl(decl) {} LambdaExpr(FuncDecl_ decl): decl(decl) {}
void emit(CodeEmitContext* ctx) override { void emit_(CodeEmitContext* ctx) override {
int index = ctx->add_func_decl(decl); int index = ctx->add_func_decl(decl);
ctx->emit(OP_LOAD_FUNCTION, index, line); ctx->emit_(OP_LOAD_FUNCTION, index, line);
} }
}; };
@ -256,13 +256,13 @@ struct FStringExpr: Expr{
Str src; Str src;
FStringExpr(const Str& src): src(src) {} FStringExpr(const Str& src): src(src) {}
void _load_simple_expr(CodeEmitContext* ctx, Str expr); void _load_simple_expr(CodeEmitContext* ctx, Str expr);
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct SubscrExpr: Expr{ struct SubscrExpr: Expr{
Expr_ a; Expr_ a;
Expr_ b; Expr_ b;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
bool emit_del(CodeEmitContext* ctx) override; bool emit_del(CodeEmitContext* ctx) override;
bool emit_store(CodeEmitContext* ctx) override; bool emit_store(CodeEmitContext* ctx) override;
}; };
@ -273,7 +273,7 @@ struct AttribExpr: Expr{
AttribExpr(Expr_ a, const Str& b): a(std::move(a)), b(b) {} AttribExpr(Expr_ a, const Str& b): a(std::move(a)), b(b) {}
AttribExpr(Expr_ a, Str&& b): a(std::move(a)), b(std::move(b)) {} AttribExpr(Expr_ a, Str&& b): a(std::move(a)), b(std::move(b)) {}
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
bool emit_del(CodeEmitContext* ctx) override; bool emit_del(CodeEmitContext* ctx) override;
bool emit_store(CodeEmitContext* ctx) override; bool emit_store(CodeEmitContext* ctx) override;
void emit_method(CodeEmitContext* ctx); void emit_method(CodeEmitContext* ctx);
@ -285,15 +285,15 @@ struct CallExpr: Expr{
std::vector<Expr_> args; std::vector<Expr_> args;
// **a will be interpreted as a special keyword argument: {"**": a} // **a will be interpreted as a special keyword argument: {"**": a}
std::vector<std::pair<Str, Expr_>> kwargs; std::vector<std::pair<Str, Expr_>> kwargs;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
struct GroupedExpr: Expr{ struct GroupedExpr: Expr{
Expr_ a; Expr_ a;
GroupedExpr(Expr_&& a): a(std::move(a)) {} GroupedExpr(Expr_&& a): a(std::move(a)) {}
void emit(CodeEmitContext* ctx) override{ void emit_(CodeEmitContext* ctx) override{
a->emit(ctx); a->emit_(ctx);
} }
bool emit_del(CodeEmitContext* ctx) override { bool emit_del(CodeEmitContext* ctx) override {
@ -311,7 +311,7 @@ struct BinaryExpr: Expr{
Expr_ rhs; Expr_ rhs;
bool is_compare() const override; bool is_compare() const override;
void _emit_compare(CodeEmitContext* ctx, std::vector<int>& jmps); void _emit_compare(CodeEmitContext* ctx, std::vector<int>& jmps);
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };
@ -319,7 +319,7 @@ struct TernaryExpr: Expr{
Expr_ cond; Expr_ cond;
Expr_ true_expr; Expr_ true_expr;
Expr_ false_expr; Expr_ false_expr;
void emit(CodeEmitContext* ctx) override; void emit_(CodeEmitContext* ctx) override;
}; };

View File

@ -30,8 +30,8 @@ namespace pkpy{
// add a `return None` in the end as a guard // add a `return None` in the end as a guard
// previously, we only do this if the last opcode is not a return // previously, we only do this if the last opcode is not a return
// however, this is buggy...since there may be a jump to the end (out of bound) even if the last opcode is a return // however, this is buggy...since there may be a jump to the end (out of bound) even if the last opcode is a return
ctx()->emit(OP_LOAD_NONE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_LOAD_NONE, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
// some check here // some check here
std::vector<Bytecode>& codes = ctx()->co->codes; std::vector<Bytecode>& codes = ctx()->co->codes;
if(ctx()->co->varnames.size() > PK_MAX_CO_VARNAMES){ if(ctx()->co->varnames.size() > PK_MAX_CO_VARNAMES){
@ -215,7 +215,7 @@ namespace pkpy{
} }
// https://github.com/blueloveTH/pocketpy/issues/37 // https://github.com/blueloveTH/pocketpy/issues/37
parse_expression(PREC_LAMBDA + 1, false); parse_expression(PREC_LAMBDA + 1, false);
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
pop_context(); pop_context();
ctx()->s_expr.push(std::move(e)); ctx()->s_expr.push(std::move(e));
} }
@ -518,7 +518,7 @@ __SUBSCR_END:
do { do {
consume(TK("@id")); consume(TK("@id"));
Str name = prev().str(); Str name = prev().str();
ctx()->emit(OP_IMPORT_PATH, ctx()->add_const(VAR(name)), prev().line); ctx()->emit_(OP_IMPORT_PATH, ctx()->add_const(VAR(name)), prev().line);
if (match(TK("as"))) { if (match(TK("as"))) {
consume(TK("@id")); consume(TK("@id"));
name = prev().str(); name = prev().str();
@ -570,29 +570,29 @@ __EAT_DOTS_END:
} }
} }
ctx()->emit(OP_IMPORT_PATH, ctx()->add_const(VAR(ss.str())), prev().line); ctx()->emit_(OP_IMPORT_PATH, ctx()->add_const(VAR(ss.str())), prev().line);
consume(TK("import")); consume(TK("import"));
if (match(TK("*"))) { if (match(TK("*"))) {
if(name_scope() != NAME_GLOBAL) SyntaxError("from <module> import * can only be used in global scope"); if(name_scope() != NAME_GLOBAL) SyntaxError("from <module> import * can only be used in global scope");
// pop the module and import __all__ // pop the module and import __all__
ctx()->emit(OP_POP_IMPORT_STAR, BC_NOARG, prev().line); ctx()->emit_(OP_POP_IMPORT_STAR, BC_NOARG, prev().line);
consume_end_stmt(); consume_end_stmt();
return; return;
} }
do { do {
ctx()->emit(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
consume(TK("@id")); consume(TK("@id"));
Str name = prev().str(); Str name = prev().str();
ctx()->emit(OP_LOAD_ATTR, StrName(name).index, prev().line); ctx()->emit_(OP_LOAD_ATTR, StrName(name).index, prev().line);
if (match(TK("as"))) { if (match(TK("as"))) {
consume(TK("@id")); consume(TK("@id"));
name = prev().str(); name = prev().str();
} }
ctx()->emit_store_name(name_scope(), StrName(name), prev().line); ctx()->emit_store_name(name_scope(), StrName(name), prev().line);
} while (match(TK(","))); } while (match(TK(",")));
ctx()->emit(OP_POP_TOP, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
consume_end_stmt(); consume_end_stmt();
} }
@ -618,15 +618,15 @@ __EAT_DOTS_END:
void Compiler::compile_if_stmt() { void Compiler::compile_if_stmt() {
EXPR(false); // condition EXPR(false); // condition
int patch = ctx()->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line); int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line);
compile_block_body(); compile_block_body();
if (match(TK("elif"))) { if (match(TK("elif"))) {
int exit_patch = ctx()->emit(OP_JUMP_ABSOLUTE, BC_NOARG, prev().line); int exit_patch = ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, prev().line);
ctx()->patch_jump(patch); ctx()->patch_jump(patch);
compile_if_stmt(); compile_if_stmt();
ctx()->patch_jump(exit_patch); ctx()->patch_jump(exit_patch);
} else if (match(TK("else"))) { } else if (match(TK("else"))) {
int exit_patch = ctx()->emit(OP_JUMP_ABSOLUTE, BC_NOARG, prev().line); int exit_patch = ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, prev().line);
ctx()->patch_jump(patch); ctx()->patch_jump(patch);
compile_block_body(); compile_block_body();
ctx()->patch_jump(exit_patch); ctx()->patch_jump(exit_patch);
@ -638,9 +638,9 @@ __EAT_DOTS_END:
void Compiler::compile_while_loop() { void Compiler::compile_while_loop() {
CodeBlock* block = ctx()->enter_block(WHILE_LOOP); CodeBlock* block = ctx()->enter_block(WHILE_LOOP);
EXPR(false); // condition EXPR(false); // condition
int patch = ctx()->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line); int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, prev().line);
compile_block_body(); compile_block_body();
ctx()->emit(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE); ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE);
ctx()->patch_jump(patch); ctx()->patch_jump(patch);
ctx()->exit_block(); ctx()->exit_block();
// optional else clause // optional else clause
@ -654,13 +654,13 @@ __EAT_DOTS_END:
Expr_ vars = EXPR_VARS(); Expr_ vars = EXPR_VARS();
consume(TK("in")); consume(TK("in"));
EXPR_TUPLE(false); EXPR_TUPLE(false);
ctx()->emit(OP_GET_ITER, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_GET_ITER, BC_NOARG, BC_KEEPLINE);
CodeBlock* block = ctx()->enter_block(FOR_LOOP); CodeBlock* block = ctx()->enter_block(FOR_LOOP);
ctx()->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
bool ok = vars->emit_store(ctx()); bool ok = vars->emit_store(ctx());
if(!ok) SyntaxError(); // this error occurs in `vars` instead of this line, but...nevermind if(!ok) SyntaxError(); // this error occurs in `vars` instead of this line, but...nevermind
compile_block_body(); compile_block_body();
ctx()->emit(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE); ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE);
ctx()->exit_block(); ctx()->exit_block();
// optional else clause // optional else clause
if (match(TK("else"))) { if (match(TK("else"))) {
@ -673,25 +673,25 @@ __EAT_DOTS_END:
ctx()->enter_block(TRY_EXCEPT); ctx()->enter_block(TRY_EXCEPT);
compile_block_body(); compile_block_body();
std::vector<int> patches = { std::vector<int> patches = {
ctx()->emit(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE) ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE)
}; };
ctx()->exit_block(); ctx()->exit_block();
do { do {
consume(TK("except")); consume(TK("except"));
if(match(TK("@id"))){ if(match(TK("@id"))){
ctx()->emit(OP_EXCEPTION_MATCH, StrName(prev().sv()).index, prev().line); ctx()->emit_(OP_EXCEPTION_MATCH, StrName(prev().sv()).index, prev().line);
}else{ }else{
ctx()->emit(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_LOAD_TRUE, BC_NOARG, BC_KEEPLINE);
} }
int patch = ctx()->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE); int patch = ctx()->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
// pop the exception on match // pop the exception on match
ctx()->emit(OP_POP_EXCEPTION, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_POP_EXCEPTION, BC_NOARG, BC_KEEPLINE);
compile_block_body(); compile_block_body();
patches.push_back(ctx()->emit(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE)); patches.push_back(ctx()->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, BC_KEEPLINE));
ctx()->patch_jump(patch); ctx()->patch_jump(patch);
}while(curr().type == TK("except")); }while(curr().type == TK("except"));
// no match, re-raise // no match, re-raise
ctx()->emit(OP_RE_RAISE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_RE_RAISE, BC_NOARG, BC_KEEPLINE);
for (int patch : patches) ctx()->patch_jump(patch); for (int patch : patches) ctx()->patch_jump(patch);
} }
@ -720,7 +720,7 @@ __EAT_DOTS_END:
EXPR_TUPLE(); EXPR_TUPLE();
e->rhs = ctx()->s_expr.popx(); e->rhs = ctx()->s_expr.popx();
if(e->is_starred()) SyntaxError(); if(e->is_starred()) SyntaxError();
e->emit(ctx()); e->emit_(ctx());
bool ok = lhs_p->emit_store(ctx()); bool ok = lhs_p->emit_store(ctx());
if(!ok) SyntaxError(); if(!ok) SyntaxError();
} return true; } return true;
@ -739,8 +739,8 @@ __EAT_DOTS_END:
} }
// stack size is n+1 // stack size is n+1
Expr_ val = ctx()->s_expr.popx(); Expr_ val = ctx()->s_expr.popx();
val->emit(ctx()); val->emit_(ctx());
for(int j=1; j<n; j++) ctx()->emit(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE); for(int j=1; j<n; j++) ctx()->emit_(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
for(int j=0; j<n; j++){ for(int j=0; j<n; j++){
auto e = ctx()->s_expr.popx(); auto e = ctx()->s_expr.popx();
if(e->is_starred()) SyntaxError(); if(e->is_starred()) SyntaxError();
@ -759,12 +759,12 @@ __EAT_DOTS_END:
switch(prev().type){ switch(prev().type){
case TK("break"): case TK("break"):
if (curr_loop_block < 0) SyntaxError("'break' outside loop"); if (curr_loop_block < 0) SyntaxError("'break' outside loop");
ctx()->emit(OP_LOOP_BREAK, curr_loop_block, kw_line); ctx()->emit_(OP_LOOP_BREAK, curr_loop_block, kw_line);
consume_end_stmt(); consume_end_stmt();
break; break;
case TK("continue"): case TK("continue"):
if (curr_loop_block < 0) SyntaxError("'continue' not properly in loop"); if (curr_loop_block < 0) SyntaxError("'continue' not properly in loop");
ctx()->emit(OP_LOOP_CONTINUE, curr_loop_block, kw_line); ctx()->emit_(OP_LOOP_CONTINUE, curr_loop_block, kw_line);
consume_end_stmt(); consume_end_stmt();
break; break;
case TK("yield"): case TK("yield"):
@ -772,7 +772,7 @@ __EAT_DOTS_END:
EXPR_TUPLE(false); EXPR_TUPLE(false);
// if yield present, mark the function as generator // if yield present, mark the function as generator
ctx()->co->is_generator = true; ctx()->co->is_generator = true;
ctx()->emit(OP_YIELD_VALUE, BC_NOARG, kw_line); ctx()->emit_(OP_YIELD_VALUE, BC_NOARG, kw_line);
consume_end_stmt(); consume_end_stmt();
break; break;
case TK("yield from"): case TK("yield from"):
@ -780,23 +780,23 @@ __EAT_DOTS_END:
EXPR_TUPLE(false); EXPR_TUPLE(false);
// if yield from present, mark the function as generator // if yield from present, mark the function as generator
ctx()->co->is_generator = true; ctx()->co->is_generator = true;
ctx()->emit(OP_GET_ITER, BC_NOARG, kw_line); ctx()->emit_(OP_GET_ITER, BC_NOARG, kw_line);
ctx()->enter_block(FOR_LOOP); ctx()->enter_block(FOR_LOOP);
ctx()->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_YIELD_VALUE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_YIELD_VALUE, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE); ctx()->emit_(OP_LOOP_CONTINUE, ctx()->get_loop(), BC_KEEPLINE);
ctx()->exit_block(); ctx()->exit_block();
consume_end_stmt(); consume_end_stmt();
break; break;
case TK("return"): case TK("return"):
if (contexts.size() <= 1) SyntaxError("'return' outside function"); if (contexts.size() <= 1) SyntaxError("'return' outside function");
if(match_end_stmt()){ if(match_end_stmt()){
ctx()->emit(OP_LOAD_NONE, BC_NOARG, kw_line); ctx()->emit_(OP_LOAD_NONE, BC_NOARG, kw_line);
}else{ }else{
EXPR_TUPLE(false); EXPR_TUPLE(false);
consume_end_stmt(); consume_end_stmt();
} }
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, kw_line); ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, kw_line);
break; break;
/*************************************************/ /*************************************************/
case TK("if"): compile_if_stmt(); break; case TK("if"): compile_if_stmt(); break;
@ -817,10 +817,10 @@ __EAT_DOTS_END:
if(is_global) scope = NAME_GLOBAL; if(is_global) scope = NAME_GLOBAL;
switch(scope){ switch(scope){
case NAME_LOCAL: case NAME_LOCAL:
ctx()->emit(OP_INC_FAST, ctx()->add_varname(name), prev().line); ctx()->emit_(OP_INC_FAST, ctx()->add_varname(name), prev().line);
break; break;
case NAME_GLOBAL: case NAME_GLOBAL:
ctx()->emit(OP_INC_GLOBAL, name.index, prev().line); ctx()->emit_(OP_INC_GLOBAL, name.index, prev().line);
break; break;
default: SyntaxError(); break; default: SyntaxError(); break;
} }
@ -832,10 +832,10 @@ __EAT_DOTS_END:
StrName name(prev().sv()); StrName name(prev().sv());
switch(name_scope()){ switch(name_scope()){
case NAME_LOCAL: case NAME_LOCAL:
ctx()->emit(OP_DEC_FAST, ctx()->add_varname(name), prev().line); ctx()->emit_(OP_DEC_FAST, ctx()->add_varname(name), prev().line);
break; break;
case NAME_GLOBAL: case NAME_GLOBAL:
ctx()->emit(OP_DEC_GLOBAL, name.index, prev().line); ctx()->emit_(OP_DEC_GLOBAL, name.index, prev().line);
break; break;
default: SyntaxError(); break; default: SyntaxError(); break;
} }
@ -844,13 +844,13 @@ __EAT_DOTS_END:
} }
case TK("assert"):{ case TK("assert"):{
EXPR(false); // condition EXPR(false); // condition
int index = ctx()->emit(OP_POP_JUMP_IF_TRUE, BC_NOARG, kw_line); int index = ctx()->emit_(OP_POP_JUMP_IF_TRUE, BC_NOARG, kw_line);
int has_msg = 0; int has_msg = 0;
if(match(TK(","))){ if(match(TK(","))){
EXPR(false); // message EXPR(false); // message
has_msg = 1; has_msg = 1;
} }
ctx()->emit(OP_RAISE_ASSERT, has_msg, kw_line); ctx()->emit_(OP_RAISE_ASSERT, has_msg, kw_line);
ctx()->patch_jump(index); ctx()->patch_jump(index);
consume_end_stmt(); consume_end_stmt();
break; break;
@ -868,9 +868,9 @@ __EAT_DOTS_END:
if(match(TK("(")) && !match(TK(")"))){ if(match(TK("(")) && !match(TK(")"))){
EXPR(false); consume(TK(")")); EXPR(false); consume(TK(")"));
}else{ }else{
ctx()->emit(OP_LOAD_NONE, BC_NOARG, kw_line); ctx()->emit_(OP_LOAD_NONE, BC_NOARG, kw_line);
} }
ctx()->emit(OP_RAISE, dummy_t, kw_line); ctx()->emit_(OP_RAISE, dummy_t, kw_line);
consume_end_stmt(); consume_end_stmt();
} break; } break;
case TK("del"): { case TK("del"): {
@ -887,11 +887,11 @@ __EAT_DOTS_END:
Expr_ e = make_expr<NameExpr>(prev().str(), name_scope()); Expr_ e = make_expr<NameExpr>(prev().str(), name_scope());
bool ok = e->emit_store(ctx()); bool ok = e->emit_store(ctx());
if(!ok) SyntaxError(); if(!ok) SyntaxError();
e->emit(ctx()); e->emit_(ctx());
ctx()->emit(OP_WITH_ENTER, BC_NOARG, prev().line); ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line);
compile_block_body(); compile_block_body();
e->emit(ctx()); e->emit_(ctx());
ctx()->emit(OP_WITH_EXIT, BC_NOARG, prev().line); ctx()->emit_(OP_WITH_EXIT, BC_NOARG, prev().line);
} break; } break;
/*************************************************/ /*************************************************/
case TK("=="): { case TK("=="): {
@ -905,7 +905,7 @@ __EAT_DOTS_END:
case TK("->"): case TK("->"):
consume(TK("@id")); consume(TK("@id"));
if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE"); if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
ctx()->emit(OP_GOTO, StrName(prev().sv()).index, prev().line); ctx()->emit_(OP_GOTO, StrName(prev().sv()).index, prev().line);
consume_end_stmt(); consume_end_stmt();
break; break;
/*************************************************/ /*************************************************/
@ -929,9 +929,9 @@ __EAT_DOTS_END:
if(!is_typed_name){ if(!is_typed_name){
ctx()->emit_expr(); ctx()->emit_expr();
if((mode()==CELL_MODE || mode()==REPL_MODE) && name_scope()==NAME_GLOBAL){ if((mode()==CELL_MODE || mode()==REPL_MODE) && name_scope()==NAME_GLOBAL){
ctx()->emit(OP_PRINT_EXPR, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_PRINT_EXPR, BC_NOARG, BC_KEEPLINE);
}else{ }else{
ctx()->emit(OP_POP_TOP, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
} }
}else{ }else{
PK_ASSERT(ctx()->s_expr.size() == 1) PK_ASSERT(ctx()->s_expr.size() == 1)
@ -960,15 +960,15 @@ __EAT_DOTS_END:
consume(TK(")")); consume(TK(")"));
} }
if(base == nullptr){ if(base == nullptr){
ctx()->emit(OP_LOAD_NONE, BC_NOARG, prev().line); ctx()->emit_(OP_LOAD_NONE, BC_NOARG, prev().line);
}else { }else {
base->emit(ctx()); base->emit_(ctx());
} }
ctx()->emit(OP_BEGIN_CLASS, namei, BC_KEEPLINE); ctx()->emit_(OP_BEGIN_CLASS, namei, BC_KEEPLINE);
ctx()->is_compiling_class = true; ctx()->is_compiling_class = true;
compile_block_body(); compile_block_body();
ctx()->is_compiling_class = false; ctx()->is_compiling_class = false;
ctx()->emit(OP_END_CLASS, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_END_CLASS, BC_NOARG, BC_KEEPLINE);
} }
void Compiler::_compile_f_args(FuncDecl_ decl, bool enable_type_hints){ void Compiler::_compile_f_args(FuncDecl_ decl, bool enable_type_hints){
@ -1062,22 +1062,22 @@ __EAT_DOTS_END:
if(docstring != nullptr){ if(docstring != nullptr){
decl->docstring = PK_OBJ_GET(Str, docstring); decl->docstring = PK_OBJ_GET(Str, docstring);
} }
ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line); ctx()->emit_(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
// add decorators // add decorators
for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){ for(auto it=decorators.rbegin(); it!=decorators.rend(); ++it){
(*it)->emit(ctx()); (*it)->emit_(ctx());
ctx()->emit(OP_ROT_TWO, BC_NOARG, (*it)->line); ctx()->emit_(OP_ROT_TWO, BC_NOARG, (*it)->line);
ctx()->emit(OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_ROT_TWO, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_ROT_TWO, BC_NOARG, BC_KEEPLINE);
ctx()->emit(OP_CALL, 1, (*it)->line); ctx()->emit_(OP_CALL, 1, (*it)->line);
} }
if(!ctx()->is_compiling_class){ if(!ctx()->is_compiling_class){
auto e = make_expr<NameExpr>(decl_name, name_scope()); auto e = make_expr<NameExpr>(decl_name, name_scope());
e->emit_store(ctx()); e->emit_store(ctx());
}else{ }else{
int index = StrName(decl_name).index; int index = StrName(decl_name).index;
ctx()->emit(OP_STORE_CLASS_ATTR, index, prev().line); ctx()->emit_(OP_STORE_CLASS_ATTR, index, prev().line);
} }
} }
@ -1143,7 +1143,7 @@ __EAT_DOTS_END:
if(mode()==EVAL_MODE) { if(mode()==EVAL_MODE) {
EXPR_TUPLE(false); EXPR_TUPLE(false);
consume(TK("@eof")); consume(TK("@eof"));
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
pop_context(); pop_context();
return code; return code;
}else if(mode()==JSON_MODE){ }else if(mode()==JSON_MODE){
@ -1151,8 +1151,8 @@ __EAT_DOTS_END:
Expr_ e = ctx()->s_expr.popx(); Expr_ e = ctx()->s_expr.popx();
if(!e->is_json_object()) SyntaxError("expect a JSON object, literal or array"); if(!e->is_json_object()) SyntaxError("expect a JSON object, literal or array");
consume(TK("@eof")); consume(TK("@eof"));
e->emit(ctx()); e->emit_(ctx());
ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
pop_context(); pop_context();
return code; return code;
} }

View File

@ -30,7 +30,7 @@ namespace pkpy{
if(curr_type == FOR_LOOP){ if(curr_type == FOR_LOOP){
// add a no op here to make block check work // add a no op here to make block check work
emit(OP_NO_OP, BC_NOARG, BC_KEEPLINE); emit_(OP_NO_OP, BC_NOARG, BC_KEEPLINE);
} }
} }
@ -40,7 +40,7 @@ namespace pkpy{
throw std::runtime_error("s_expr.size() != 1\n" + _log_s_expr()); throw std::runtime_error("s_expr.size() != 1\n" + _log_s_expr());
} }
Expr_ expr = s_expr.popx(); Expr_ expr = s_expr.popx();
expr->emit(this); expr->emit_(this);
} }
std::string CodeEmitContext::_log_s_expr(){ std::string CodeEmitContext::_log_s_expr(){
@ -49,7 +49,7 @@ namespace pkpy{
return ss.str(); return ss.str();
} }
int CodeEmitContext::emit(Opcode opcode, uint16_t arg, int line) { int CodeEmitContext::emit_(Opcode opcode, uint16_t arg, int line) {
co->codes.push_back(Bytecode{(uint8_t)opcode, arg}); co->codes.push_back(Bytecode{(uint8_t)opcode, arg});
co->iblocks.push_back(curr_block_i); co->iblocks.push_back(curr_block_i);
co->lines.push_back(line); co->lines.push_back(line);
@ -108,41 +108,41 @@ namespace pkpy{
void CodeEmitContext::emit_store_name(NameScope scope, StrName name, int line){ void CodeEmitContext::emit_store_name(NameScope scope, StrName name, int line){
switch(scope){ switch(scope){
case NAME_LOCAL: case NAME_LOCAL:
emit(OP_STORE_FAST, add_varname(name), line); emit_(OP_STORE_FAST, add_varname(name), line);
break; break;
case NAME_GLOBAL: case NAME_GLOBAL:
emit(OP_STORE_GLOBAL, StrName(name).index, line); emit_(OP_STORE_GLOBAL, StrName(name).index, line);
break; break;
case NAME_GLOBAL_UNKNOWN: case NAME_GLOBAL_UNKNOWN:
emit(OP_STORE_NAME, StrName(name).index, line); emit_(OP_STORE_NAME, StrName(name).index, line);
break; break;
default: FATAL_ERROR(); break; default: FATAL_ERROR(); break;
} }
} }
void NameExpr::emit(CodeEmitContext* ctx) { void NameExpr::emit_(CodeEmitContext* ctx) {
int index = ctx->co->varnames_inv.try_get(name); int index = ctx->co->varnames_inv.try_get(name);
if(scope == NAME_LOCAL && index >= 0){ if(scope == NAME_LOCAL && index >= 0){
ctx->emit(OP_LOAD_FAST, index, line); ctx->emit_(OP_LOAD_FAST, index, line);
}else{ }else{
Opcode op = ctx->level <= 1 ? OP_LOAD_GLOBAL : OP_LOAD_NONLOCAL; Opcode op = ctx->level <= 1 ? OP_LOAD_GLOBAL : OP_LOAD_NONLOCAL;
// we cannot determine the scope when calling exec()/eval() // we cannot determine the scope when calling exec()/eval()
if(scope == NAME_GLOBAL_UNKNOWN) op = OP_LOAD_NAME; if(scope == NAME_GLOBAL_UNKNOWN) op = OP_LOAD_NAME;
ctx->emit(op, StrName(name).index, line); ctx->emit_(op, StrName(name).index, line);
} }
} }
bool NameExpr::emit_del(CodeEmitContext* ctx) { bool NameExpr::emit_del(CodeEmitContext* ctx) {
switch(scope){ switch(scope){
case NAME_LOCAL: case NAME_LOCAL:
ctx->emit(OP_DELETE_FAST, ctx->add_varname(name), line); ctx->emit_(OP_DELETE_FAST, ctx->add_varname(name), line);
break; break;
case NAME_GLOBAL: case NAME_GLOBAL:
ctx->emit(OP_DELETE_GLOBAL, StrName(name).index, line); ctx->emit_(OP_DELETE_GLOBAL, StrName(name).index, line);
break; break;
case NAME_GLOBAL_UNKNOWN: case NAME_GLOBAL_UNKNOWN:
ctx->emit(OP_DELETE_NAME, StrName(name).index, line); ctx->emit_(OP_DELETE_NAME, StrName(name).index, line);
break; break;
default: FATAL_ERROR(); break; default: FATAL_ERROR(); break;
} }
@ -151,21 +151,21 @@ namespace pkpy{
bool NameExpr::emit_store(CodeEmitContext* ctx) { bool NameExpr::emit_store(CodeEmitContext* ctx) {
if(ctx->is_compiling_class){ if(ctx->is_compiling_class){
ctx->emit(OP_STORE_CLASS_ATTR, name.index, line); ctx->emit_(OP_STORE_CLASS_ATTR, name.index, line);
return true; return true;
} }
ctx->emit_store_name(scope, name, line); ctx->emit_store_name(scope, name, line);
return true; return true;
} }
void InvertExpr::emit(CodeEmitContext* ctx) { void InvertExpr::emit_(CodeEmitContext* ctx) {
child->emit(ctx); child->emit_(ctx);
ctx->emit(OP_UNARY_INVERT, BC_NOARG, line); ctx->emit_(OP_UNARY_INVERT, BC_NOARG, line);
} }
void StarredExpr::emit(CodeEmitContext* ctx) { void StarredExpr::emit_(CodeEmitContext* ctx) {
child->emit(ctx); child->emit_(ctx);
ctx->emit(OP_UNARY_STAR, level, line); ctx->emit_(OP_UNARY_STAR, level, line);
} }
bool StarredExpr::emit_store(CodeEmitContext* ctx) { bool StarredExpr::emit_store(CodeEmitContext* ctx) {
@ -174,54 +174,54 @@ namespace pkpy{
return child->emit_store(ctx); return child->emit_store(ctx);
} }
void NotExpr::emit(CodeEmitContext* ctx) { void NotExpr::emit_(CodeEmitContext* ctx) {
child->emit(ctx); child->emit_(ctx);
ctx->emit(OP_UNARY_NOT, BC_NOARG, line); ctx->emit_(OP_UNARY_NOT, BC_NOARG, line);
} }
void AndExpr::emit(CodeEmitContext* ctx) { void AndExpr::emit_(CodeEmitContext* ctx) {
lhs->emit(ctx); lhs->emit_(ctx);
int patch = ctx->emit(OP_JUMP_IF_FALSE_OR_POP, BC_NOARG, line); int patch = ctx->emit_(OP_JUMP_IF_FALSE_OR_POP, BC_NOARG, line);
rhs->emit(ctx); rhs->emit_(ctx);
ctx->patch_jump(patch); ctx->patch_jump(patch);
} }
void OrExpr::emit(CodeEmitContext* ctx) { void OrExpr::emit_(CodeEmitContext* ctx) {
lhs->emit(ctx); lhs->emit_(ctx);
int patch = ctx->emit(OP_JUMP_IF_TRUE_OR_POP, BC_NOARG, line); int patch = ctx->emit_(OP_JUMP_IF_TRUE_OR_POP, BC_NOARG, line);
rhs->emit(ctx); rhs->emit_(ctx);
ctx->patch_jump(patch); ctx->patch_jump(patch);
} }
void Literal0Expr::emit(CodeEmitContext* ctx){ void Literal0Expr::emit_(CodeEmitContext* ctx){
switch (token) { switch (token) {
case TK("None"): ctx->emit(OP_LOAD_NONE, BC_NOARG, line); break; case TK("None"): ctx->emit_(OP_LOAD_NONE, BC_NOARG, line); break;
case TK("True"): ctx->emit(OP_LOAD_TRUE, BC_NOARG, line); break; case TK("True"): ctx->emit_(OP_LOAD_TRUE, BC_NOARG, line); break;
case TK("False"): ctx->emit(OP_LOAD_FALSE, BC_NOARG, line); break; case TK("False"): ctx->emit_(OP_LOAD_FALSE, BC_NOARG, line); break;
case TK("..."): ctx->emit(OP_LOAD_ELLIPSIS, BC_NOARG, line); break; case TK("..."): ctx->emit_(OP_LOAD_ELLIPSIS, BC_NOARG, line); break;
default: FATAL_ERROR(); default: FATAL_ERROR();
} }
} }
void LongExpr::emit(CodeEmitContext* ctx) { void LongExpr::emit_(CodeEmitContext* ctx) {
VM* vm = ctx->vm; VM* vm = ctx->vm;
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(s)), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(s)), line);
ctx->emit(OP_BUILD_LONG, BC_NOARG, line); ctx->emit_(OP_BUILD_LONG, BC_NOARG, line);
} }
void BytesExpr::emit(CodeEmitContext* ctx) { void BytesExpr::emit_(CodeEmitContext* ctx) {
VM* vm = ctx->vm; VM* vm = ctx->vm;
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(s)), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(s)), line);
ctx->emit(OP_BUILD_BYTES, BC_NOARG, line); ctx->emit_(OP_BUILD_BYTES, BC_NOARG, line);
} }
void LiteralExpr::emit(CodeEmitContext* ctx) { void LiteralExpr::emit_(CodeEmitContext* ctx) {
VM* vm = ctx->vm; VM* vm = ctx->vm;
PyObject* obj = nullptr; PyObject* obj = nullptr;
if(std::holds_alternative<i64>(value)){ if(std::holds_alternative<i64>(value)){
i64 _val = std::get<i64>(value); i64 _val = std::get<i64>(value);
if(_val >= INT16_MIN && _val <= INT16_MAX){ if(_val >= INT16_MIN && _val <= INT16_MAX){
ctx->emit(OP_LOAD_INTEGER, (uint16_t)_val, line); ctx->emit_(OP_LOAD_INTEGER, (uint16_t)_val, line);
return; return;
} }
obj = VAR(_val); obj = VAR(_val);
@ -233,10 +233,10 @@ namespace pkpy{
obj = VAR(std::get<Str>(value)); obj = VAR(std::get<Str>(value));
} }
if(obj == nullptr) FATAL_ERROR(); if(obj == nullptr) FATAL_ERROR();
ctx->emit(OP_LOAD_CONST, ctx->add_const(obj), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(obj), line);
} }
void NegatedExpr::emit(CodeEmitContext* ctx){ void NegatedExpr::emit_(CodeEmitContext* ctx){
VM* vm = ctx->vm; VM* vm = ctx->vm;
// if child is a int of float, do constant folding // if child is a int of float, do constant folding
if(child->is_literal()){ if(child->is_literal()){
@ -244,53 +244,53 @@ namespace pkpy{
if(std::holds_alternative<i64>(lit->value)){ if(std::holds_alternative<i64>(lit->value)){
i64 _val = -std::get<i64>(lit->value); i64 _val = -std::get<i64>(lit->value);
if(_val >= INT16_MIN && _val <= INT16_MAX){ if(_val >= INT16_MIN && _val <= INT16_MAX){
ctx->emit(OP_LOAD_INTEGER, (uint16_t)_val, line); ctx->emit_(OP_LOAD_INTEGER, (uint16_t)_val, line);
}else{ }else{
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(_val)), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(_val)), line);
} }
return; return;
} }
if(std::holds_alternative<f64>(lit->value)){ if(std::holds_alternative<f64>(lit->value)){
PyObject* obj = VAR(-std::get<f64>(lit->value)); PyObject* obj = VAR(-std::get<f64>(lit->value));
ctx->emit(OP_LOAD_CONST, ctx->add_const(obj), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(obj), line);
return; return;
} }
} }
child->emit(ctx); child->emit_(ctx);
ctx->emit(OP_UNARY_NEGATIVE, BC_NOARG, line); ctx->emit_(OP_UNARY_NEGATIVE, BC_NOARG, line);
} }
void SliceExpr::emit(CodeEmitContext* ctx){ void SliceExpr::emit_(CodeEmitContext* ctx){
if(start){ if(start){
start->emit(ctx); start->emit_(ctx);
}else{ }else{
ctx->emit(OP_LOAD_NONE, BC_NOARG, line); ctx->emit_(OP_LOAD_NONE, BC_NOARG, line);
} }
if(stop){ if(stop){
stop->emit(ctx); stop->emit_(ctx);
}else{ }else{
ctx->emit(OP_LOAD_NONE, BC_NOARG, line); ctx->emit_(OP_LOAD_NONE, BC_NOARG, line);
} }
if(step){ if(step){
step->emit(ctx); step->emit_(ctx);
}else{ }else{
ctx->emit(OP_LOAD_NONE, BC_NOARG, line); ctx->emit_(OP_LOAD_NONE, BC_NOARG, line);
} }
ctx->emit(OP_BUILD_SLICE, BC_NOARG, line); ctx->emit_(OP_BUILD_SLICE, BC_NOARG, line);
} }
void DictItemExpr::emit(CodeEmitContext* ctx) { void DictItemExpr::emit_(CodeEmitContext* ctx) {
if(is_starred()){ if(is_starred()){
PK_ASSERT(key == nullptr); PK_ASSERT(key == nullptr);
value->emit(ctx); value->emit_(ctx);
}else{ }else{
value->emit(ctx); value->emit_(ctx);
key->emit(ctx); // reverse order key->emit_(ctx); // reverse order
ctx->emit(OP_BUILD_TUPLE, 2, line); ctx->emit_(OP_BUILD_TUPLE, 2, line);
} }
} }
@ -311,7 +311,7 @@ namespace pkpy{
prev.op = OP_NO_OP; prev.op = OP_NO_OP;
prev.arg = BC_NOARG; prev.arg = BC_NOARG;
}else{ }else{
ctx->emit(OP_UNPACK_SEQUENCE, items.size(), line); ctx->emit_(OP_UNPACK_SEQUENCE, items.size(), line);
} }
}else{ }else{
// starred assignment target must be in a tuple // starred assignment target must be in a tuple
@ -320,7 +320,7 @@ namespace pkpy{
if(starred_i != items.size()-1) return false; if(starred_i != items.size()-1) return false;
// a,*b = [1,2,3] // a,*b = [1,2,3]
// stack is [1,2,3] -> [1,[2,3]] // stack is [1,2,3] -> [1,[2,3]]
ctx->emit(OP_UNPACK_EX, items.size()-1, line); ctx->emit_(OP_UNPACK_EX, items.size()-1, line);
} }
// do reverse emit // do reverse emit
for(int i=items.size()-1; i>=0; i--){ for(int i=items.size()-1; i>=0; i--){
@ -338,26 +338,26 @@ namespace pkpy{
return true; return true;
} }
void CompExpr::emit(CodeEmitContext* ctx){ void CompExpr::emit_(CodeEmitContext* ctx){
ctx->emit(op0(), 0, line); ctx->emit_(op0(), 0, line);
iter->emit(ctx); iter->emit_(ctx);
ctx->emit(OP_GET_ITER, BC_NOARG, BC_KEEPLINE); ctx->emit_(OP_GET_ITER, BC_NOARG, BC_KEEPLINE);
ctx->enter_block(FOR_LOOP); ctx->enter_block(FOR_LOOP);
ctx->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE); ctx->emit_(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE);
bool ok = vars->emit_store(ctx); bool ok = vars->emit_store(ctx);
// this error occurs in `vars` instead of this line, but...nevermind // this error occurs in `vars` instead of this line, but...nevermind
PK_ASSERT(ok); // TODO: raise a SyntaxError instead PK_ASSERT(ok); // TODO: raise a SyntaxError instead
if(cond){ if(cond){
cond->emit(ctx); cond->emit_(ctx);
int patch = ctx->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE); int patch = ctx->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE);
expr->emit(ctx); expr->emit_(ctx);
ctx->emit(op1(), BC_NOARG, BC_KEEPLINE); ctx->emit_(op1(), BC_NOARG, BC_KEEPLINE);
ctx->patch_jump(patch); ctx->patch_jump(patch);
}else{ }else{
expr->emit(ctx); expr->emit_(ctx);
ctx->emit(op1(), BC_NOARG, BC_KEEPLINE); ctx->emit_(op1(), BC_NOARG, BC_KEEPLINE);
} }
ctx->emit(OP_LOOP_CONTINUE, ctx->get_loop(), BC_KEEPLINE); ctx->emit_(OP_LOOP_CONTINUE, ctx->get_loop(), BC_KEEPLINE);
ctx->exit_block(); ctx->exit_block();
} }
@ -376,24 +376,24 @@ namespace pkpy{
if(std::regex_match(expr.str(), pattern)){ if(std::regex_match(expr.str(), pattern)){
int dot = expr.index("."); int dot = expr.index(".");
if(dot < 0){ if(dot < 0){
ctx->emit(OP_LOAD_NAME, StrName(expr.sv()).index, line); ctx->emit_(OP_LOAD_NAME, StrName(expr.sv()).index, line);
}else{ }else{
StrName name(expr.substr(0, dot).sv()); StrName name(expr.substr(0, dot).sv());
StrName attr(expr.substr(dot+1).sv()); StrName attr(expr.substr(dot+1).sv());
ctx->emit(OP_LOAD_NAME, name.index, line); ctx->emit_(OP_LOAD_NAME, name.index, line);
ctx->emit(OP_LOAD_ATTR, attr.index, line); ctx->emit_(OP_LOAD_ATTR, attr.index, line);
} }
}else{ }else{
int index = ctx->add_const(py_var(ctx->vm, expr)); int index = ctx->add_const(py_var(ctx->vm, expr));
ctx->emit(OP_LOAD_CONST, index, line); ctx->emit_(OP_LOAD_CONST, index, line);
ctx->emit(OP_EVAL, BC_NOARG, line); ctx->emit_(OP_EVAL, BC_NOARG, line);
} }
if(repr){ if(repr){
ctx->emit(OP_REPR, BC_NOARG, line); ctx->emit_(OP_REPR, BC_NOARG, line);
} }
} }
void FStringExpr::emit(CodeEmitContext* ctx){ void FStringExpr::emit_(CodeEmitContext* ctx){
VM* vm = ctx->vm; VM* vm = ctx->vm;
PK_LOCAL_STATIC const std::regex pattern(R"(\{(.*?)\})"); PK_LOCAL_STATIC const std::regex pattern(R"(\{(.*?)\})");
std::cregex_iterator begin(src.begin(), src.end(), pattern); std::cregex_iterator begin(src.begin(), src.end(), pattern);
@ -404,7 +404,7 @@ namespace pkpy{
std::cmatch m = *it; std::cmatch m = *it;
if (i < m.position()) { if (i < m.position()) {
Str literal = src.substr(i, m.position() - i); Str literal = src.substr(i, m.position() - i);
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
size++; size++;
} }
Str expr = m[1].str(); Str expr = m[1].str();
@ -412,7 +412,7 @@ namespace pkpy{
if(conon >= 0){ if(conon >= 0){
_load_simple_expr(ctx, expr.substr(0, conon)); _load_simple_expr(ctx, expr.substr(0, conon));
Str spec = expr.substr(conon+1); Str spec = expr.substr(conon+1);
ctx->emit(OP_FORMAT_STRING, ctx->add_const(VAR(spec)), line); ctx->emit_(OP_FORMAT_STRING, ctx->add_const(VAR(spec)), line);
}else{ }else{
_load_simple_expr(ctx, expr); _load_simple_expr(ctx, expr);
} }
@ -421,60 +421,60 @@ namespace pkpy{
} }
if (i < src.length()) { if (i < src.length()) {
Str literal = src.substr(i, src.length() - i); Str literal = src.substr(i, src.length() - i);
ctx->emit(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line); ctx->emit_(OP_LOAD_CONST, ctx->add_const(VAR(literal)), line);
size++; size++;
} }
ctx->emit(OP_BUILD_STRING, size, line); ctx->emit_(OP_BUILD_STRING, size, line);
} }
void SubscrExpr::emit(CodeEmitContext* ctx){ void SubscrExpr::emit_(CodeEmitContext* ctx){
a->emit(ctx); a->emit_(ctx);
b->emit(ctx); b->emit_(ctx);
ctx->emit(OP_LOAD_SUBSCR, BC_NOARG, line); ctx->emit_(OP_LOAD_SUBSCR, BC_NOARG, line);
} }
bool SubscrExpr::emit_del(CodeEmitContext* ctx){ bool SubscrExpr::emit_del(CodeEmitContext* ctx){
a->emit(ctx); a->emit_(ctx);
b->emit(ctx); b->emit_(ctx);
ctx->emit(OP_DELETE_SUBSCR, BC_NOARG, line); ctx->emit_(OP_DELETE_SUBSCR, BC_NOARG, line);
return true; return true;
} }
bool SubscrExpr::emit_store(CodeEmitContext* ctx){ bool SubscrExpr::emit_store(CodeEmitContext* ctx){
a->emit(ctx); a->emit_(ctx);
b->emit(ctx); b->emit_(ctx);
ctx->emit(OP_STORE_SUBSCR, BC_NOARG, line); ctx->emit_(OP_STORE_SUBSCR, BC_NOARG, line);
return true; return true;
} }
void AttribExpr::emit(CodeEmitContext* ctx){ void AttribExpr::emit_(CodeEmitContext* ctx){
a->emit(ctx); a->emit_(ctx);
int index = StrName(b).index; int index = StrName(b).index;
ctx->emit(OP_LOAD_ATTR, index, line); ctx->emit_(OP_LOAD_ATTR, index, line);
} }
bool AttribExpr::emit_del(CodeEmitContext* ctx) { bool AttribExpr::emit_del(CodeEmitContext* ctx) {
a->emit(ctx); a->emit_(ctx);
int index = StrName(b).index; int index = StrName(b).index;
ctx->emit(OP_DELETE_ATTR, index, line); ctx->emit_(OP_DELETE_ATTR, index, line);
return true; return true;
} }
bool AttribExpr::emit_store(CodeEmitContext* ctx){ bool AttribExpr::emit_store(CodeEmitContext* ctx){
a->emit(ctx); a->emit_(ctx);
int index = StrName(b).index; int index = StrName(b).index;
ctx->emit(OP_STORE_ATTR, index, line); ctx->emit_(OP_STORE_ATTR, index, line);
return true; return true;
} }
void AttribExpr::emit_method(CodeEmitContext* ctx) { void AttribExpr::emit_method(CodeEmitContext* ctx) {
a->emit(ctx); a->emit_(ctx);
int index = StrName(b).index; int index = StrName(b).index;
ctx->emit(OP_LOAD_METHOD, index, line); ctx->emit_(OP_LOAD_METHOD, index, line);
} }
void CallExpr::emit(CodeEmitContext* ctx) { void CallExpr::emit_(CodeEmitContext* ctx) {
bool vargs = false; bool vargs = false;
bool vkwargs = false; bool vkwargs = false;
for(auto& arg: args) if(arg->is_starred()) vargs = true; for(auto& arg: args) if(arg->is_starred()) vargs = true;
@ -485,43 +485,43 @@ namespace pkpy{
auto p = static_cast<AttribExpr*>(callable.get()); auto p = static_cast<AttribExpr*>(callable.get());
p->emit_method(ctx); // OP_LOAD_METHOD p->emit_method(ctx); // OP_LOAD_METHOD
}else{ }else{
callable->emit(ctx); callable->emit_(ctx);
ctx->emit(OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE); ctx->emit_(OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE);
} }
if(vargs || vkwargs){ if(vargs || vkwargs){
for(auto& item: args) item->emit(ctx); for(auto& item: args) item->emit_(ctx);
ctx->emit(OP_BUILD_TUPLE_UNPACK, (uint16_t)args.size(), line); ctx->emit_(OP_BUILD_TUPLE_UNPACK, (uint16_t)args.size(), line);
if(!kwargs.empty()){ if(!kwargs.empty()){
for(auto& item: kwargs){ for(auto& item: kwargs){
if(item.second->is_starred()){ if(item.second->is_starred()){
if(item.second->star_level() != 2) FATAL_ERROR(); if(item.second->star_level() != 2) FATAL_ERROR();
item.second->emit(ctx); item.second->emit_(ctx);
}else{ }else{
// k=v // k=v
int index = ctx->add_const(py_var(ctx->vm, item.first)); int index = ctx->add_const(py_var(ctx->vm, item.first));
ctx->emit(OP_LOAD_CONST, index, line); ctx->emit_(OP_LOAD_CONST, index, line);
item.second->emit(ctx); item.second->emit_(ctx);
ctx->emit(OP_BUILD_TUPLE, 2, line); ctx->emit_(OP_BUILD_TUPLE, 2, line);
} }
} }
ctx->emit(OP_BUILD_DICT_UNPACK, (int)kwargs.size(), line); ctx->emit_(OP_BUILD_DICT_UNPACK, (int)kwargs.size(), line);
ctx->emit(OP_CALL_TP, 1, line); ctx->emit_(OP_CALL_TP, 1, line);
}else{ }else{
ctx->emit(OP_CALL_TP, 0, line); ctx->emit_(OP_CALL_TP, 0, line);
} }
}else{ }else{
// vectorcall protocal // vectorcall protocal
for(auto& item: args) item->emit(ctx); for(auto& item: args) item->emit_(ctx);
for(auto& item: kwargs){ for(auto& item: kwargs){
uint16_t index = StrName(item.first.sv()).index; uint16_t index = StrName(item.first.sv()).index;
ctx->emit(OP_LOAD_INTEGER, index, line); ctx->emit_(OP_LOAD_INTEGER, index, line);
item.second->emit(ctx); item.second->emit_(ctx);
} }
int KWARGC = kwargs.size(); int KWARGC = kwargs.size();
int ARGC = args.size(); int ARGC = args.size();
ctx->emit(OP_CALL, (KWARGC<<8)|ARGC, line); ctx->emit_(OP_CALL, (KWARGC<<8)|ARGC, line);
} }
} }
@ -538,26 +538,26 @@ namespace pkpy{
if(lhs->is_compare()){ if(lhs->is_compare()){
static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps); static_cast<BinaryExpr*>(lhs.get())->_emit_compare(ctx, jmps);
}else{ }else{
lhs->emit(ctx); // [a] lhs->emit_(ctx); // [a]
} }
rhs->emit(ctx); // [a, b] rhs->emit_(ctx); // [a, b]
ctx->emit(OP_DUP_TOP, BC_NOARG, line); // [a, b, b] ctx->emit_(OP_DUP_TOP, BC_NOARG, line); // [a, b, b]
ctx->emit(OP_ROT_THREE, BC_NOARG, line); // [b, a, b] ctx->emit_(OP_ROT_THREE, BC_NOARG, line); // [b, a, b]
switch(op){ switch(op){
case TK("<"): ctx->emit(OP_COMPARE_LT, BC_NOARG, line); break; case TK("<"): ctx->emit_(OP_COMPARE_LT, BC_NOARG, line); break;
case TK("<="): ctx->emit(OP_COMPARE_LE, BC_NOARG, line); break; case TK("<="): ctx->emit_(OP_COMPARE_LE, BC_NOARG, line); break;
case TK("=="): ctx->emit(OP_COMPARE_EQ, BC_NOARG, line); break; case TK("=="): ctx->emit_(OP_COMPARE_EQ, BC_NOARG, line); break;
case TK("!="): ctx->emit(OP_COMPARE_NE, BC_NOARG, line); break; case TK("!="): ctx->emit_(OP_COMPARE_NE, BC_NOARG, line); break;
case TK(">"): ctx->emit(OP_COMPARE_GT, BC_NOARG, line); break; case TK(">"): ctx->emit_(OP_COMPARE_GT, BC_NOARG, line); break;
case TK(">="): ctx->emit(OP_COMPARE_GE, BC_NOARG, line); break; case TK(">="): ctx->emit_(OP_COMPARE_GE, BC_NOARG, line); break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
// [b, RES] // [b, RES]
int index = ctx->emit(OP_SHORTCUT_IF_FALSE_OR_POP, BC_NOARG, line); int index = ctx->emit_(OP_SHORTCUT_IF_FALSE_OR_POP, BC_NOARG, line);
jmps.push_back(index); jmps.push_back(index);
} }
void BinaryExpr::emit(CodeEmitContext* ctx) { void BinaryExpr::emit_(CodeEmitContext* ctx) {
std::vector<int> jmps; std::vector<int> jmps;
if(is_compare() && lhs->is_compare()){ if(is_compare() && lhs->is_compare()){
// (a < b) < c // (a < b) < c
@ -565,51 +565,51 @@ namespace pkpy{
// [b, RES] // [b, RES]
}else{ }else{
// (1 + 2) < c // (1 + 2) < c
lhs->emit(ctx); lhs->emit_(ctx);
} }
rhs->emit(ctx); rhs->emit_(ctx);
switch (op) { switch (op) {
case TK("+"): ctx->emit(OP_BINARY_ADD, BC_NOARG, line); break; case TK("+"): ctx->emit_(OP_BINARY_ADD, BC_NOARG, line); break;
case TK("-"): ctx->emit(OP_BINARY_SUB, BC_NOARG, line); break; case TK("-"): ctx->emit_(OP_BINARY_SUB, BC_NOARG, line); break;
case TK("*"): ctx->emit(OP_BINARY_MUL, BC_NOARG, line); break; case TK("*"): ctx->emit_(OP_BINARY_MUL, BC_NOARG, line); break;
case TK("/"): ctx->emit(OP_BINARY_TRUEDIV, BC_NOARG, line); break; case TK("/"): ctx->emit_(OP_BINARY_TRUEDIV, BC_NOARG, line); break;
case TK("//"): ctx->emit(OP_BINARY_FLOORDIV, BC_NOARG, line); break; case TK("//"): ctx->emit_(OP_BINARY_FLOORDIV, BC_NOARG, line); break;
case TK("%"): ctx->emit(OP_BINARY_MOD, BC_NOARG, line); break; case TK("%"): ctx->emit_(OP_BINARY_MOD, BC_NOARG, line); break;
case TK("**"): ctx->emit(OP_BINARY_POW, BC_NOARG, line); break; case TK("**"): ctx->emit_(OP_BINARY_POW, BC_NOARG, line); break;
case TK("<"): ctx->emit(OP_COMPARE_LT, BC_NOARG, line); break; case TK("<"): ctx->emit_(OP_COMPARE_LT, BC_NOARG, line); break;
case TK("<="): ctx->emit(OP_COMPARE_LE, BC_NOARG, line); break; case TK("<="): ctx->emit_(OP_COMPARE_LE, BC_NOARG, line); break;
case TK("=="): ctx->emit(OP_COMPARE_EQ, BC_NOARG, line); break; case TK("=="): ctx->emit_(OP_COMPARE_EQ, BC_NOARG, line); break;
case TK("!="): ctx->emit(OP_COMPARE_NE, BC_NOARG, line); break; case TK("!="): ctx->emit_(OP_COMPARE_NE, BC_NOARG, line); break;
case TK(">"): ctx->emit(OP_COMPARE_GT, BC_NOARG, line); break; case TK(">"): ctx->emit_(OP_COMPARE_GT, BC_NOARG, line); break;
case TK(">="): ctx->emit(OP_COMPARE_GE, BC_NOARG, line); break; case TK(">="): ctx->emit_(OP_COMPARE_GE, BC_NOARG, line); break;
case TK("in"): ctx->emit(OP_CONTAINS_OP, 0, line); break; case TK("in"): ctx->emit_(OP_CONTAINS_OP, 0, line); break;
case TK("not in"): ctx->emit(OP_CONTAINS_OP, 1, line); break; case TK("not in"): ctx->emit_(OP_CONTAINS_OP, 1, line); break;
case TK("is"): ctx->emit(OP_IS_OP, 0, line); break; case TK("is"): ctx->emit_(OP_IS_OP, 0, line); break;
case TK("is not"): ctx->emit(OP_IS_OP, 1, line); break; case TK("is not"): ctx->emit_(OP_IS_OP, 1, line); break;
case TK("<<"): ctx->emit(OP_BITWISE_LSHIFT, BC_NOARG, line); break; case TK("<<"): ctx->emit_(OP_BITWISE_LSHIFT, BC_NOARG, line); break;
case TK(">>"): ctx->emit(OP_BITWISE_RSHIFT, BC_NOARG, line); break; case TK(">>"): ctx->emit_(OP_BITWISE_RSHIFT, BC_NOARG, line); break;
case TK("&"): ctx->emit(OP_BITWISE_AND, BC_NOARG, line); break; case TK("&"): ctx->emit_(OP_BITWISE_AND, BC_NOARG, line); break;
case TK("|"): ctx->emit(OP_BITWISE_OR, BC_NOARG, line); break; case TK("|"): ctx->emit_(OP_BITWISE_OR, BC_NOARG, line); break;
case TK("^"): ctx->emit(OP_BITWISE_XOR, BC_NOARG, line); break; case TK("^"): ctx->emit_(OP_BITWISE_XOR, BC_NOARG, line); break;
case TK("@"): ctx->emit(OP_BINARY_MATMUL, BC_NOARG, line); break; case TK("@"): ctx->emit_(OP_BINARY_MATMUL, BC_NOARG, line); break;
default: FATAL_ERROR(); default: FATAL_ERROR();
} }
for(int i: jmps) ctx->patch_jump(i); for(int i: jmps) ctx->patch_jump(i);
} }
void TernaryExpr::emit(CodeEmitContext* ctx){ void TernaryExpr::emit_(CodeEmitContext* ctx){
cond->emit(ctx); cond->emit_(ctx);
int patch = ctx->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, cond->line); int patch = ctx->emit_(OP_POP_JUMP_IF_FALSE, BC_NOARG, cond->line);
true_expr->emit(ctx); true_expr->emit_(ctx);
int patch_2 = ctx->emit(OP_JUMP_ABSOLUTE, BC_NOARG, true_expr->line); int patch_2 = ctx->emit_(OP_JUMP_ABSOLUTE, BC_NOARG, true_expr->line);
ctx->patch_jump(patch); ctx->patch_jump(patch);
false_expr->emit(ctx); false_expr->emit_(ctx);
ctx->patch_jump(patch_2); ctx->patch_jump(patch_2);
} }