Skip to content

Commit 69f12ff

Browse files
committed
Implement tuple and list in ast - comprehensions still to go
1 parent bdbd2d0 commit 69f12ff

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

parser/grammar.y

+23-21
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ func (es *stmtsStack) Add(stmt ...ast.Stmt) {
6565
(*es)[i] = append((*es)[i], stmt...)
6666
}
6767

68+
// Returns a Tuple if > 1 items or a trailing comma, otherwise returns
69+
// the first item in elts
70+
func tupleOrExpr(pos ast.Pos, elts []ast.Expr, optional_comma bool) ast.Expr {
71+
if optional_comma || len(elts) > 1 {
72+
return &ast.Tuple{ExprBase: ast.ExprBase{pos}, Elts: elts, Ctx: ast.Load}
73+
} else {
74+
return elts[0]
75+
}
76+
}
77+
6878
%}
6979

7080
%union {
@@ -492,12 +502,7 @@ optional_comma:
492502
testlist_star_expr:
493503
test_or_star_exprs optional_comma
494504
{
495-
elts := $1.Pop()
496-
if $2 || len(elts) > 1 {
497-
$$ = &ast.Tuple{ExprBase: ast.ExprBase{$<pos>$}, Elts: elts} // FIXME Ctx
498-
} else {
499-
$$ = elts[0]
500-
}
505+
$$ = tupleOrExpr($<pos>$, $1.Pop(), $2)
501506
}
502507

503508
augassign:
@@ -1096,22 +1101,30 @@ atom:
10961101
panic("yield_expr not implemented")
10971102
$$ = nil
10981103
}
1099-
| '(' testlist_comp ')'
1104+
| '(' test_or_star_expr comp_for ')'
11001105
{
11011106
// FIXME
1102-
panic("testlist_comp not implemented")
1107+
panic("not implemented")
11031108
$$ = nil
11041109
}
1110+
| '(' test_or_star_exprs optional_comma ')'
1111+
{
1112+
$$ = tupleOrExpr($<pos>$, $2.Pop(), $3)
1113+
}
11051114
| '[' ']'
11061115
{
11071116
$$ = &ast.List{ExprBase: ast.ExprBase{$<pos>$}, Ctx: ast.Load}
11081117
}
1109-
| '[' testlist_comp ']'
1118+
| '[' test_or_star_expr comp_for ']'
11101119
{
11111120
// FIXME
1112-
panic("testlist_comp not implemented")
1121+
panic("not implemented")
11131122
$$ = nil
11141123
}
1124+
| '[' test_or_star_exprs optional_comma ']'
1125+
{
1126+
$$ = &ast.List{ExprBase: ast.ExprBase{$<pos>$}, Elts: $2.Pop(), Ctx: ast.Load}
1127+
}
11151128
| '{' '}'
11161129
{
11171130
$$ = &ast.Dict{ExprBase: ast.ExprBase{$<pos>$}}
@@ -1156,17 +1169,6 @@ atom:
11561169
$$ = &ast.NameConstant{ExprBase: ast.ExprBase{$<pos>$}, Value: py.False}
11571170
}
11581171

1159-
testlist_comp:
1160-
test_or_star_expr comp_for
1161-
{
1162-
// FIXME
1163-
}
1164-
| test_or_star_exprs optional_comma
1165-
{
1166-
// FIXME
1167-
// $1.Pop()
1168-
}
1169-
11701172
// Trailers are half made Call, Attribute or Subscript
11711173
trailer:
11721174
'(' ')'

