Skip to content

Commit f627870

Browse files
committed
Make Call with arguments work
1 parent 133ce36 commit f627870

File tree

5 files changed

+94
-5
lines changed

5 files changed

+94
-5
lines changed

‎ast/ast.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ type UnaryOp struct{
429429

430430
typeLambdastruct{
431431
ExprBase
432-
ArgsArguments
432+
Args*Arguments
433433
BodyExpr
434434
}
435435

‎ast/dump.go‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ func dumpItem(v interface{}) string{
1919
returnfmt.Sprintf("b'%s'", string(x))
2020
caseIdentifier:
2121
returnfmt.Sprintf("'%s'", string(x))
22+
case*Keyword:
23+
returndump(x, "keyword")
2224
caseModBase:
2325
caseStmtBase:
2426
caseExprBase:
@@ -43,7 +45,7 @@ func dump(ast interface{}, name string) string{
4345
fieldType:=astType.Field(i)
4446
fieldValue:=astValue.Field(i)
4547
fname:=strings.ToLower(fieldType.Name)
46-
iffname=="stmtbase"||fname=="exprbase"||fname=="modbase"||fname=="slicebase"{
48+
iffname=="stmtbase"||fname=="exprbase"||fname=="modbase"||fname=="slicebase"||fname=="pos"{
4749
continue
4850
}
4951
iffieldValue.Kind() ==reflect.Slice&&fieldValue.Type().Elem().Kind() !=reflect.Uint8{

‎parser/grammar.y‎

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,21 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr{
5959
comprehensions []ast.Comprehension
6060
isExpr bool
6161
slice ast.Slicer
62+
call *ast.Call
6263
}
6364

6465
%type<obj>strings
6566
%type<mod>inputsfile_inputsingle_inputeval_input
6667
%type<stmts>simple_stmtstmtnl_or_stmtsmall_stmtsstmts
6768
%type<stmt>compound_stmtsmall_stmtexpr_stmtdel_stmtpass_stmtflow_stmtimport_stmtglobal_stmtnonlocal_stmtassert_stmtbreak_stmtcontinue_stmtreturn_stmtraise_stmtyield_stmt
6869
%type<op>augassign
69-
%type<expr>expr_or_star_exprexprstar_exprxor_exprand_exprshift_exprarith_exprtermfactorpowertraileratomtest_or_star_exprtestnot_testlambdeftest_nocondlambdef_nocondor_testand_testcomparisontestlisttestlist_star_expryield_expr_or_testlistyield_expryield_expr_or_testlist_star_exprdictorsetmakersliceop
70+
%type<expr>expr_or_star_exprexprstar_exprxor_exprand_exprshift_exprarith_exprtermfactorpowertraileratomtest_or_star_exprtestnot_testlambdeftest_nocondlambdef_nocondor_testand_testcomparisontestlisttestlist_star_expryield_expr_or_testlistyield_expryield_expr_or_testlist_star_exprdictorsetmakersliceoparglist
7071
%type<exprs>exprlisttestlistrawcomp_ifcomp_iterexpr_or_star_exprstest_or_star_exprsteststest_colon_teststrailers
7172
%type<cmpop>comp_op
7273
%type<comma>optional_comma
7374
%type<comprehensions>comp_for
7475
%type<slice>subscriptsubscriptlistsubscripts
76+
%type<call>argumentargumentsoptional_argumentsarguments2
7577

7678
%tokenNEWLINE
7779
%tokenENDMARKER
@@ -1142,8 +1144,7 @@ trailer:
11421144
}
11431145
| '(' arglist ')'
11441146
{
1145-
// FIXME
1146-
$$ = nil
1147+
$$ = $2
11471148
}
11481149
| '[' subscriptlist ']'
11491150
{
@@ -1329,26 +1330,92 @@ classdef:
13291330

13301331
arguments:
13311332
argument
1333+
{
1334+
$$ = $1
1335+
}
13321336
| arguments ',' argument
1337+
{
1338+
$$.Args = append($$.Args, $3.Args...)
1339+
$$.Keywords = append($$.Keywords, $3.Keywords...)
1340+
}
13331341

13341342
optional_arguments:
1343+
{
1344+
$$ = &ast.Call{}
1345+
}
13351346
| arguments ','
1347+
{
1348+
$$ = $1
1349+
}
13361350

13371351
arguments2:
1352+
{
1353+
$$ = &ast.Call{}
1354+
}
13381355
| arguments2 ',' argument
1356+
{
1357+
$$.Args = append($$.Args, $3.Args...)
1358+
$$.Keywords = append($$.Keywords, $3.Keywords...)
1359+
}
13391360

13401361
arglist:
13411362
arguments optional_comma
1363+
{
1364+
$$ = $1
1365+
}
13421366
| optional_arguments '*' test arguments2
1367+
{
1368+
call := $1
1369+
call.Starargs = $3
1370+
iflen($4.Args) != 0{
1371+
yylex.Error("SyntaxError: only named arguments may follow *expression")
1372+
}
1373+
call.Keywords = append(call.Keywords, $4.Keywords...)
1374+
$$ = call
1375+
}
13431376
| optional_arguments '*' test arguments2 ',' STARSTAR test
1377+
{
1378+
call := $1
1379+
call.Starargs = $3
1380+
call.Kwargs = $7
1381+
iflen($4.Args) != 0{
1382+
yylex.Error("SyntaxError: only named arguments may follow *expression")
1383+
}
1384+
call.Keywords = append(call.Keywords, $4.Keywords...)
1385+
$$ = call
1386+
}
13441387
| optional_arguments STARSTAR test
1388+
{
1389+
call := $1
1390+
call.Kwargs = $3
1391+
$$ = call
1392+
}
13451393

13461394
// The reason that keywords are test nodes instead of NAME is that using NAME
13471395
// results in an ambiguity. ast.c makes sure it's a NAME.
13481396
argument:
13491397
test
1398+
{
1399+
$$ = &ast.Call{}
1400+
$$.Args = []ast.Expr{$1}
1401+
}
13501402
| test comp_for
1403+
{
1404+
$$ = &ast.Call{}
1405+
$$.Args = []ast.Expr{
1406+
&ast.GeneratorExp{ExprBase: ast.ExprBase{$<pos>$}, Elt: $1, Generators: $2},
1407+
}
1408+
}
13511409
| test '=' test // Really [keyword '='] test
1410+
{
1411+
$$ = &ast.Call{}
1412+
test := $1
1413+
if name, ok := test.(*ast.Name); ok{
1414+
$$.Keywords = []*ast.Keyword{&ast.Keyword{Pos: name.Pos, Arg: name.Id, Value: $3}}
1415+
} else{
1416+
yylex.Error("SyntaxError: keyword can't be an expression")
1417+
}
1418+
}
13521419

13531420
comp_iter:
13541421
comp_for

‎parser/grammar_test.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ func TestGrammar(t *testing.T){
131131
{"a==(b<c)", "eval", "Expression(body=Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Compare(left=Name(id='b', ctx=Load()), ops=[Lt()], comparators=[Name(id='c', ctx=Load())])]))"},
132132
{"(a==b)<(c>d)>e", "eval", "Expression(body=Compare(left=Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]), ops=[Lt(), Gt()], comparators=[Compare(left=Name(id='c', ctx=Load()), ops=[Gt()], comparators=[Name(id='d', ctx=Load())]), Name(id='e', ctx=Load())]))"},
133133
{"a()", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None))"},
134+
{"a(b)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='b', ctx=Load())], keywords=[], starargs=None, kwargs=None))"},
135+
{"a(b,)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='b', ctx=Load())], keywords=[], starargs=None, kwargs=None))"},
136+
{"a(b,c)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='b', ctx=Load()), Name(id='c', ctx=Load())], keywords=[], starargs=None, kwargs=None))"},
137+
{"a(b,*c)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='b', ctx=Load())], keywords=[], starargs=Name(id='c', ctx=Load()), kwargs=None))"},
138+
{"a(b,*c,**d)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='b', ctx=Load())], keywords=[], starargs=Name(id='c', ctx=Load()), kwargs=Name(id='d', ctx=Load())))"},
139+
{"a(b,**c)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='b', ctx=Load())], keywords=[], starargs=None, kwargs=Name(id='c', ctx=Load())))"},
140+
{"a(a=b)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[], keywords=[keyword(arg='a', value=Name(id='b', ctx=Load()))], starargs=None, kwargs=None))"},
141+
{"a(a,a=b,*args,**kwargs)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='a', ctx=Load())], keywords=[keyword(arg='a', value=Name(id='b', ctx=Load()))], starargs=Name(id='args', ctx=Load()), kwargs=Name(id='kwargs', ctx=Load())))"},
142+
{"a(a,a=b,*args,e=f,**kwargs)", "eval", "Expression(body=Call(func=Name(id='a', ctx=Load()), args=[Name(id='a', ctx=Load())], keywords=[keyword(arg='a', value=Name(id='b', ctx=Load())), keyword(arg='e', value=Name(id='f', ctx=Load()))], starargs=Name(id='args', ctx=Load()), kwargs=Name(id='kwargs', ctx=Load())))"},
134143
{"a.b", "eval", "Expression(body=Attribute(value=Name(id='a', ctx=Load()), attr='b', ctx=Load()))"},
135144
{"a.b.c.d", "eval", "Expression(body=Attribute(value=Attribute(value=Attribute(value=Name(id='a', ctx=Load()), attr='b', ctx=Load()), attr='c', ctx=Load()), attr='d', ctx=Load()))"},
136145
{"a.b().c.d()()", "eval", "Expression(body=Call(func=Call(func=Attribute(value=Attribute(value=Call(func=Attribute(value=Name(id='a', ctx=Load()), attr='b', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None), attr='c', ctx=Load()), attr='d', ctx=Load()), args=[], keywords=[], starargs=None, kwargs=None), args=[], keywords=[], starargs=None, kwargs=None))"},

‎parser/make_grammar_test.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,17 @@
134134

135135
# trailers
136136
("a()", "eval"),
137+
("a(b)", "eval"),
138+
("a(b,)", "eval"),
139+
("a(b,c)", "eval"),
140+
("a(b,*c)", "eval"),
141+
("a(*b)", "eval"),
142+
#("a(*b,c)", "eval"), -test error
143+
("a(b,*c,**d)", "eval"),
144+
("a(b,**c)", "eval"),
145+
("a(a=b)", "eval"),
146+
("a(a,a=b,*args,**kwargs)", "eval"),
147+
("a(a,a=b,*args,e=f,**kwargs)", "eval"),
137148
("a.b", "eval"),
138149
("a.b.c.d", "eval"),
139150
("a.b().c.d()()", "eval"),

0 commit comments

Comments
(0)