This commit is contained in:
blueloveTH 2023-04-02 14:14:41 +08:00
parent b88cd66046
commit 449fb9a2f8
7 changed files with 295 additions and 165 deletions

View File

@ -26,49 +26,86 @@ inline PyObject* VM::run_frame(Frame* frame){
Function& f = CAST(Function&, frame->top()); // reference
f._closure = frame->_locals;
} continue;
case OP_LOAD_NAME_REF: {
frame->push(PyRef(NameRef(frame->co->names[byte.arg])));
} continue;
case OP_LOAD_NAME: {
frame->push(NameRef(frame->co->names[byte.arg]).get(this, frame));
} continue;
case OP_STORE_NAME: {
auto& p = frame->co->names[byte.arg];
NameRef(p).set(this, frame, frame->pop());
} continue;
case OP_BUILD_ATTR_REF: case OP_BUILD_ATTR: {
auto& attr = frame->co->names[byte.arg];
PyObject* obj = frame->pop_value(this);
AttrRef ref = AttrRef(obj, NameRef(attr));
if(byte.op == OP_BUILD_ATTR) frame->push(ref.get(this, frame));
else frame->push(PyRef(ref));
} continue;
case OP_BUILD_INDEX: {
PyObject* index = frame->pop_value(this);
auto ref = IndexRef(frame->pop_value(this), index);
if(byte.arg > 0) frame->push(ref.get(this, frame));
else frame->push(PyRef(ref));
} continue;
case OP_FAST_INDEX: case OP_FAST_INDEX_REF: {
auto& a = frame->co->names[byte.arg & 0xFFFF];
auto& x = frame->co->names[(byte.arg >> 16) & 0xFFFF];
auto ref = IndexRef(NameRef(a).get(this, frame), NameRef(x).get(this, frame));
if(byte.op == OP_FAST_INDEX) frame->push(ref.get(this, frame));
else frame->push(PyRef(ref));
} continue;
case OP_ROT_TWO: ::std::swap(frame->top(), frame->top_1()); continue;
case OP_STORE_REF: {
PyRef_AS_C(frame->top_1())->set(this, frame, frame->top_value(this));
frame->_pop(); frame->_pop();
} continue;
case OP_DELETE_REF:
PyRef_AS_C(frame->top())->del(this, frame);
frame->_pop();
continue;
case OP_BUILD_TUPLE: {
Args items = frame->pop_n_values_reversed(this, byte.arg);
frame->push(VAR(std::move(items)));
} continue;
/*****************************************/
case OP_LOAD_NAME: {
// TODO: use name resolution linked list to optimize this
StrName name = frame->co->names[byte.arg];
PyObject* val;
val = frame->f_locals().try_get(name);
if(val != nullptr) { frame->push(val); continue; }
val = frame->f_closure_try_get(name);
if(val != nullptr) { frame->push(val); continue; }
val = frame->f_globals().try_get(name);
if(val != nullptr) { frame->push(val); continue; }
val = vm->builtins->attr().try_get(name);
if(val != nullptr) { frame->push(val); continue; }
vm->NameError(name);
} continue;
case OP_LOAD_ATTR: {
PyObject* a = frame->top();
StrName name = frame->co->names[byte.arg];
frame->top() = getattr(a, name);
} continue;
case OP_LOAD_SUBSCR: {
PyObject* b = frame->popx();
PyObject* a = frame->top();
frame->top() = fast_call(__getitem__, Args{a, b});
} continue;
case OP_STORE_LOCAL: {
StrName name = frame->co->names[byte.arg];
frame->f_locals().set(name, frame->popx());
} continue;
case OP_STORE_GLOBAL: {
StrName name = frame->co->names[byte.arg];
frame->f_globals().set(name, frame->popx());
} continue;
case OP_STORE_ATTR: {
StrName name = frame->co->names[byte.arg];
PyObject* a = frame->popx();
PyObject* val = frame->popx();
setattr(a, name, val);
} continue;
case OP_STORE_SUBSCR: {
Args args(3);
args[1] = frame->popx(); // b
args[0] = frame->popx(); // a
args[2] = frame->popx(); // val
fast_call(__setitem__, std::move(args));
} continue;
case OP_DELETE_LOCAL: {
StrName name = frame->co->names[byte.arg];
if(frame->f_locals().contains(name)){
frame->f_locals().erase(name);
}else{
NameError(name);
}
} continue;
case OP_DELETE_GLOBAL: {
StrName name = frame->co->names[byte.arg];
if(frame->f_globals().contains(name)){
frame->f_globals().erase(name);
}else{
NameError(name);
}
} continue;
case OP_DELETE_ATTR: {
PyObject* a = frame->popx();
StrName name = frame->co->names[byte.arg];
if(!a->is_attr_valid()) TypeError("cannot delete attribute");
if(!a->attr().contains(name)) AttributeError(a, name);
a->attr().erase(name);
} continue;
case OP_DELETE_SUBSCR: {
PyObject* b = frame->popx();
PyObject* a = frame->popx();
fast_call(__delitem__, Args{a, b});
} continue;
/*****************************************/
case OP_BUILD_TUPLE_REF: {
Args items = frame->pop_n_reversed(byte.arg);
frame->push(PyRef(TupleRef(std::move(items))));

View File

@ -25,7 +25,7 @@ inline const char* OP_NAMES[] = {
};
struct Bytecode{
uint8_t op;
uint16_t op;
uint16_t block;
int arg;
int line;
@ -61,7 +61,7 @@ struct CodeObject {
std::vector<Bytecode> codes;
List consts;
std::vector<std::pair<StrName, NameScope>> names;
std::vector<StrName> names;
std::set<StrName> global_names;
std::vector<CodeBlock> blocks = { CodeBlock{NO_BLOCK, -1} };
std::map<StrName, int> labels;

View File

@ -173,7 +173,7 @@ private:
}
template <typename T, typename... Args>
std::unique_ptr<T> expr_prev_line(Args&&... args) {
std::unique_ptr<T> make_expr(Args&&... args) {
std::unique_ptr<T> expr = std::make_unique<T>(std::forward<Args>(args)...);
expr->line = prev().line;
return expr;
@ -183,17 +183,17 @@ private:
// PASS
void exprLiteral(){
ctx()->s_expr.push(expr_prev_line<LiteralExpr>(prev().value));
ctx()->s_expr.push(make_expr<LiteralExpr>(prev().value));
}
// PASS
void exprFString(){
ctx()->s_expr.push(expr_prev_line<FStringExpr>(std::get<Str>(prev().value)));
ctx()->s_expr.push(make_expr<FStringExpr>(std::get<Str>(prev().value)));
}
// PASS
void exprLambda(){
auto e = expr_prev_line<LambdaExpr>();
auto e = make_expr<LambdaExpr>();
e->func.name = "<lambda>";
e->scope = name_scope();
if(!match(TK(":"))){
@ -260,7 +260,7 @@ private:
// PASS
void exprTuple(){
auto e = expr_prev_line<TupleExpr>();
auto e = make_expr<TupleExpr>();
do {
EXPR(); // NOTE: "1," will fail, "1,2" will be ok
e->items.push_back(ctx()->s_expr.popx());
@ -270,7 +270,7 @@ private:
// PASS
void exprOr(){
auto e = expr_prev_line<OrExpr>();
auto e = make_expr<OrExpr>();
e->lhs = ctx()->s_expr.popx();
parse_expression(PREC_LOGICAL_OR + 1);
e->rhs = ctx()->s_expr.popx();
@ -279,7 +279,7 @@ private:
// PASS
void exprAnd(){
auto e = expr_prev_line<AndExpr>();
auto e = make_expr<AndExpr>();
e->lhs = ctx()->s_expr.popx();
parse_expression(PREC_LOGICAL_AND + 1);
e->rhs = ctx()->s_expr.popx();
@ -288,7 +288,7 @@ private:
// PASS
void exprTernary(){
auto e = expr_prev_line<TernaryExpr>();
auto e = make_expr<TernaryExpr>();
e->cond = ctx()->s_expr.popx();
EXPR(); // if true
e->true_expr = ctx()->s_expr.popx();
@ -300,7 +300,7 @@ private:
// PASS
void exprBinaryOp(){
auto e = expr_prev_line<BinaryExpr>();
auto e = make_expr<BinaryExpr>();
e->op = prev().type;
e->lhs = ctx()->s_expr.popx();
parse_expression(rules[e->op].precedence + 1);
@ -311,7 +311,7 @@ private:
// PASS
void exprNot() {
parse_expression(PREC_LOGICAL_NOT + 1);
ctx()->s_expr.push(expr_prev_line<NotExpr>(ctx()->s_expr.popx()));
ctx()->s_expr.push(make_expr<NotExpr>(ctx()->s_expr.popx()));
}
// PASS
@ -320,10 +320,10 @@ private:
parse_expression(PREC_UNARY + 1);
switch(op){
case TK("-"):
ctx()->s_expr.push(expr_prev_line<NegatedExpr>(ctx()->s_expr.popx()));
ctx()->s_expr.push(make_expr<NegatedExpr>(ctx()->s_expr.popx()));
break;
case TK("*"):
ctx()->s_expr.push(expr_prev_line<StarredExpr>(ctx()->s_expr.popx()));
ctx()->s_expr.push(make_expr<StarredExpr>(ctx()->s_expr.popx()));
break;
default: UNREACHABLE();
}
@ -375,7 +375,7 @@ private:
match_newlines(mode()==REPL_MODE);
} while (match(TK(",")));
consume(TK("]"));
auto e = expr_prev_line<ListExpr>(std::move(items));
auto e = make_expr<ListExpr>(std::move(items));
e->line = line; // override line
ctx()->s_expr.push(std::move(e));
}
@ -392,7 +392,7 @@ private:
if(parsing_dict){
consume(TK(":"));
EXPR();
auto dict_item = expr_prev_line<DictItemExpr>();
auto dict_item = make_expr<DictItemExpr>();
dict_item->key = ctx()->s_expr.popx();
dict_item->value = ctx()->s_expr.popx();
items.push_back(std::move(dict_item));
@ -410,17 +410,17 @@ private:
} while (match(TK(",")));
consume(TK("}"));
if(items.size()==0 || parsing_dict){
auto e = expr_prev_line<DictExpr>(std::move(items));
auto e = make_expr<DictExpr>(std::move(items));
ctx()->s_expr.push(std::move(e));
}else{
auto e = expr_prev_line<SetExpr>(std::move(items));
auto e = make_expr<SetExpr>(std::move(items));
ctx()->s_expr.push(std::move(e));
}
}
// PASS
void exprCall() {
auto e = expr_prev_line<CallExpr>();
auto e = make_expr<CallExpr>();
e->callable = ctx()->s_expr.popx();
do {
match_newlines(mode()==REPL_MODE);
@ -434,38 +434,32 @@ private:
} else{
if(!e->kwargs.empty()) SyntaxError("positional argument follows keyword argument");
EXPR();
// if(co()->codes.back().op == OP_UNARY_STAR) need_unpack = true;
e->args.push_back(ctx()->s_expr.popx());
}
match_newlines(mode()==REPL_MODE);
} while (match(TK(",")));
consume(TK(")"));
if(e->args.size() > 32767) SyntaxError("too many positional arguments");
if(e->kwargs.size() > 32767) SyntaxError("too many keyword arguments");
ctx()->s_expr.push(std::move(e));
// if(ARGC > 32767) SyntaxError("too many positional arguments");
// if(KWARGC > 32767) SyntaxError("too many keyword arguments");
// if(KWARGC > 0){
// emit(need_unpack ? OP_CALL_KWARGS_UNPACK : OP_CALL_KWARGS, (KWARGC << 16) | ARGC);
// }else{
// emit(need_unpack ? OP_CALL_UNPACK : OP_CALL, ARGC);
// }
}
// PASS
void exprName(){
ctx()->s_expr.push(expr_prev_line<NameExpr>(prev().str(), name_scope()));
ctx()->s_expr.push(make_expr<NameExpr>(prev().str(), name_scope()));
}
// PASS
void exprAttrib() {
consume(TK("@id"));
ctx()->s_expr.push(
expr_prev_line<AttribExpr>(ctx()->s_expr.popx(), prev().str())
make_expr<AttribExpr>(ctx()->s_expr.popx(), prev().str())
);
}
// PASS
void exprSubscr() {
auto e = expr_prev_line<SubscrExpr>();
auto e = make_expr<SubscrExpr>();
std::vector<Expr_> items;
do {
EXPR_TUPLE();
@ -477,7 +471,7 @@ private:
e->b = std::move(items[0]);
break;
case 2: case 3: {
auto slice = expr_prev_line<SliceExpr>();
auto slice = make_expr<SliceExpr>();
slice->start = std::move(items[0]);
slice->stop = std::move(items[1]);
if(items.size()==3){
@ -492,7 +486,7 @@ private:
// PASS
void exprLiteral0() {
ctx()->s_expr.push(expr_prev_line<Literal0Expr>(prev().type));
ctx()->s_expr.push(make_expr<Literal0Expr>(prev().type));
}
void compile_block_body() {
@ -708,15 +702,6 @@ private:
ctx()->emit(OP_ASSERT, BC_NOARG, kw_line);
consume_end_stmt();
break;
case TK("del"):
EXPR_TUPLE();
Expr_ e = ctx()->s_expr.popx();
switch(e->ref_type()){
case EXPR_NAME_REF:
}
ctx()->emit(OP_DELETE_REF, BC_NOARG, kw_line);
consume_end_stmt();
break;
case TK("global"):
do {
consume(TK("@id"));
@ -735,6 +720,13 @@ private:
ctx()->emit(OP_RAISE, dummy_t, kw_line);
consume_end_stmt();
} break;
case TK("del"): {
EXPR_TUPLE();
Expr_ e = ctx()->s_expr.popx();
bool ok = e->emit_del(ctx());
if(!ok) SyntaxError();
consume_end_stmt();
} break;
case TK("with"): {
EXPR(true);
consume(TK("as"));

View File

@ -11,25 +11,20 @@ namespace pkpy{
struct CodeEmitContext;
enum ExprRefType{
EXPR_NO_REF,
EXPR_NAME_REF,
EXPR_ATTR_REF,
EXPR_INDEX_REF,
EXPR_STARRED_REF,
EXPR_TUPLE_REF
};
struct Expr{
int line = 0;
virtual ~Expr() = default;
virtual void emit(CodeEmitContext* ctx) = 0;
virtual Str str() const = 0;
virtual std::vector<const Expr*> children() = 0;
virtual ExprRefType ref_type() const {
return EXPR_NO_REF;
}
virtual std::vector<const Expr*> children() const { return {}; }
virtual bool is_starred() const { return false; }
// for OP_DELETE_XXX
virtual bool emit_del(CodeEmitContext* ctx) { return false; }
// for OP_STORE_XXX
virtual bool emit_store(CodeEmitContext* ctx) { return false; }
};
struct CodeEmitContext{
@ -67,13 +62,12 @@ struct CodeEmitContext{
void emit_expr(){
if(s_expr.size() != 1) UNREACHABLE();
Expr_ expr = s_expr.popx();
// emit
// ...
expr->emit(this);
}
int emit(Opcode opcode, int arg, int line) {
co->codes.push_back(
Bytecode{(uint8_t)opcode, (uint16_t)curr_block_i, arg, line}
Bytecode{(uint16_t)opcode, (uint16_t)curr_block_i, arg, line}
);
int i = co->codes.size() - 1;
if(line==BC_KEEPLINE && i>=1) co->codes[i].line = co->codes[i-1].line;
@ -91,13 +85,11 @@ struct CodeEmitContext{
return true;
}
int add_name(StrName name, NameScope scope){
if(scope == NAME_LOCAL && co->global_names.count(name)) scope = NAME_GLOBAL;
auto p = std::make_pair(name, scope);
int add_name(StrName name){
for(int i=0; i<co->names.size(); i++){
if(co->names[i] == p) return i;
if(co->names[i] == name) return i;
}
co->names.push_back(p);
co->names.push_back(name);
return co->names.size() - 1;
}
@ -107,7 +99,7 @@ struct CodeEmitContext{
}
};
// PASS
struct NameExpr: Expr{
Str name;
NameScope scope;
@ -117,59 +109,99 @@ struct NameExpr: Expr{
Str str() const override { return "$" + name; }
void emit(CodeEmitContext* ctx) override {
int index = ctx->add_name(name, scope);
int index = ctx->add_name(name);
ctx->emit(OP_LOAD_NAME, index, line);
}
ExprRefType ref_type() const override {
return EXPR_NAME_REF;
bool emit_del(CodeEmitContext* ctx) override {
int index = ctx->add_name(name);
switch(scope){
case NAME_LOCAL:
ctx->emit(OP_DELETE_LOCAL, index, line);
break;
case NAME_GLOBAL:
ctx->emit(OP_DELETE_GLOBAL, index, line);
break;
default: UNREACHABLE(); break;
}
return true;
}
bool emit_store(CodeEmitContext* ctx) override {
int index = ctx->add_name(name);
switch(scope){
case NAME_LOCAL:
ctx->emit(OP_STORE_LOCAL, index, line);
break;
case NAME_GLOBAL:
ctx->emit(OP_STORE_GLOBAL, index, line);
break;
default: UNREACHABLE(); break;
}
return true;
}
};
// *号运算符,作为左值和右值效果不同
struct StarredExpr: Expr{
Expr_ child;
StarredExpr(Expr_&& child): child(std::move(child)) {}
Str str() const override { return "*"; }
std::vector<const Expr*> children() const override { return {child.get()}; }
bool is_starred() const override { return true; }
void emit(CodeEmitContext* ctx) override {
child->emit(ctx);
ctx->emit(OP_UNARY_STAR, (int)false, line);
// as a rvalue, we should do unpack here
//ctx->emit(OP_UNARY_STAR, (int)false, line);
}
ExprRefType ref_type() const override {
return EXPR_STARRED_REF;
bool emit_store(CodeEmitContext* ctx) override {
child->emit(ctx);
// as a lvalue, we should do pack here
//ctx->emit(OP_UNARY_STAR, (int)true, line);
return true;
}
};
// PASS
struct NegatedExpr: Expr{
Expr_ child;
NegatedExpr(Expr_&& child): child(std::move(child)) {}
Str str() const override { return "-"; }
std::vector<const Expr*> children() const override { return {child.get()}; }
void emit(CodeEmitContext* ctx) override {
child->emit(ctx);
ctx->emit(OP_UNARY_NEGATIVE, BC_NOARG, line);
}
};
// PASS
struct NotExpr: Expr{
Expr_ child;
NotExpr(Expr_&& child): child(std::move(child)) {}
Str str() const override { return "not"; }
std::vector<const Expr*> children() const override { return {child.get()}; }
void emit(CodeEmitContext* ctx) override {
child->emit(ctx);
ctx->emit(OP_UNARY_NOT, BC_NOARG, line);
}
};
// PASS
struct AndExpr: Expr{
Expr_ lhs;
Expr_ rhs;
Str str() const override { return "and"; }
std::vector<const Expr*> children() const override { return {lhs.get(), rhs.get()}; }
void emit(CodeEmitContext* ctx) override {
lhs->emit(ctx);
int patch = ctx->emit(OP_JUMP_IF_FALSE_OR_POP, BC_NOARG, line);
@ -178,11 +210,14 @@ struct AndExpr: Expr{
}
};
// PASS
struct OrExpr: Expr{
Expr_ lhs;
Expr_ rhs;
Str str() const override { return "or"; }
std::vector<const Expr*> children() const override { return {lhs.get(), rhs.get()}; }
void emit(CodeEmitContext* ctx) override {
lhs->emit(ctx);
int patch = ctx->emit(OP_JUMP_IF_TRUE_OR_POP, BC_NOARG, line);
@ -249,12 +284,18 @@ struct LiteralExpr: Expr{
}
};
// PASS
struct SliceExpr: Expr{
Expr_ start;
Expr_ stop;
Expr_ step;
Str str() const override { return "slice()"; }
std::vector<const Expr*> children() const override {
// may contain nullptr
return {start.get(), stop.get(), step.get()};
}
void emit(CodeEmitContext* ctx) override {
if(start){
start->emit(ctx);
@ -278,11 +319,30 @@ struct SliceExpr: Expr{
}
};
struct DictItemExpr: Expr{
Expr_ key;
Expr_ value;
Str str() const override { return "k:v"; }
std::vector<const Expr*> children() const override { return {key.get(), value.get()}; }
void emit(CodeEmitContext* ctx) override {
key->emit(ctx);
value->emit(ctx);
ctx->emit(OP_BUILD_TUPLE, 2, line);
}
};
struct SequenceExpr: Expr{
std::vector<Expr_> items;
SequenceExpr(std::vector<Expr_>&& items): items(std::move(items)) {}
virtual Opcode opcode() const = 0;
std::vector<const Expr*> children() const override {
std::vector<const Expr*> ret;
for(auto& item: items) ret.push_back(item.get());
return ret;
}
void emit(CodeEmitContext* ctx) override {
for(auto& item: items) item->emit(ctx);
ctx->emit(opcode(), items.size(), line);
@ -308,8 +368,9 @@ struct TupleExpr: SequenceExpr{
Str str() const override { return "tuple()"; }
Opcode opcode() const override { return OP_BUILD_TUPLE; }
ExprRefType ref_type() const override {
return EXPR_TUPLE_REF;
bool emit_store(CodeEmitContext* ctx) override {
// ...
return true;
}
};
@ -318,14 +379,6 @@ struct CompExpr: Expr{
Expr_ vars; // loop vars
Expr_ iter; // loop iter
Expr_ cond; // optional if condition
virtual void emit_expr() = 0;
};
// a:b
struct DictItemExpr: Expr{
Expr_ key;
Expr_ value;
Str str() const override { return "k:v"; }
};
struct ListCompExpr: CompExpr{
@ -345,7 +398,9 @@ struct LambdaExpr: Expr{
void emit(CodeEmitContext* ctx) override {
VM* vm = ctx->vm;
ctx->emit(OP_LOAD_FUNCTION, ctx->add_const(VAR(func)), line);
if(scope == NAME_LOCAL) ctx->emit(OP_SETUP_CLOSURE, BC_NOARG, BC_KEEPLINE);
if(scope == NAME_LOCAL){
ctx->emit(OP_SETUP_CLOSURE, BC_NOARG, BC_KEEPLINE);
}
}
};
@ -393,11 +448,21 @@ struct SubscrExpr: Expr{
void emit(CodeEmitContext* ctx) override{
a->emit(ctx);
b->emit(ctx);
ctx->emit(OP_BUILD_INDEX, BC_NOARG, line);
ctx->emit(OP_LOAD_SUBSCR, BC_NOARG, line);
}
ExprRefType ref_type() const override {
return EXPR_INDEX_REF;
bool emit_del(CodeEmitContext* ctx) override {
a->emit(ctx);
b->emit(ctx);
ctx->emit(OP_DELETE_SUBSCR, BC_NOARG, line);
return true;
}
bool emit_store(CodeEmitContext* ctx) override {
a->emit(ctx);
b->emit(ctx);
ctx->emit(OP_STORE_SUBSCR, BC_NOARG, line);
return true;
}
};
@ -408,16 +473,56 @@ struct AttribExpr: Expr{
AttribExpr(Expr_ a, Str&& b): a(std::move(a)), b(std::move(b)) {}
Str str() const override { return "a.b"; }
ExprRefType ref_type() const override {
return EXPR_ATTR_REF;
void emit(CodeEmitContext* ctx) override{
a->emit(ctx);
int index = ctx->add_name(b);
ctx->emit(OP_LOAD_ATTR, index, line);
}
bool emit_del(CodeEmitContext* ctx) override {
a->emit(ctx);
int index = ctx->add_name(b);
ctx->emit(OP_DELETE_ATTR, index, line);
return true;
}
bool emit_store(CodeEmitContext* ctx) override {
a->emit(ctx);
int index = ctx->add_name(b);
ctx->emit(OP_STORE_ATTR, index, line);
return true;
}
};
// PASS
struct CallExpr: Expr{
Expr_ callable;
std::vector<Expr_> args;
std::vector<std::pair<Str, Expr_>> kwargs;
Str str() const override { return "()"; }
Str str() const override { return "call(...)"; }
std::vector<const Expr*> children() const override {
std::vector<const Expr*> ret;
for(auto& item: args) ret.push_back(item.get());
// ...ignore kwargs for simplicity
return ret;
}
bool need_unpack() const {
for(auto& item: args) if(item->is_starred()) return true;
return false;
}
void emit(CodeEmitContext* ctx) override {
callable->emit(ctx);
int KWARGC = (int)kwargs.size();
int ARGC = (int)args.size();
if(KWARGC > 0){
ctx->emit(need_unpack() ? OP_CALL_KWARGS_UNPACK : OP_CALL_KWARGS, (KWARGC<<16)|ARGC, line);
}else{
ctx->emit(need_unpack() ? OP_CALL_UNPACK : OP_CALL, ARGC, line);
}
}
};
struct BinaryExpr: Expr{
@ -426,6 +531,10 @@ struct BinaryExpr: Expr{
Expr_ rhs;
Str str() const override { return TK_STR(op); }
std::vector<const Expr*> children() const override {
return {lhs.get(), rhs.get()};
}
void emit(CodeEmitContext* ctx) override {
lhs->emit(ctx);
rhs->emit(ctx);
@ -459,13 +568,18 @@ struct BinaryExpr: Expr{
}
};
// PASS
struct TernaryExpr: Expr{
Expr_ cond;
Expr_ true_expr;
Expr_ false_expr;
Str str() const override {
return "cond ? true_expr : false_expr";
return "cond ? t : f";
}
std::vector<const Expr*> children() const override {
return {cond.get(), true_expr.get(), false_expr.get()};
}
void emit(CodeEmitContext* ctx) override {

View File

@ -53,34 +53,20 @@ struct Frame {
// return ss.str();
// }
PyObject* pop(){
#if DEBUG_EXTRA_CHECK
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
#endif
PyObject* v = _data.back();
_data.pop_back();
return v;
}
void _pop(){
void pop(){
#if DEBUG_EXTRA_CHECK
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
#endif
_data.pop_back();
}
void try_deref(VM*, PyObject*&);
PyObject* pop_value(VM* vm){
PyObject* value = pop();
try_deref(vm, value);
return value;
}
PyObject* top_value(VM* vm){
PyObject* value = top();
try_deref(vm, value);
return value;
PyObject* popx(){
#if DEBUG_EXTRA_CHECK
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
#endif
PyObject* ret = _data.back();
_data.pop_back();
return ret;
}
PyObject*& top(){
@ -141,18 +127,9 @@ struct Frame {
}
}
Args pop_n_values_reversed(VM* vm, int n){
Args v(n);
for(int i=n-1; i>=0; i--){
v[i] = pop();
try_deref(vm, v[i]);
}
return v;
}
Args pop_n_reversed(int n){
Args v(n);
for(int i=n-1; i>=0; i--) v[i] = pop();
for(int i=n-1; i>=0; i--) v[i] = popx();
return v;
}

View File

@ -71,7 +71,6 @@ OPCODE(BUILD_ATTR_REF)
OPCODE(STORE_NAME)
OPCODE(STORE_FUNCTION)
OPCODE(STORE_REF)
OPCODE(DELETE_REF)
OPCODE(TRY_BLOCK_ENTER)
OPCODE(TRY_BLOCK_EXIT)
@ -89,4 +88,20 @@ OPCODE(BEGIN_CLASS)
OPCODE(END_CLASS)
OPCODE(STORE_CLASS_ATTR)
/**************************/
OPCODE(LOAD_NAME)
OPCODE(LOAD_ATTR)
OPCODE(LOAD_SUBSCR)
OPCODE(STORE_LOCAL)
OPCODE(STORE_GLOBAL)
OPCODE(STORE_ATTR)
OPCODE(STORE_SUBSCR)
OPCODE(DELETE_LOCAL)
OPCODE(DELETE_GLOBAL)
OPCODE(DELETE_ATTR)
OPCODE(DELETE_SUBSCR)
/**************************/
#endif

View File

@ -83,11 +83,6 @@ struct AttrRef : BaseRef {
vm->setattr(obj, attr.name(), std::move(val));
}
void del(VM* vm, Frame* frame) const{
if(!obj->is_attr_valid()) vm->TypeError("cannot delete attribute");
if(!obj->attr().contains(attr.name())) vm->AttributeError(obj, attr.name());
obj->attr().erase(attr.name());
}
};
struct IndexRef : BaseRef {