Convert literal values to right type

This commit is contained in:
Marc Vertes
2018-11-19 10:27:54 +01:00
parent eba9ccbe29
commit 0970329031
5 changed files with 47 additions and 15 deletions

View File

@@ -10,3 +10,6 @@ func main() {
m = 9
fmt.Println(m)
}
// Output:
// September

View File

@@ -6,8 +6,9 @@ import (
)
func main() {
// t := time.Now()
t := time.Unix(1000000000, 0)
m := t.Minute()
fmt.Println(t, m)
t := time.Unix(1e9, 0)
fmt.Println(t.Minute())
}
// Output:
// 46

View File

@@ -228,15 +228,19 @@ func (interp *Interpreter) Cfg(root *Node) []*Node {
n.val = dest.val
// Propagate type
// TODO: Check that existing destination type matches source type
if n.child[1].action == Recv {
if src.action == Recv {
// Assign by reading from a receiving channel
n.gen = nop
src.findex = dest.findex // Set recv address to LHS
dest.typ = src.typ.val
} else if n.child[1].action == CompositeLit {
} else if src.action == CompositeLit {
n.gen = nop
src.findex = dest.findex
src.level = level
} else if src.kind == BasicLit {
// TODO: perform constant folding and propagation here
// Convert literal value to destination type
src.val = reflect.ValueOf(src.val).Convert(dest.typ.TypeOf())
}
n.typ = dest.typ
if sym != nil {

View File

@@ -3628,10 +3628,13 @@ func main() {
var m time.Month
m = 9
fmt.Println(m)
}`
}
`
i := NewInterpreter(Opt{Entry: "main"}, "time4.go")
i.Eval(src)
// Output:
// September
}
func Example_time5() {
@@ -3644,14 +3647,15 @@ import (
)
func main() {
// t := time.Now()
t := time.Unix(1000000000, 0)
m := t.Minute()
fmt.Println(t, m)
}`
t := time.Unix(1e9, 0)
fmt.Println(t.Minute())
}
`
i := NewInterpreter(Opt{Entry: "main"}, "time5.go")
i.Eval(src)
// Output:
// 46
}
func Example_type0() {

View File

@@ -588,13 +588,33 @@ func callBin(n *Node) {
child := n.child[1:]
value := genValue(n.child[0])
var values []func(*Frame) reflect.Value
for _, c := range child {
funcType := n.child[0].typ.rtype
variadicNum := -1
var variadicType reflect.Type
if funcType.IsVariadic() {
variadicNum = funcType.NumIn() - 1
variadicType = funcType.In(variadicNum).Elem()
}
for i, c := range child {
if isRegularCall(c) {
for i := range c.child[0].typ.ret {
ind := c.findex + i
// Handle nested function calls: pass returned values as arguments
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 {
// 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 {
c.val = reflect.ValueOf(c.val).Convert(argType)
}
}
values = append(values, genValue(c))
}
}