From 636dbdd64aec876820cb2971ed6b0df4734a7dec Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Fri, 9 Jun 2023 22:16:53 +0800 Subject: [PATCH] ... --- src/compiler.h | 4 ---- src/expr.h | 33 ++++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index 890e9d70..e2568c85 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -322,7 +322,6 @@ class Compiler { if (curr().type == TK("]")) break; EXPR(); items.push_back(ctx()->s_expr.popx()); - if(items.back()->is_starred()) SyntaxError(); match_newlines_repl(); if(items.size()==1 && match(TK("for"))){ _consume_comp(std::move(items[0])); @@ -351,12 +350,9 @@ class Compiler { auto dict_item = make_expr(); dict_item->key = ctx()->s_expr.popx(); dict_item->value = ctx()->s_expr.popx(); - if(dict_item->key->is_starred()) SyntaxError(); - if(dict_item->value->is_starred()) SyntaxError(); items.push_back(std::move(dict_item)); }else{ items.push_back(ctx()->s_expr.popx()); - if(items.back()->is_starred()) SyntaxError(); } match_newlines_repl(); if(items.size()==1 && match(TK("for"))){ diff --git a/src/expr.h b/src/expr.h index 80f0f34d..f2f70669 100644 --- a/src/expr.h +++ b/src/expr.h @@ -370,10 +370,16 @@ struct DictItemExpr: Expr{ Expr_ value; std::string str() const override { return "DictItem()"; } + int star_level() const override { return value->star_level(); } + void emit(CodeEmitContext* ctx) override { - value->emit(ctx); - key->emit(ctx); // reverse order - ctx->emit(OP_BUILD_TUPLE, 2, line); + if(is_starred()){ + value->emit(ctx); + }else{ + value->emit(ctx); + key->emit(ctx); // reverse order + ctx->emit(OP_BUILD_TUPLE, 2, line); + } } }; @@ -391,7 +397,11 @@ struct SequenceExpr: Expr{ struct ListExpr: SequenceExpr{ using SequenceExpr::SequenceExpr; std::string str() const override { return "List()"; } - Opcode opcode() const override { return OP_BUILD_LIST; } + + Opcode opcode() const override { + for(auto& e: items) if(e->is_starred()) return OP_BUILD_LIST_UNPACK; + return OP_BUILD_LIST; + } bool is_json_object() const override { return true; } }; @@ -399,7 +409,10 @@ struct ListExpr: SequenceExpr{ struct DictExpr: SequenceExpr{ using SequenceExpr::SequenceExpr; std::string str() const override { return "Dict()"; } - Opcode opcode() const override { return OP_BUILD_DICT; } + Opcode opcode() const override { + for(auto& e: items) if(e->is_starred()) return OP_BUILD_DICT_UNPACK; + return OP_BUILD_DICT; + } bool is_json_object() const override { return true; } }; @@ -407,13 +420,19 @@ struct DictExpr: SequenceExpr{ struct SetExpr: SequenceExpr{ using SequenceExpr::SequenceExpr; std::string str() const override { return "Set()"; } - Opcode opcode() const override { return OP_BUILD_SET; } + Opcode opcode() const override { + for(auto& e: items) if(e->is_starred()) return OP_BUILD_SET_UNPACK; + return OP_BUILD_SET; + } }; struct TupleExpr: SequenceExpr{ using SequenceExpr::SequenceExpr; std::string str() const override { return "Tuple()"; } - Opcode opcode() const override { return OP_BUILD_TUPLE; } + Opcode opcode() const override { + for(auto& e: items) if(e->is_starred()) return OP_BUILD_TUPLE_UNPACK; + return OP_BUILD_TUPLE; + } bool emit_store(CodeEmitContext* ctx) override { // TOS is an iterable