BLUELOVETH 2 лет назад
Родитель
Сommit
190d2a0589
2 измененных файлов с 45 добавлено и 24 удалено
  1. 16 24
      src/compiler.h
  2. 29 0
      src/expr.h

+ 16 - 24
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<BinaryExpr>();
-                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;
     }
 

+ 29 - 0
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{