diff options
author | Alan Donovan <alan@alandonovan.net> | 2019-02-13 19:18:15 -0500 |
---|---|---|
committer | alandonovan <adonovan@google.com> | 2019-02-13 19:18:15 -0500 |
commit | 52153852d546514d9bf61e444fe5d829f3835476 (patch) | |
tree | a015da6c381e6aa3f44ad7487e25ab7f1356736d /internal/compile/compile.go | |
parent | 266cd6fde1b6d00f056929eb7d04fee53640b3e6 (diff) | |
download | starlark-go-52153852d546514d9bf61e444fe5d829f3835476.tar.gz |
Support keyword-only function parameters (#143)
Following a hitherto undocumented feature of Skylark-in-Java,
which in turn follows Python3,
a function declaration may now include optional parameters
after the *args parameter:
```
def f(a, b, c=1, *args, d=2, **kwargs)
```
The parameter d is a "keyword-only" parameter as it can
never by assigned from a positional parameter; all positional
arguments surplus to a, b, and c are put in a tuple and
assigned to args.
To declare a non-variadic function with keyword-only arguments,
the *args parameter is replaced by just *:
```
def f(a, b, c=1, *, d=2, **kwargs)
```
The * parameter is not a real parameter; it just serves as a
separator between the parameter that may be specified positionally
and the keyword-only ones.
Spec proposal at bazelbuild/starlark#23
Fixes #61
Diffstat (limited to 'internal/compile/compile.go')
-rw-r--r-- | internal/compile/compile.go | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/internal/compile/compile.go b/internal/compile/compile.go index 6b43fbe..b313a5c 100644 --- a/internal/compile/compile.go +++ b/internal/compile/compile.go @@ -37,7 +37,7 @@ import ( const debug = false // TODO(adonovan): use a bitmap of options; and regexp to match files // Increment this to force recompilation of saved bytecode files. -const Version = 5 +const Version = 6 type Opcode uint8 @@ -305,10 +305,11 @@ type Funcode struct { Doc string // docstring of this function Code []byte // the byte code pclinetab []uint16 // mapping from pc to linenum - Locals []Ident // for error messages and tracing + Locals []Ident // locals, parameters first Freevars []Ident // for tracing MaxStack int NumParams int + NumKwonlyParams int HasVarargs, HasKwargs bool } @@ -1705,7 +1706,14 @@ func (fcomp *fcomp) function(pos syntax.Position, name string, f *syntax.Functio fmt.Fprintf(os.Stderr, "resuming %s @ %s\n", fcomp.fn.Name, fcomp.pos) } - funcode.NumParams = len(f.Params) + // def f(a, *, b=1) has only 2 parameters. + numParams := len(f.Params) + if f.NumKwonlyParams > 0 && !f.HasVarargs { + numParams-- + } + + funcode.NumParams = numParams + funcode.NumKwonlyParams = f.NumKwonlyParams funcode.HasVarargs = f.HasVarargs funcode.HasKwargs = f.HasKwargs fcomp.emit1(MAKEFUNC, fcomp.pcomp.functionIndex(funcode)) |