Convert literal values to right type

This commit is contained in:
Marc Vertes
2018-11-19 13:24:55 +01:00
parent 0970329031
commit 503b1d9119
4 changed files with 90 additions and 14 deletions

12
_test/fun5.go Normal file
View File

@@ -0,0 +1,12 @@
package main
func f(i int64) {
println(i)
}
func main() {
f(34)
}
// Output:
// 34

14
_test/variadic1.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import "fmt"
func f(s string, a ...int32) {
fmt.Println(s, a)
}
func main() {
f("hello", 1, 2, 3)
}
// Output:
// hello [1 2 3]

View File

@@ -1121,6 +1121,25 @@ func main() {
// ok
}
func Example_fun5() {
src := `
package main
func f(i int64) {
println(i)
}
func main() {
f(34)
}
`
i := NewInterpreter(Opt{Entry: "main"}, "fun5.go")
i.Eval(src)
// Output:
// 34
}
func Example_goroutine() {
src := `
package main
@@ -3918,3 +3937,24 @@ func main() {
// Output:
// hello []
}
func Example_variadic1() {
src := `
package main
import "fmt"
func f(s string, a ...int32) {
fmt.Println(s, a)
}
func main() {
f("hello", 1, 2, 3)
}
`
i := NewInterpreter(Opt{Entry: "main"}, "variadic1.go")
i.Eval(src)
// Output:
// hello [1 2 3]
}

View File

@@ -450,13 +450,24 @@ func call(n *Node) {
value := genValue(n.child[0])
child := n.child[1:]
// compute input argument value functions
for _, c := range child {
for i, c := range child {
if isRegularCall(c) {
for i := range c.child[0].typ.ret {
ind := c.findex + i
for j := range c.child[0].typ.ret {
ind := c.findex + j
values = append(values, func(f *Frame) reflect.Value { return f.data[ind] })
}
} else {
if c.kind == BasicLit {
var argType reflect.Type
if variadic >= 0 && i >= variadic {
argType = n.child[0].typ.arg[variadic].TypeOf()
} else {
argType = n.child[0].typ.arg[i].TypeOf()
}
if argType != nil && argType.Kind() != reflect.Interface {
c.val = reflect.ValueOf(c.val).Convert(argType)
}
}
values = append(values, genValue(c))
}
}
@@ -589,12 +600,9 @@ func callBin(n *Node) {
value := genValue(n.child[0])
var values []func(*Frame) reflect.Value
funcType := n.child[0].typ.rtype
variadicNum := -1
var variadicType reflect.Type
variadic := -1
if funcType.IsVariadic() {
variadicNum = funcType.NumIn() - 1
variadicType = funcType.In(variadicNum).Elem()
variadic = funcType.NumIn() - 1
}
for i, c := range child {
@@ -606,12 +614,14 @@ func callBin(n *Node) {
}
} else {
if c.kind == BasicLit {
// Convert literal value (untyped) to function argument type
if variadicNum >= 0 {
if i >= variadicNum && variadicType.Kind() != reflect.Interface {
c.val = reflect.ValueOf(c.val).Convert(variadicType)
}
} else if argType := funcType.In(i); argType.Kind() != reflect.Interface {
// Convert literal value (untyped) to function argument type (if not an interface{})
var argType reflect.Type
if variadic >= 0 && i >= variadic {
argType = funcType.In(variadic).Elem()
} else {
argType = funcType.In(i)
}
if argType != nil && argType.Kind() != reflect.Interface {
c.val = reflect.ValueOf(c.val).Convert(argType)
}
}