Skip to content

Commit

Permalink
Assign and augmented assign
Browse files Browse the repository at this point in the history
  • Loading branch information
ncw committed Nov 28, 2014
1 parent 8858589 commit bad0904
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
27 changes: 21 additions & 6 deletions parser/grammar.y
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr {
return expr
}

// Set the context for all the items in exprs
func setCtx(exprs []ast.Expr, ctx ast.ExprContext) {
for i := range exprs {
exprs[i].(ast.SetCtxer).SetCtx(ctx)
}
}

%}

%union {
Expand Down Expand Up @@ -77,7 +84,7 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr {
%type <stmt> compound_stmt small_stmt expr_stmt del_stmt pass_stmt flow_stmt import_stmt global_stmt nonlocal_stmt assert_stmt break_stmt continue_stmt return_stmt raise_stmt yield_stmt import_name import_from while_stmt if_stmt for_stmt try_stmt with_stmt
%type <op> augassign
%type <expr> expr_or_star_expr expr star_expr xor_expr and_expr shift_expr arith_expr term factor power trailer atom test_or_star_expr test not_test lambdef test_nocond lambdef_nocond or_test and_test comparison testlist testlist_star_expr yield_expr_or_testlist yield_expr yield_expr_or_testlist_star_expr dictorsetmaker sliceop arglist except_clause
%type <exprs> exprlist testlistraw comp_if comp_iter expr_or_star_exprs test_or_star_exprs tests test_colon_tests trailers
%type <exprs> exprlist testlistraw comp_if comp_iter expr_or_star_exprs test_or_star_exprs tests test_colon_tests trailers equals_yield_expr_or_testlist_star_expr
%type <cmpop> comp_op
%type <comma> optional_comma
%type <comprehensions> comp_for
Expand Down Expand Up @@ -553,11 +560,18 @@ expr_stmt: testlist_star_expr ('=' (yield_expr|testlist_star_expr))*
expr_stmt:
testlist_star_expr augassign yield_expr_or_testlist
{
// FIXME
target := $1
target.(ast.SetCtxer).SetCtx(ast.Store)
$$ = &ast.AugAssign{StmtBase: ast.StmtBase{$<pos>$}, Target: target, Op: $2, Value: $3}
}
| testlist_star_expr equals_yield_expr_or_testlist_star_expr
{
// FIXME
targets := []ast.Expr{$1}
targets = append(targets, $2...)
value := targets[len(targets)-1]
targets = targets[:len(targets)-1]
setCtx(targets, ast.Store)
$$ = &ast.Assign{StmtBase: ast.StmtBase{$<pos>$}, Targets: targets, Value: value}
}
| testlist_star_expr
{
Expand Down Expand Up @@ -587,9 +601,12 @@ yield_expr_or_testlist_star_expr:
equals_yield_expr_or_testlist_star_expr:
'=' yield_expr_or_testlist_star_expr
{
$$ = nil
$$ = append($$, $2)
}
| equals_yield_expr_or_testlist_star_expr '=' yield_expr_or_testlist_star_expr
{
$$ = append($$, $3)
}

test_or_star_exprs:
Expand Down Expand Up @@ -682,9 +699,7 @@ augassign:
del_stmt:
DEL exprlist
{
for i := range $2 {
$2[i].(ast.SetCtxer).SetCtx(ast.Del)
}
setCtx($2, ast.Del)
$$ = &ast.Delete{StmtBase: ast.StmtBase{$<pos>$}, Targets: $2}
}

Expand Down
17 changes: 17 additions & 0 deletions parser/grammar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,23 @@ func TestGrammar(t *testing.T) {
{"with x:\n pass\n", "exec", "Module(body=[With(items=[withitem(context_expr=Name(id='x', ctx=Load()), optional_vars=None)], body=[Pass()])])"},
{"with x as y:\n pass\n", "exec", "Module(body=[With(items=[withitem(context_expr=Name(id='x', ctx=Load()), optional_vars=Name(id='y', ctx=Store()))], body=[Pass()])])"},
{"with x as y, a as b, c, d as e:\n pass\n continue\n", "exec", "Module(body=[With(items=[withitem(context_expr=Name(id='x', ctx=Load()), optional_vars=Name(id='y', ctx=Store())), withitem(context_expr=Name(id='a', ctx=Load()), optional_vars=Name(id='b', ctx=Store())), withitem(context_expr=Name(id='c', ctx=Load()), optional_vars=None), withitem(context_expr=Name(id='d', ctx=Load()), optional_vars=Name(id='e', ctx=Store()))], body=[Pass(), Continue()])])"},
{"a += b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Add(), value=Name(id='b', ctx=Load()))])"},
{"a -= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Sub(), value=Name(id='b', ctx=Load()))])"},
{"a *= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Mult(), value=Name(id='b', ctx=Load()))])"},
{"a /= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Div(), value=Name(id='b', ctx=Load()))])"},
{"a -= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Sub(), value=Name(id='b', ctx=Load()))])"},
{"a %= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Mod(), value=Name(id='b', ctx=Load()))])"},
{"a &= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=BitAnd(), value=Name(id='b', ctx=Load()))])"},
{"a |= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=BitOr(), value=Name(id='b', ctx=Load()))])"},
{"a ^= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=BitXor(), value=Name(id='b', ctx=Load()))])"},
{"a <<= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=LShift(), value=Name(id='b', ctx=Load()))])"},
{"a >>= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=RShift(), value=Name(id='b', ctx=Load()))])"},
{"a **= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=Pow(), value=Name(id='b', ctx=Load()))])"},
{"a //= b", "exec", "Module(body=[AugAssign(target=Name(id='a', ctx=Store()), op=FloorDiv(), value=Name(id='b', ctx=Load()))])"},
{"a = b", "exec", "Module(body=[Assign(targets=[Name(id='a', ctx=Store())], value=Name(id='b', ctx=Load()))])"},
{"a = b = c", "exec", "Module(body=[Assign(targets=[Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], value=Name(id='c', ctx=Load()))])"},
{"a, b = 1, 2", "exec", "Module(body=[Assign(targets=[Tuple(elts=[Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store())], value=Tuple(elts=[Num(n=1), Num(n=2)], ctx=Load()))])"},
{"a, b = c, d = 1, 2", "exec", "Module(body=[Assign(targets=[Tuple(elts=[Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store()), Tuple(elts=[Name(id='c', ctx=Store()), Name(id='d', ctx=Store())], ctx=Store())], value=Tuple(elts=[Num(n=1), Num(n=2)], ctx=Load()))])"},
// END TESTS
} {
Ast, err := ParseString(test.in, test.mode)
Expand Down
21 changes: 21 additions & 0 deletions parser/make_grammar_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,27 @@
pass
continue
""", "exec"),

# Augmented assign
("a += b", "exec"),
("a -= b", "exec"),
("a *= b", "exec"),
("a /= b", "exec"),
("a -= b", "exec"),
("a %= b", "exec"),
("a &= b", "exec"),
("a |= b", "exec"),
("a ^= b", "exec"),
("a <<= b", "exec"),
("a >>= b", "exec"),
("a **= b", "exec"),
("a //= b", "exec"),

# Assign
("a = b", "exec"),
("a = b = c", "exec"),
("a, b = 1, 2", "exec"),
("a, b = c, d = 1, 2", "exec"),
]

def dump(source, mode):
Expand Down

0 comments on commit bad0904

Please sign in to comment.