diff --git a/src/compiler.h b/src/compiler.h index 774e4540..d8660a4d 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -830,6 +830,7 @@ private: } void compile_function(){ + // TODO: bug, if there are multiple decorators, will cause error bool has_decorator = !co()->codes.empty() && co()->codes.back().op == OP_SETUP_DECORATOR; Function func; StrName obj_name; diff --git a/src/expr.h b/src/expr.h index 2fe92068..7106f82a 100644 --- a/src/expr.h +++ b/src/expr.h @@ -16,8 +16,8 @@ struct Expr{ virtual void emit(CodeEmitContext* ctx) = 0; virtual Str str() const = 0; - virtual void emit_lvalue(CodeEmitContext* ctx){ - throw std::runtime_error("emit_lvalue() is not supported"); + virtual void emit_ref(CodeEmitContext* ctx){ + throw std::runtime_error("emit_ref() is not supported"); } }; @@ -108,8 +108,14 @@ struct NameExpr: Expr{ int index = ctx->add_name(name, scope); ctx->emit(OP_LOAD_NAME, index, line); } + + void emit_ref(CodeEmitContext* ctx) override { + int index = ctx->add_name(name, scope); + ctx->emit(OP_LOAD_NAME_REF, index, line); + } }; + struct StarredExpr: Expr{ Expr_ child; StarredExpr(Expr_&& child): child(std::move(child)) {} @@ -119,6 +125,11 @@ struct StarredExpr: Expr{ child->emit(ctx); ctx->emit(OP_UNARY_STAR, (int)false, line); } + + void emit_ref(CodeEmitContext* ctx) override { + child->emit(ctx); + ctx->emit(OP_UNARY_STAR, (int)true, line); + } }; struct NegatedExpr: Expr{ @@ -232,28 +243,58 @@ struct SliceExpr: Expr{ Expr_ stop; Expr_ step; Str str() const override { return "slice()"; } + + void emit(CodeEmitContext* ctx) override { + if(start){ + start->emit(ctx); + }else{ + ctx->emit(OP_LOAD_NONE, BC_NOARG, line); + } + + if(stop){ + stop->emit(ctx); + }else{ + ctx->emit(OP_LOAD_NONE, BC_NOARG, line); + } + + if(step){ + step->emit(ctx); + }else{ + ctx->emit(OP_LOAD_NONE, BC_NOARG, line); + } + + ctx->emit(OP_BUILD_SLICE, BC_NOARG, line); + } }; -struct ListExpr: Expr{ +struct SequenceExpr: Expr{ std::vector items; - Str str() const override { return "[]"; } + virtual Opcode opcode() const = 0; + + void emit(CodeEmitContext* ctx) override { + for(auto& item: items) item->emit(ctx); + ctx->emit(opcode(), items.size(), line); + } }; -struct DictExpr: Expr{ - std::vector items; // each item is a DictItemExpr - DictExpr(std::vector&& items): items(std::move(items)) {} - Str str() const override { return "{}"; } +struct ListExpr: SequenceExpr{ + Str str() const override { return "list()"; } + Opcode opcode() const override { return OP_BUILD_LIST; } }; -struct SetExpr: Expr{ - std::vector items; - SetExpr(std::vector&& items): items(std::move(items)) {} - Str str() const override { return "{}"; } +struct DictExpr: SequenceExpr{ + Str str() const override { return "dict()"; } + Opcode opcode() const override { return OP_BUILD_MAP; } }; -struct TupleExpr: Expr{ - std::vector items; +struct SetExpr: SequenceExpr{ + Str str() const override { return "set()"; } + Opcode opcode() const override { return OP_BUILD_SET; } +}; + +struct TupleExpr: SequenceExpr{ Str str() const override { return "tuple()"; } + Opcode opcode() const override { return OP_BUILD_TUPLE; } }; struct CompExpr: Expr{