From 190d2a0589e325857c188afac92327507dee6bb9 Mon Sep 17 00:00:00 2001 From: BLUELOVETH Date: Mon, 3 Apr 2023 13:09:46 +0000 Subject: [PATCH] up --- src/compiler.h | 40 ++++++++++++++++------------------------ src/expr.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index 7fae7ff2..522c294f 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -575,6 +575,8 @@ class Compiler { void compile_decorated(){ EXPR(false); + // TODO: support multiple decorator + // use a while loop to consume '@' if(!match_newlines(mode()==REPL_MODE)) SyntaxError(); ctx()->emit(OP_SETUP_DECORATOR, BC_NOARG, prev().line); consume(TK("def")); @@ -582,40 +584,30 @@ class Compiler { } bool try_compile_assignment(){ - Expr_ lhs = ctx()->s_expr.popx(); + Expr* lhs_p = ctx()->s_expr.top().get(); + bool inplace; switch (curr().type) { - // case TK("+="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 0); break; - // case TK("-="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 1); break; - // case TK("*="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 2); break; - // case TK("/="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 3); break; - // case TK("//="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 4); break; - // case TK("%="): lhs->emit(ctx()); advance(); emit(OP_BINARY_OP, 5); break; - // case TK("<<="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 0); break; - // case TK(">>="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 1); break; - // case TK("&="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 2); break; - // case TK("|="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 3); break; - // case TK("^="): lhs->emit(ctx()); advance(); emit(OP_BITWISE_OP, 4); break; - // case TK("="): advance(); break; case TK("+="): case TK("-="): case TK("*="): case TK("/="): case TK("//="): case TK("%="): case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): { + inplace = true; advance(); auto e = make_expr(); - e->op = prev().type; - e->lhs = lhs; // here should be a copy + e->op = prev().type - 1; // -1 to remove = + e->lhs = ctx()->s_expr.popx(); EXPR_TUPLE(); e->rhs = ctx()->s_expr.popx(); - // ... + ctx()->s_expr.push(std::move(e)); } break; - case TK("="): advance(); break; + case TK("="): + inplace = false; + advance(); + EXPR_TUPLE(); + break; default: return false; } - if(prev().type == TK("=")){ - EXPR_TUPLE(); - Expr_ rhs = ctx()->s_expr.popx(); - // do assign here - // lhs = rhs - return true; - } + ctx()->emit_expr(); + bool ok = lhs_p->emit_store(ctx()); + if(!ok) SyntaxError(); return true; } diff --git a/src/expr.h b/src/expr.h index a4c0ea0b..096a3334 100644 --- a/src/expr.h +++ b/src/expr.h @@ -421,15 +421,44 @@ struct CompExpr: Expr{ Expr_ vars; // loop vars Expr_ iter; // loop iter Expr_ cond; // optional if condition + + virtual Opcode op0() = 0; + virtual Opcode op1() = 0; + + void emit(CodeEmitContext* ctx){ + ctx->emit(op0(), 0, line); + iter->emit(ctx); + ctx->emit(OP_GET_ITER, BC_NOARG, BC_KEEPLINE); + ctx->enter_block(FOR_LOOP); + ctx->emit(OP_FOR_ITER, BC_NOARG, BC_KEEPLINE); + bool ok = vars->emit_store(ctx); + if(!ok) SyntaxError(); // this error occurs in `vars` instead of this line, but...nevermind + if(cond){ + cond->emit(ctx); + int patch = ctx->emit(OP_POP_JUMP_IF_FALSE, BC_NOARG, BC_KEEPLINE); + ctx->emit(op1(), BC_NOARG, BC_KEEPLINE); + ctx->patch_jump(patch); + }else{ + ctx->emit(op1(), BC_NOARG, BC_KEEPLINE); + } + ctx->emit(OP_LOOP_CONTINUE, BC_NOARG, BC_KEEPLINE); + ctx->exit_block(); + } }; struct ListCompExpr: CompExpr{ + Opcode op0() override { return OP_BUILD_LIST; } + Opcode op1() override { return OP_LIST_APPEND; } }; struct DictCompExpr: CompExpr{ + Opcode op0() override { return OP_BUILD_DI CT; } + Opcode op1() override { return OP_DICT_ADD; } }; struct SetCompExpr: CompExpr{ + Opcode op0() override { return OP_BUILD_SET; } + Opcode op1() override { return OP_SET_ADD; } }; struct LambdaExpr: Expr{