Skip to content

Commit 6ae1b00

Browse files
committed
Function definitions
1 parent 0079df4 commit 6ae1b00

File tree

4 files changed

+114
-56
lines changed

4 files changed

+114
-56
lines changed

ast/dump.go

+2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ func dump(ast interface{}, name string) string {
7373
fname = "optional_vars"
7474
case "kwdefaults":
7575
fname = "kw_defaults"
76+
case "decoratorlist":
77+
fname = "decorator_list"
7678
}
7779
if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() != reflect.Uint8 {
7880
strs := make([]string, fieldValue.Len())

parser/grammar.y

+84-56
Original file line numberDiff line numberDiff line change
@@ -84,27 +84,27 @@ func setCtx(exprs []ast.Expr, ctx ast.ExprContext) {
8484
%type <obj> strings
8585
%type <mod> inputs file_input single_input eval_input
8686
%type <stmts> simple_stmt stmt nl_or_stmt small_stmts stmts suite optional_else
87-
%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
87+
%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 funcdef classdef classdef_or_funcdef decorated
8888
%type <op> augassign
89-
%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
90-
%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
89+
%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 optional_return_type decorator
90+
%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 decorators
9191
%type <cmpop> comp_op
9292
%type <comma> optional_comma
9393
%type <comprehensions> comp_for
9494
%type <slice> subscript subscriptlist subscripts
9595
%type <call> argument arguments optional_arguments arguments2
9696
%type <level> dot dots
97-
%type <str> dotted_name from_arg vfpdef
97+
%type <str> dotted_name from_arg
9898
%type <identifiers> names
9999
%type <alias> dotted_as_name import_as_name
100100
%type <aliases> dotted_as_names import_as_names import_from_arg
101101
%type <ifstmt> elifs
102102
%type <exchandlers> except_clauses
103103
%type <withitem> with_item
104104
%type <withitems> with_items
105-
%type <arg> vfpdeftest optional_vfpdef
106-
%type <args> vfpdeftests vfpdeftests1
107-
%type <arguments> varargslist
105+
%type <arg> vfpdeftest vfpdef optional_vfpdef tfpdeftest tfpdef optional_tfpdef
106+
%type <args> vfpdeftests vfpdeftests1 tfpdeftests tfpdeftests1
107+
%type <arguments> varargslist parameters optional_typedargslist typedargslist
108108

109109
%token NEWLINE
110110
%token ENDMARKER
@@ -285,141 +285,172 @@ decorator:
285285
decorators:
286286
decorator
287287
{
288-
// FIXME
288+
$$ = nil
289+
$$ = append($$, $1)
289290
}
290291
| decorators decorator
291292
{
292-
// FIXME
293+
$$ = append($$, $2)
293294
}
294295

295296
classdef_or_funcdef:
296297
classdef
297298
{
298-
// FIXME
299+
$$ = $1
299300
}
300301
| funcdef
301302
{
302-
// FIXME
303+
$$ = $1
303304
}
304305

305306
decorated:
306307
decorators classdef_or_funcdef
307308
{
308-
// FIXME
309+
switch x := ($2).(type) {
310+
case *ast.ClassDef:
311+
x.DecoratorList = $1
312+
$$ = x
313+
case *ast.FunctionDef:
314+
x.DecoratorList = $1
315+
$$ = x
316+
default:
317+
panic("bad type for decorated")
318+
}
309319
}
310320

311321
optional_return_type:
312322
{
313-
// FIXME
323+
$$ = nil
314324
}
315325
| MINUSGT test
316326
{
317-
// FIXME
327+
$$ = $2
318328
}
319329

320330
funcdef:
321331
DEF NAME parameters optional_return_type ':' suite
322332
{
323-
// FIXME
333+
$$ = &ast.FunctionDef{StmtBase: ast.StmtBase{$<pos>$}, Name: ast.Identifier($2), Args: $3, Body: $6, Returns: $4}
324334
}
325335

326336
parameters:
327337
'(' optional_typedargslist ')'
328338
{
329-
// FIXME
339+
$$ = $2
330340
}
331341

332342
optional_typedargslist:
333343
{
334-
// FIXME
344+
$$ = &ast.Arguments{Pos: $<pos>$}
335345
}
336346
| typedargslist
337347
{
338-
// FIXME
348+
$$ = $1
339349
}
340350

341351
// (',' tfpdef ['=' test])*
342352
tfpdeftest:
343353
tfpdef
344354
{
345-
// FIXME
355+
$$ = $1
356+
$<expr>$ = nil
346357
}
347358
| tfpdef '=' test
348359
{
349-
// FIXME
360+
$$ = $1
361+
$<expr>$ = $3
350362
}
351363

352364
tfpdeftests:
353365
{
354-
// FIXME
366+
$$ = nil
367+
$<exprs>$ = nil
355368
}
356369
| tfpdeftests ',' tfpdeftest
357370
{
358-
// FIXME
371+
$$ = append($$, $3)
372+
if $<expr>3 != nil {
373+
$<exprs>$ = append($<exprs>$, $<expr>3)
374+
}
375+
}
376+
377+
tfpdeftests1:
378+
tfpdeftest
379+
{
380+
$$ = nil
381+
$$ = append($$, $1)
382+
$<exprs>$ = nil
383+
if $<expr>1 != nil {
384+
$<exprs>$ = append($<exprs>$, $<expr>1)
385+
}
386+
}
387+
| tfpdeftests1 ',' tfpdeftest
388+
{
389+
$$ = append($$, $3)
390+
if $<expr>3 != nil {
391+
$<exprs>$ = append($<exprs>$, $<expr>3)
392+
}
359393
}
360394

361395
optional_tfpdef:
362396
{
363-
// FIXME
397+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier("")}
364398
}
365399
| tfpdef
366400
{
367-
// FIXME
401+
$$ = $1
368402
}
369403

404+
// FIXME this isn't checking all the python rules for args before kwargs etc
370405
typedargslist:
371-
tfpdeftest tfpdeftests
372-
{
373-
// FIXME
374-
}
375-
| tfpdeftest tfpdeftests ','
406+
tfpdeftests1 optional_comma
376407
{
377-
// FIXME
408+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1}
378409
}
379-
| tfpdeftest tfpdeftests ',' '*' optional_tfpdef tfpdeftests
410+
| tfpdeftests1 ',' '*' optional_tfpdef tfpdeftests
380411
{
381-
// FIXME
412+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Vararg: $4, Kwonlyargs: $5, KwDefaults: $<exprs>5}
382413
}
383-
| tfpdeftest tfpdeftests ',' '*' optional_tfpdef tfpdeftests ',' STARSTAR tfpdef
414+
| tfpdeftests1 ',' '*' optional_tfpdef tfpdeftests ',' STARSTAR tfpdef
384415
{
385-
// FIXME
416+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Vararg: $4, Kwonlyargs: $5, KwDefaults: $<exprs>5, Kwarg: $8}
386417
}
387-
| tfpdeftest tfpdeftests ',' STARSTAR tfpdef
418+
| tfpdeftests1 ',' STARSTAR tfpdef
388419
{
389-
// FIXME
420+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Kwarg: $4}
390421
}
391422
| '*' optional_tfpdef tfpdeftests
392423
{
393-
// FIXME
424+
$$ = &ast.Arguments{Pos: $<pos>$, Vararg: $2, Kwonlyargs: $3, KwDefaults: $<exprs>3}
394425
}
395426
| '*' optional_tfpdef tfpdeftests ',' STARSTAR tfpdef
396427
{
397-
// FIXME
428+
$$ = &ast.Arguments{Pos: $<pos>$, Vararg: $2, Kwonlyargs: $3, KwDefaults: $<exprs>3, Kwarg: $6}
398429
}
399430
| STARSTAR tfpdef
400431
{
401-
// FIXME
432+
$$ = &ast.Arguments{Pos: $<pos>$, Kwarg: $2}
402433
}
403434

404435
tfpdef:
405436
NAME
406437
{
407-
// FIXME
438+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
408439
}
409440
| NAME ':' test
410441
{
411-
// FIXME
442+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1), Annotation: $3}
412443
}
413444

414445
vfpdeftest:
415446
vfpdef
416447
{
417-
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
448+
$$ = $1
418449
$<expr>$ = nil
419450
}
420451
| vfpdef '=' test
421452
{
422-
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
453+
$$ = $1
423454
$<expr>$ = $3
424455
}
425456

@@ -460,7 +491,7 @@ optional_vfpdef:
460491
}
461492
| vfpdef
462493
{
463-
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
494+
$$ = $1
464495
}
465496

466497
// FIXME this isn't checking all the python rules for args before kwargs etc
@@ -475,33 +506,29 @@ varargslist:
475506
}
476507
| vfpdeftests1 ',' '*' optional_vfpdef vfpdeftests ',' STARSTAR vfpdef
477508
{
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}
509+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Vararg: $4, Kwonlyargs: $5, KwDefaults: $<exprs>5, Kwarg: $8}
480510
}
481511
| vfpdeftests1 ',' STARSTAR vfpdef
482512
{
483-
starstar := &ast.Arg{Pos: $<pos>4, Arg: ast.Identifier($4)}
484-
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Kwarg: starstar}
513+
$$ = &ast.Arguments{Pos: $<pos>$, Args: $1, Defaults: $<exprs>1, Kwarg: $4}
485514
}
486515
| '*' optional_vfpdef vfpdeftests
487516
{
488517
$$ = &ast.Arguments{Pos: $<pos>$, Vararg: $2, Kwonlyargs: $3, KwDefaults: $<exprs>3}
489518
}
490519
| '*' optional_vfpdef vfpdeftests ',' STARSTAR vfpdef
491520
{
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}
521+
$$ = &ast.Arguments{Pos: $<pos>$, Vararg: $2, Kwonlyargs: $3, KwDefaults: $<exprs>3, Kwarg: $6}
494522
}
495523
| STARSTAR vfpdef
496524
{
497-
starstar := &ast.Arg{Pos: $<pos>2, Arg: ast.Identifier($2)}
498-
$$ = &ast.Arguments{Pos: $<pos>$, Kwarg: starstar}
525+
$$ = &ast.Arguments{Pos: $<pos>$, Kwarg: $2}
499526
}
500527

