Skip to content

Commit 0079df4

Browse files
committed
Lambda and varargs
1 parent bad0904 commit 0079df4

File tree

5 files changed

+107
-31
lines changed

5 files changed

+107
-31
lines changed

ast/ast.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -650,11 +650,11 @@ type ExceptHandler struct {
650650

651651
type Arguments struct {
652652
Pos
653-
Args []Arg
654-
Vararg Arg
655-
Kwonlyargs []Arg
653+
Args []*Arg
654+
Vararg *Arg
655+
Kwonlyargs []*Arg
656656
KwDefaults []Expr
657-
Kwarg Arg
657+
Kwarg *Arg
658658
Defaults []Expr
659659
}
660660

ast/dump.go

+12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ func dumpItem(v interface{}) string {
2626
return dump(x, "keyword")
2727
case *WithItem:
2828
return dump(x, "withitem")
29+
case *Arguments:
30+
if x == nil {
31+
return "None"
32+
}
33+
return dump(x, "arguments")
34+
case *Arg:
35+
if x == nil {
36+
return "None"
37+
}
38+
return dump(x, "arg")
2939
case ModBase:
3040
case StmtBase:
3141
case ExprBase:
@@ -61,6 +71,8 @@ func dump(ast interface{}, name string) string {
6171
fname = "context_expr"
6272
case "optionalvars":
6373
fname = "optional_vars"
74+
case "kwdefaults":
75+
fname = "kw_defaults"
6476
}
6577
if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() != reflect.Uint8 {
6678
strs := make([]string, fieldValue.Len())

parser/grammar.y

+61-27
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ func setCtx(exprs []ast.Expr, ctx ast.ExprContext) {
7676
exchandlers []*ast.ExceptHandler
7777
withitem *ast.WithItem
7878
withitems []*ast.WithItem
79+
arg *ast.Arg
80+
args []*ast.Arg
81+
arguments *ast.Arguments
7982
}
8083

8184
%type <obj> strings
@@ -91,14 +94,17 @@ func setCtx(exprs []ast.Expr, ctx ast.ExprContext) {
9194
%type <slice> subscript subscriptlist subscripts
9295
%type <call> argument arguments optional_arguments arguments2
9396
%type <level> dot dots
94-
%type <str> dotted_name from_arg
97+
%type <str> dotted_name from_arg vfpdef
9598
%type <identifiers> names
9699
%type <alias> dotted_as_name import_as_name
97100
%type <aliases> dotted_as_names import_as_names import_from_arg
98101
%type <ifstmt> elifs
99102
%type <exchandlers> except_clauses
100103
%type <withitem> with_item
101104
%type <withitems> with_items
105+
%type <arg> vfpdeftest optional_vfpdef
106+
%type <args> vfpdeftests vfpdeftests1
107+
%type <arguments> varargslist
102108

103109
%token NEWLINE
104110
%token ENDMARKER
@@ -408,69 +414,94 @@ tfpdef:
408414
vfpdeftest:
409415
vfpdef
410416
{
411-
// FIXME
417+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
418+
$<expr>$ = nil
412419
}
413420
| vfpdef '=' test
414421
{
415-
// FIXME
422+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
423+
$<expr>$ = $3
416424
}
417425

418426
vfpdeftests:
419427
{
420-
// FIXME
428+
$$ = nil
429+
$<exprs>$ = nil
421430
}
422431
| vfpdeftests ',' vfpdeftest
423432
{
424-
// FIXME
433+
$$ = append($$, $3)
434+
if $<expr>3 != nil {
435+
$<exprs>$ = append($<exprs>$, $<expr>3)
436+
}
437+
}
438+
439+
vfpdeftests1:
440+
vfpdeftest
441+
{
442+
$$ = nil
443+
$$ = append($$, $1)
444+
$<exprs>$ = nil
445+
if $<expr>1 != nil {
446+
$<exprs>$ = append($<exprs>$, $<expr>1)
447+
}
448+
}
449+
| vfpdeftests1 ',' vfpdeftest
450+
{
451+
$$ = append($$, $3)
452+
if $<expr>3 != nil {
453+
$<exprs>$ = append($<exprs>$, $<expr>3)
454+
}
425455
}
426456

427457
optional_vfpdef:
428458
{
429-
// FIXME
459+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier("")}
430460
}
431461
| vfpdef
432462
{
433-
// FIXME
463+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
434464
}
435465

466+
// FIXME this isn't checking all the python rules for args before kwargs etc
436467
varargslist:
437-
vfpdeftest vfpdeftests
468+
vfpdeftests1 optional_comma
438469
{
439-
// FIXME
470+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1}
440471
}
441-
| vfpdeftest vfpdeftests ','
472+
| vfpdeftests1 ',' '*' optional_vfpdef vfpdeftests
442473
{
443-
// FIXME
474+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Vararg: $4, Kwonlyargs: $5, KwDefaults: $<exprs>5}
444475
}
445-
| vfpdeftest vfpdeftests ',' '*' optional_vfpdef vfpdeftests
476+
| vfpdeftests1 ',' '*' optional_vfpdef vfpdeftests ',' STARSTAR vfpdef
446477
{
447-
// FIXME
478+
starstar := &ast.Arg{Pos: $<pos>8, Arg: ast.Identifier($8)}
479+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Vararg: $4, Kwonlyargs: $5, KwDefaults: $<exprs>5, Kwarg: starstar}
448480
}
449-
| vfpdeftest vfpdeftests ',' '*' optional_vfpdef vfpdeftests ',' STARSTAR vfpdef
481+
| vfpdeftests1 ',' STARSTAR vfpdef
450482
{
451-
// FIXME
452-
}
453-
| vfpdeftest vfpdeftests ',' STARSTAR vfpdef
454-
{
455-
// FIXME
483+
starstar := &ast.Arg{Pos: $<pos>4, Arg: ast.Identifier($4)}
484+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Kwarg: starstar}
456485
}
457486
| '*' optional_vfpdef vfpdeftests
458487
{
459-
// FIXME
488+
$$ = &ast.Arguments{Pos: $<pos>$, Vararg: $2, Kwonlyargs: $3, KwDefaults: $<exprs>3}
460489
}
461490
| '*' optional_vfpdef vfpdeftests ',' STARSTAR vfpdef
462491
{
463-
// FIXME
492+
starstar := &ast.Arg{Pos: $<pos>6, Arg: ast.Identifier($6)}
493+
$$ = &ast.Arguments{Pos: $<pos>$, Vararg: $2, Kwonlyargs: $3, KwDefaults: $<exprs>3, Kwarg: starstar}
464494
}
465495
| STARSTAR vfpdef
466496
{
467-
// FIXME
497+
starstar := &ast.Arg{Pos: $<pos>2, Arg: ast.Identifier($2)}
498+
$$ = &ast.Arguments{Pos: $<pos>$, Kwarg: starstar}
468499
}
469500
470501
vfpdef:
471502
NAME
472503
{
473-
// FIXME
504+
$$ = $1
474505
}
475506
476507
stmt:
@@ -1161,21 +1192,24 @@ test_nocond:
11611192
lambdef:
11621193
LAMBDA ':' test
11631194
{
1164-
// FIXME
1195+
args := &ast.Arguments{Pos: $<pos>$}
1196+
$$ = &ast.Lambda{ExprBase: ast.ExprBase{$<pos>$}, Args: args, Body: $3}
11651197
}
11661198
| LAMBDA varargslist ':' test
11671199
{
1168-
// FIXME
1200+
$$ = &ast.Lambda{ExprBase: ast.ExprBase{$<pos>$}, Args: $2, Body: $4}
11691201
}
11701202

