diff --git a/docs/features/differences.md b/docs/features/differences.md index f47e9578..c7baa8b7 100644 --- a/docs/features/differences.md +++ b/docs/features/differences.md @@ -30,7 +30,7 @@ The easiest way to test a feature is to [try it on your browser](https://pocketp 8. `else` clause in try..except. 9. Inplace methods like `__iadd__` and `__imul__`. 10. `__del__` in class definition. -11. `a = b = 1`, use `a, b = 1, 1` instead. +11. Multiple inheritance. ## Different behaviors diff --git a/src/compiler.h b/src/compiler.h index 4e762c1e..214b1b39 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -646,40 +646,42 @@ __SUBSCR_END: } bool try_compile_assignment(){ - Expr* lhs_p = ctx()->s_expr.top().get(); - bool inplace; switch (curr().type) { case TK("+="): case TK("-="): case TK("*="): case TK("/="): case TK("//="): case TK("%="): case TK("<<="): case TK(">>="): case TK("&="): case TK("|="): case TK("^="): { + Expr* lhs_p = ctx()->s_expr.top().get(); + if(lhs_p->is_starred()) SyntaxError(); if(ctx()->is_compiling_class) SyntaxError(); - inplace = true; advance(); auto e = make_expr(); 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("="): - inplace = false; - advance(); - EXPR_TUPLE(); - break; + if(e->is_starred()) SyntaxError(); + e->emit(ctx()); + bool ok = lhs_p->emit_store(ctx()); + if(!ok) SyntaxError(); + } return true; + case TK("="): { + int n = 0; + while(match(TK("="))){ + EXPR_TUPLE(); + n += 1; + } + // stack size is n+1 + Expr_ val = ctx()->s_expr.popx(); + val->emit(ctx()); + for(int i=1; iemit(OP_DUP_TOP, BC_NOARG, BC_KEEPLINE); + for(int i=0; is_expr.popx(); + if(e->is_starred()) SyntaxError(); + bool ok = e->emit_store(ctx()); + if(!ok) SyntaxError(); + } + } return true; default: return false; } - // std::cout << ctx()->_log_s_expr() << std::endl; - Expr_ rhs = ctx()->s_expr.popx(); - - if(lhs_p->is_starred() || rhs->is_starred()){ - SyntaxError("can't use starred expression here"); - } - - rhs->emit(ctx()); - bool ok = lhs_p->emit_store(ctx()); - if(!ok) SyntaxError(); - if(!inplace) ctx()->s_expr.pop(); - return true; } void compile_stmt() { diff --git a/tests/32_assign.py b/tests/32_assign.py new file mode 100644 index 00000000..6ab2de25 --- /dev/null +++ b/tests/32_assign.py @@ -0,0 +1,10 @@ +a = b = 1,2 + +assert a == b +assert a == (1,2) + +a = 1,2 + +a = b = c = d = '123' + +assert a == b == c == d == '123' \ No newline at end of file