xgo/vm/vm_tail_call_test.go
2019-01-11 00:53:04 -08:00

85 lines
1.2 KiB
Go

package vm_test
import "testing"
func TestTailCall(t *testing.T) {
expect(t, `
fac := func(n, a) {
if n == 1 {
return a
}
return fac(n-1, n*a)
}
out = fac(5, 1)`, 120)
expect(t, `
fac := func(n, a) {
if n == 1 {
return a
}
x := {foo: fac} // indirection for test
return x.foo(n-1, n*a)
}
out = fac(5, 1)`, 120)
expect(t, `
fib := func(x, s) {
if x == 0 {
return 0 + s
} else if x == 1 {
return 1 + s
}
return fib(x-1, fib(x-2, s))
}
out = fib(15, 0)`, 610)
expect(t, `
fib := func(n, a, b) {
if n == 0 {
return a
} else if n == 1 {
return b
}
return fib(n-1, b, a + b)
}
out = fib(15, 0, 1)`, 610)
// global variable and no return value
expect(t, `
out = 0
foo := func(a) {
if a == 0 {
return
}
out += a
foo(a-1)
}
foo(10)`, 55)
expect(t, `
f1 := func() {
f2 := 0 // TODO: this might be fixed in the future
f2 = func(n, s) {
if n == 0 { return s }
return f2(n-1, n + s)
}
return f2(5, 0)
}
out = f1()`, 15)
}
// tail call with free vars
func TestTailCallFreeVars(t *testing.T) {
expect(t, `
func() {
a := 10
f2 := 0
f2 = func(n, s) {
if n == 0 {
return s + a
}
return f2(n-1, n+s)
}
out = f2(5, 0)
}()`, 25)
}