Handle branching in boolean functions

This commit is contained in:
Marc Vertes
2018-11-29 16:36:21 +01:00
parent 65933b2441
commit a0b659fa8a
4 changed files with 115 additions and 8 deletions

22
_test/and0.go Normal file
View File

@@ -0,0 +1,22 @@
package main
func main() {
a, b := 1, 2
if f2() && f1() {
println(a, b)
}
}
func f1() bool {
println("f1")
return true
}
func f2() bool {
println("f2")
return false
}
// Output:
// f2

20
_test/and1.go Normal file
View File

@@ -0,0 +1,20 @@
package main
func main() {
a := f2() && f1()
println(a)
}
func f1() bool {
println("f1")
return true
}
func f2() bool {
println("f2")
return false
}
// Output:
// f2
// false

View File

@@ -431,6 +431,62 @@ func f2() bool {
// f2
}
func Example_and0() {
src := `
package main
func main() {
a, b := 1, 2
if f2() && f1() {
println(a, b)
}
}
func f1() bool {
println("f1")
return true
}
func f2() bool {
println("f2")
return false
}
`
i := NewInterpreter(Opt{Entry: "main"}, "and0.go")
i.Eval(src)
// Output:
// f2
}
func Example_and1() {
src := `
package main
func main() {
a := f2() && f1()
println(a)
}
func f1() bool {
println("f1")
return true
}
func f2() bool {
println("f2")
return false
}
`
i := NewInterpreter(Opt{Entry: "main"}, "and1.go")
i.Eval(src)
// Output:
// f2
// false
}
func Example_assign() {
src := `
package main

View File

@@ -325,7 +325,6 @@ func genNodeWrapper(n *Node) func(*Frame) reflect.Value {
}
}
// FIXME: handle case where func return a boolean
func call(n *Node) {
goroutine := n.anc.kind == GoStmt
method := n.child[0].recv != nil
@@ -335,9 +334,10 @@ func call(n *Node) {
values = append(values, genValueRecv(n.child[0]))
}
variadic := variadicPos(n)
next := getExec(n.tnext)
value := genValue(n.child[0])
child := n.child[1:]
tnext := getExec(n.tnext)
fnext := getExec(n.fnext)
// compute input argument value functions
for i, c := range child {
@@ -416,15 +416,24 @@ func call(n *Node) {
// Execute function body
if goroutine {
go runCfg(def.child[3].start, &nf)
return tnext
} else {
runCfg(def.child[3].start, &nf)
// Propagate return values to caller frame
//log.Println(n.index, "call rets:", ret, nf.data[:len(ret)])
for i, r := range ret {
f.data[r] = nf.data[i]
}
}
return next
// Handle branching according to boolean result
if fnext != nil {
if nf.data[0].Bool() {
return tnext
}
return fnext
}
// Propagate return values to caller frame
//log.Println(n.index, "call rets:", ret, nf.data[:len(ret)])
for i, r := range ret {
f.data[r] = nf.data[i]
}
return tnext
}
}