compiler: support ...
variadic calls
This commit is contained in:
parent
b9171eda14
commit
057e1e2806
2 changed files with 18 additions and 5 deletions
|
@ -758,8 +758,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
}
|
}
|
||||||
// Do not swap for builtin functions.
|
// Do not swap for builtin functions.
|
||||||
if !isBuiltin {
|
if !isBuiltin {
|
||||||
if typ, ok := c.typeOf(n.Fun).(*types.Signature); ok && typ.Variadic() {
|
typ, ok := c.typeOf(n.Fun).(*types.Signature)
|
||||||
// pack variadic args into an array
|
if ok && typ.Variadic() && !n.Ellipsis.IsValid() {
|
||||||
|
// pack variadic args into an array only if last argument is not of form `...`
|
||||||
varSize := len(n.Args) - typ.Params().Len() + 1
|
varSize := len(n.Args) - typ.Params().Len() + 1
|
||||||
c.emitReverse(varSize)
|
c.emitReverse(varSize)
|
||||||
emit.Int(c.prog.BinWriter, int64(varSize))
|
emit.Int(c.prog.BinWriter, int64(varSize))
|
||||||
|
|
|
@ -186,7 +186,7 @@ func TestLocalsCount(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVariadic(t *testing.T) {
|
func TestVariadic(t *testing.T) {
|
||||||
src := `package foo
|
srcTmpl := `package foo
|
||||||
func someFunc(a int, b ...int) int {
|
func someFunc(a int, b ...int) int {
|
||||||
sum := a
|
sum := a
|
||||||
for i := range b {
|
for i := range b {
|
||||||
|
@ -195,9 +195,21 @@ func TestVariadic(t *testing.T) {
|
||||||
return sum
|
return sum
|
||||||
}
|
}
|
||||||
func Main() int {
|
func Main() int {
|
||||||
return someFunc(10, 1, 2, 3)
|
%s
|
||||||
|
return someFunc(10, %s)
|
||||||
}`
|
}`
|
||||||
eval(t, src, big.NewInt(4))
|
t.Run("Elements", func(t *testing.T) {
|
||||||
|
src := fmt.Sprintf(srcTmpl, "", "1, 2, 3")
|
||||||
|
eval(t, src, big.NewInt(4))
|
||||||
|
})
|
||||||
|
t.Run("Slice", func(t *testing.T) {
|
||||||
|
src := fmt.Sprintf(srcTmpl, "a := []int{1, 2, 3}", "a...")
|
||||||
|
eval(t, src, big.NewInt(4))
|
||||||
|
})
|
||||||
|
t.Run("Literal", func(t *testing.T) {
|
||||||
|
src := fmt.Sprintf(srcTmpl, "", "[]int{1, 2, 3}...")
|
||||||
|
eval(t, src, big.NewInt(4))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVariadicMethod(t *testing.T) {
|
func TestVariadicMethod(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue