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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 84 additions & 56 deletions
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

Lines changed: 13 additions & 0 deletions
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

Lines changed: 15 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy