Skip to content

Commit 8858589

Browse files
committed
With statememt
1 parent 034315f commit 8858589

File tree

5 files changed

+37
-7
lines changed

5 files changed

+37
-7
lines changed

ast/ast.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ type If struct {
337337

338338
type With struct {
339339
StmtBase
340-
Items []WithItem
340+
Items []*WithItem
341341
Body []Stmt
342342
}
343343

ast/dump.go

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ func dumpItem(v interface{}) string {
2424
return fmt.Sprintf("'%s'", string(x))
2525
case *Keyword:
2626
return dump(x, "keyword")
27+
case *WithItem:
28+
return dump(x, "withitem")
2729
case ModBase:
2830
case StmtBase:
2931
case ExprBase:
@@ -55,6 +57,10 @@ func dump(ast interface{}, name string) string {
5557
continue
5658
case "exprtype":
5759
fname = "type"
60+
case "contextexpr":
61+
fname = "context_expr"
62+
case "optionalvars":
63+
fname = "optional_vars"
5864
}
5965
if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() != reflect.Uint8 {
6066
strs := make([]string, fieldValue.Len())

parser/grammar.y

+13-6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr {
6767
ifstmt *ast.If
6868
lastif *ast.If
6969
exchandlers []*ast.ExceptHandler
70+
withitem *ast.WithItem
71+
withitems []*ast.WithItem
7072
}
7173

7274
%type <obj> strings
@@ -88,6 +90,8 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr {
8890
%type <aliases> dotted_as_names import_as_names import_from_arg
8991
%type <ifstmt> elifs
9092
%type <exchandlers> except_clauses
93+
%type <withitem> with_item
94+
%type <withitems> with_items
9195

9296
%token NEWLINE
9397
%token ENDMARKER
@@ -1050,27 +1054,30 @@ try_stmt:
10501054
with_items:
10511055
with_item
10521056
{
1053-
// FIXME
1057+
$$ = nil
1058+
$$ = append($$, $1)
10541059
}
10551060
| with_items ',' with_item
10561061
{
1057-
// FIXME
1062+
$$ = append($$, $3)
10581063
}
10591064

10601065
with_stmt:
1061-
WITH with_items ':' suite
1066+
WITH with_items ':' suite
10621067
{
1063-
// FIXME
1068+
$$ = &ast.With{StmtBase: ast.StmtBase{$<pos>$}, Items: $2, Body: $4}
10641069
}
10651070

10661071
with_item:
10671072
test
10681073
{
1069-
// FIXME
1074+
$$ = &ast.WithItem{Pos: $<pos>$, ContextExpr: $1}
10701075
}
10711076
| test AS expr
10721077
{
1073-
// FIXME
1078+
v := $3
1079+
v.(ast.SetCtxer).SetCtx(ast.Store)
1080+
$$ = &ast.WithItem{Pos: $<pos>$, ContextExpr: $1, OptionalVars: v}
10741081
}
10751082

10761083
// NB compile.c makes sure that the default except clause is last

parser/grammar_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ func TestGrammar(t *testing.T) {
214214
{"try:\n pass\nexcept a:\n break\nexcept:\n continue\nexcept b as c:\n break\nelse:\n pass\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=Name(id='a', ctx=Load()), name=None, body=[Break()]), ExceptHandler(type=None, name=None, body=[Continue()]), ExceptHandler(type=Name(id='b', ctx=Load()), name='c', body=[Break()])], orelse=[Pass()], finalbody=[])])"},
215215
{"try:\n pass\nexcept:\n continue\nfinally:\n pass\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=None, name=None, body=[Continue()])], orelse=[], finalbody=[Pass()])])"},
216216
{"try:\n pass\nexcept:\n continue\nelse:\n break\nfinally:\n pass\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=None, name=None, body=[Continue()])], orelse=[Break()], finalbody=[Pass()])])"},
217+
{"with x:\n pass\n", "exec", "Module(body=[With(items=[withitem(context_expr=Name(id='x', ctx=Load()), optional_vars=None)], body=[Pass()])])"},
218+
{"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()])])"},
219+
{"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()])])"},
217220
// END TESTS
218221
} {
219222
Ast, err := ParseString(test.in, test.mode)

parser/make_grammar_test.py

+14
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,20 @@
300300
finally:
301301
pass
302302
""", "exec"),
303+
304+
("""\
305+
with x:
306+
pass
307+
""", "exec"),
308+
("""\
309+
with x as y:
310+
pass
311+
""", "exec"),
312+
("""\
313+
with x as y, a as b, c, d as e:
314+
pass
315+
continue
316+
""", "exec"),
303317
]
304318

305319
def dump(source, mode):

0 commit comments

Comments
 (0)