501528
vfpdef:
502529
NAME
503530
{
504-
$$ = $1
531+
$$ = &ast.Arg{Pos: $<pos>$, Arg: ast.Identifier($1)}
505532
}
506533

507534
stmt:
@@ -997,15 +1024,15 @@ compound_stmt:
9971024
}
9981025
| funcdef
9991026
{
1000-
// FIXME
1027+
$$ = $1
10011028
}
10021029
| classdef
10031030
{
1004-
// FIXME
1031+
$$ = $1
10051032
}
10061033
| decorated
10071034
{
1008-
// FIXME
1035+
$$ = $1
10091036
}
10101037

10111038
elifs:
@@ -1737,6 +1764,7 @@ classdef:
17371764
CLASS NAME optional_arglist_call ':' suite
17381765
{
17391766
// FIXME
1767+
// $$ = &ast.ClassDef{StmtBase: ast.StmtBase{$<pos>$}, Name: ast.Identifier($2), Args: $3, Body: $5}
17401768
}
17411769

17421770
arguments:

parser/grammar_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,19 @@ func TestGrammar(t *testing.T) {
248248
{"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())))"},
249249
{"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())))"},
250250
{"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())))"},
251+
{"def fn(): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Pass()], decorator_list=[], returns=None)])"},
252+
{"def fn(a): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[arg(arg='a', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Pass()], decorator_list=[], returns=None)])"},
253+
{"def fn(a, b): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[arg(arg='a', annotation=None), arg(arg='b', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Pass()], decorator_list=[], returns=None)])"},
254+
{"def fn(a, b,): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[arg(arg='a', annotation=None), arg(arg='b', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Pass()], decorator_list=[], returns=None)])"},
255+
{"def fn(a = b): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[arg(arg='a', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[Name(id='b', ctx=Load())]), body=[Pass()], decorator_list=[], returns=None)])"},
256+
{"def fn(a, b=c): pass", "exec", "Module(body=[FunctionDef(name='fn', 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=[Pass()], decorator_list=[], returns=None)])"},
257+
{"def fn(a, *b): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[arg(arg='a', annotation=None)], vararg=arg(arg='b', annotation=None), kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Pass()], decorator_list=[], returns=None)])"},
258+
{"def fn(a, *b, c=d): pass", "exec", "Module(body=[FunctionDef(name='fn', 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=[Pass()], decorator_list=[], returns=None)])"},
259+
{"def fn(a, *b, c=d, **kws): pass", "exec", "Module(body=[FunctionDef(name='fn', 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=[Pass()], decorator_list=[], returns=None)])"},
260+
{"def fn(a, c=d, **kws): pass", "exec", "Module(body=[FunctionDef(name='fn', 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=[Pass()], decorator_list=[], returns=None)])"},
261+
{"def fn(*args, c=d): pass", "exec", "Module(body=[FunctionDef(name='fn', 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=[Pass()], decorator_list=[], returns=None)])"},
262+
{"def fn(*args, c=d, **kws): pass", "exec", "Module(body=[FunctionDef(name='fn', 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=[Pass()], decorator_list=[], returns=None)])"},
263+
{"def fn(**kws): pass", "exec", "Module(body=[FunctionDef(name='fn', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=arg(arg='kws', annotation=None), defaults=[]), body=[Pass()], decorator_list=[], returns=None)])"},
251264
// END TESTS
252265
} {
253266
Ast, err := ParseString(test.in, test.mode)

parser/make_grammar_test.py

+15
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,21 @@
351351
("lambda *args, c=d: a", "eval"),
352352
("lambda *args, c=d, **kws: a", "eval"),
353353
("lambda **kws: a", "eval"),
354+
355+
# function
356+
("def fn(): pass", "exec"),
357+
("def fn(a): pass", "exec"),
358+
("def fn(a, b): pass", "exec"),
359+
("def fn(a, b,): pass", "exec"),
360+
("def fn(a = b): pass", "exec"),
361+
("def fn(a, b=c): pass", "exec"),
362+
("def fn(a, *b): pass", "exec"),
363+
("def fn(a, *b, c=d): pass", "exec"),
364+
("def fn(a, *b, c=d, **kws): pass", "exec"),
365+
("def fn(a, c=d, **kws): pass", "exec"),
366+
("def fn(*args, c=d): pass", "exec"),
367+
("def fn(*args, c=d, **kws): pass", "exec"),
368+
("def fn(**kws): pass", "exec"),
354369
]
355370

356371
def dump(source, mode):

0 commit comments

Comments
 (0)