1203+
// FIXME not sure this is necessary
11711204
lambdef_nocond:
11721205
LAMBDA ':' test_nocond
11731206
{
1174-
// FIXME
1207+
args := &ast.Arguments{Pos: $<pos>$}
1208+
$$ = &ast.Lambda{ExprBase: ast.ExprBase{$<pos>$}, Args: args, Body: $3}
11751209
}
11761210
| LAMBDA varargslist ':' test_nocond
11771211
{
1178-
// FIXME
1212+
$$ = &ast.Lambda{ExprBase: ast.ExprBase{$<pos>$}, Args: $2, Body: $4}
11791213
}
11801214

11811215
or_test:

parser/grammar_test.go

+14
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,20 @@ func TestGrammar(t *testing.T) {
234234
{"a = b = c", "exec", "Module(body=[Assign(targets=[Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], value=Name(id='c', ctx=Load()))])"},
235235
{"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()))])"},
236236
{"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()))])"},
237+
{"lambda: a", "eval", "Expression(body=Lambda(args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
238+
{"lambda: lambda: a", "eval", "Expression(body=Lambda(args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Lambda(args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load()))))"},
239+
{"lambda a: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
240+
{"lambda a, b: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None), arg(arg='b', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
241+
{"lambda a, b,: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None), arg(arg='b', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
242+
{"lambda a = b: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[Name(id='b', ctx=Load())]), body=Name(id='a', ctx=Load())))"},
243+
{"lambda a, b=c: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None), arg(arg='b', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[Name(id='c', ctx=Load())]), body=Name(id='a', ctx=Load())))"},
244+
{"lambda a, *b: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None)], vararg=arg(arg='b', annotation=None), kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
245+
{"lambda a, *b, c=d: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None)], vararg=arg(arg='b', annotation=None), kwonlyargs=[arg(arg='c', annotation=None)], kw_defaults=[Name(id='d', ctx=Load())], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
246+
{"lambda a, *b, c=d, **kws: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None)], vararg=arg(arg='b', annotation=None), kwonlyargs=[arg(arg='c', annotation=None)], kw_defaults=[Name(id='d', ctx=Load())], kwarg=arg(arg='kws', annotation=None), defaults=[]), body=Name(id='a', ctx=Load())))"},
247+
{"lambda a, c=d, **kws: a", "eval", "Expression(body=Lambda(args=arguments(args=[arg(arg='a', annotation=None), arg(arg='c', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=arg(arg='kws', annotation=None), defaults=[Name(id='d', ctx=Load())]), body=Name(id='a', ctx=Load())))"},
248+
{"lambda *args, c=d: a", "eval", "Expression(body=Lambda(args=arguments(args=[], vararg=arg(arg='args', annotation=None), kwonlyargs=[arg(arg='c', annotation=None)], kw_defaults=[Name(id='d', ctx=Load())], kwarg=None, defaults=[]), body=Name(id='a', ctx=Load())))"},
249+
{"lambda *args, c=d, **kws: a", "eval", "Expression(body=Lambda(args=arguments(args=[], vararg=arg(arg='args', annotation=None), kwonlyargs=[arg(arg='c', annotation=None)], kw_defaults=[Name(id='d', ctx=Load())], kwarg=arg(arg='kws', annotation=None), defaults=[]), body=Name(id='a', ctx=Load())))"},
250+
{"lambda **kws: a", "eval", "Expression(body=Lambda(args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=arg(arg='kws', annotation=None), defaults=[]), body=Name(id='a', ctx=Load())))"},
237251
// END TESTS
238252
} {
239253
Ast, err := ParseString(test.in, test.mode)

parser/make_grammar_test.py

+16
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,22 @@
335335
("a = b = c", "exec"),
336336
("a, b = 1, 2", "exec"),
337337
("a, b = c, d = 1, 2", "exec"),
338+
339+
# lambda
340+
("lambda: a", "eval"),
341+
("lambda: lambda: a", "eval"),
342+
("lambda a: a", "eval"),
343+
("lambda a, b: a", "eval"),
344+
("lambda a, b,: a", "eval"),
345+
("lambda a = b: a", "eval"),
346+
("lambda a, b=c: a", "eval"),
347+
("lambda a, *b: a", "eval"),
348+
("lambda a, *b, c=d: a", "eval"),
349+
("lambda a, *b, c=d, **kws: a", "eval"),
350+
("lambda a, c=d, **kws: a", "eval"),
351+
("lambda *args, c=d: a", "eval"),
352+
("lambda *args, c=d, **kws: a", "eval"),
353+
("lambda **kws: a", "eval"),
338354
]
339355

340356
def dump(source, mode):

0 commit comments

Comments
 (0)