parser/grammar_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ func TestGrammar(t *testing.T) {
1919
out string
2020
}{
2121
// START TESTS
22+
// *** Tests auto generated by make_grammar_test.py - do not edit ***
2223
{"", "exec", "Module(body=[])"},
2324
{"pass", "exec", "Module(body=[Pass()])"},
2425
{"()", "eval", "Expression(body=Tuple(elts=[], ctx=Load()))"},
@@ -47,6 +48,17 @@ func TestGrammar(t *testing.T) {
4748
{"{ 'a':1 }", "eval", "Expression(body=Dict(keys=[Str(s='a')], values=[Num(n=1)]))"},
4849
{"{ 'a':1, 'b':2 }", "eval", "Expression(body=Dict(keys=[Str(s='a'), Str(s='b')], values=[Num(n=1), Num(n=2)]))"},
4950
{"{ 'a':{'aa':11, 'bb':{'aa':11, 'bb':22}}, 'b':{'aa':11, 'bb':22} }", "eval", "Expression(body=Dict(keys=[Str(s='a'), Str(s='b')], values=[Dict(keys=[Str(s='aa'), Str(s='bb')], values=[Num(n=11), Dict(keys=[Str(s='aa'), Str(s='bb')], values=[Num(n=11), Num(n=22)])]), Dict(keys=[Str(s='aa'), Str(s='bb')], values=[Num(n=11), Num(n=22)])]))"},
51+
{"(1)", "eval", "Expression(body=Num(n=1))"},
52+
{"(1,)", "eval", "Expression(body=Tuple(elts=[Num(n=1)], ctx=Load()))"},
53+
{"(1,2)", "eval", "Expression(body=Tuple(elts=[Num(n=1), Num(n=2)], ctx=Load()))"},
54+
{"(1,2,)", "eval", "Expression(body=Tuple(elts=[Num(n=1), Num(n=2)], ctx=Load()))"},
55+
{"{(1,2)}", "eval", "Expression(body=Set(elts=[Tuple(elts=[Num(n=1), Num(n=2)], ctx=Load())]))"},
56+
{"(((((1,),(2,),),(2,),),((1,),(2,),),),((1,),(2,),))", "eval", "Expression(body=Tuple(elts=[Tuple(elts=[Tuple(elts=[Tuple(elts=[Tuple(elts=[Num(n=1)], ctx=Load()), Tuple(elts=[Num(n=2)], ctx=Load())], ctx=Load()), Tuple(elts=[Num(n=2)], ctx=Load())], ctx=Load()), Tuple(elts=[Tuple(elts=[Num(n=1)], ctx=Load()), Tuple(elts=[Num(n=2)], ctx=Load())], ctx=Load())], ctx=Load()), Tuple(elts=[Tuple(elts=[Num(n=1)], ctx=Load()), Tuple(elts=[Num(n=2)], ctx=Load())], ctx=Load())], ctx=Load()))"},
57+
{"(((1)))", "eval", "Expression(body=Num(n=1))"},
58+
{"[1]", "eval", "Expression(body=List(elts=[Num(n=1)], ctx=Load()))"},
59+
{"[1,]", "eval", "Expression(body=List(elts=[Num(n=1)], ctx=Load()))"},
60+
{"[1,2]", "eval", "Expression(body=List(elts=[Num(n=1), Num(n=2)], ctx=Load()))"},
61+
{"[1,2,]", "eval", "Expression(body=List(elts=[Num(n=1), Num(n=2)], ctx=Load()))"},
5062
// END TESTS
5163
} {
5264
Ast, err := ParseString(test.in, test.mode)

parser/make_grammar_test.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,20 @@
3232
("{1,}", "eval"),
3333
("{1,2}", "eval"),
3434
("{1,2,3,}", "eval"),
35-
# Need to implement tuple first ("{(1,2)}", "eval"),
3635
("{ 'a':1 }", "eval"),
3736
("{ 'a':1, 'b':2 }", "eval"),
3837
("{ 'a':{'aa':11, 'bb':{'aa':11, 'bb':22}}, 'b':{'aa':11, 'bb':22} }", "eval"),
38+
("(1)", "eval"),
39+
("(1,)", "eval"),
40+
("(1,2)", "eval"),
41+
("(1,2,)", "eval"),
42+
("{(1,2)}", "eval"),
43+
("(((((1,),(2,),),(2,),),((1,),(2,),),),((1,),(2,),))", "eval"),
44+
("(((1)))", "eval"),
45+
("[1]", "eval"),
46+
("[1,]", "eval"),
47+
("[1,2]", "eval"),
48+
("[1,2,]", "eval"),
3949
]
4050

4151
def dump(source, mode):
@@ -60,6 +70,7 @@ def main():
6070
for line in lines:
6171
if "START TESTS" in line:
6272
out.append(line)
73+
out.append("\t\t// *** Tests auto generated by make_grammar_test.py - do not edit ***")
6374
for source, mode in inp:
6475
out.append('\t\t{"%s", "%s", "%s"},' % (escape(source), mode, escape(dump(source, mode))))
6576
in_tests = True

0 commit comments

Comments
 (0)