2019-01-09 10:17:42 +03:00
package vm_test
import (
"testing"
)
func TestFunction ( t * testing . T ) {
// function with no "return" statement returns "invalid" value.
2019-01-11 09:34:28 +03:00
expect ( t , ` f1 := func() { }; out = f1(); ` , undefined ( ) )
expect ( t , ` f1 := func() { }; f2 := func() { return f1(); }; f1(); out = f2(); ` , undefined ( ) )
expect ( t , ` f := func(x) { x; }; out = f(5); ` , undefined ( ) )
expect ( t , ` f := func(x) { return x; }; out = f(5); ` , 5 )
expect ( t , ` f := func(x) { return x * 2; }; out = f(5); ` , 10 )
expect ( t , ` f := func(x, y) { return x + y; }; out = f(5, 5); ` , 10 )
expect ( t , ` f := func(x, y) { return x + y; }; out = f(5 + 5, f(5, 5)); ` , 20 )
2019-01-09 10:17:42 +03:00
expect ( t , ` out = func(x) { return x; }(5) ` , 5 )
2019-01-11 09:34:28 +03:00
expect ( t , ` x := 10; f := func(x) { return x; }; f(5); out = x; ` , 10 )
2019-01-09 10:17:42 +03:00
expect ( t , `
2019-01-11 09:34:28 +03:00
f2 := func ( a ) {
f1 := func ( a ) {
2019-01-09 10:17:42 +03:00
return a * 2 ;
} ;
return f1 ( a ) * 3 ;
} ;
out = f2 ( 10 ) ;
` , 60 )
// closures
expect ( t , `
2019-01-11 09:34:28 +03:00
newAdder := func ( x ) {
2019-01-09 10:17:42 +03:00
return func ( y ) { return x + y } ;
} ;
2019-01-11 09:34:28 +03:00
add2 := newAdder ( 2 ) ;
2019-01-09 10:17:42 +03:00
out = add2 ( 5 ) ;
` , 7 )
// function as a argument
expect ( t , `
2019-01-11 09:34:28 +03:00
add := func ( a , b ) { return a + b } ;
sub := func ( a , b ) { return a - b } ;
applyFunc := func ( a , b , f ) { return f ( a , b ) } ;
2019-01-09 10:17:42 +03:00
out = applyFunc ( applyFunc ( 2 , 2 , add ) , 3 , sub ) ;
` , 1 )
2019-01-11 09:34:28 +03:00
expect ( t , ` f1 := func() { return 5 + 10; }; out = f1(); ` , 15 )
expect ( t , ` f1 := func() { return 1 }; f2 := func() { return 2 }; out = f1() + f2() ` , 3 )
expect ( t , ` f1 := func() { return 1 }; f2 := func() { return f1() + 2 }; f3 := func() { return f2() + 3 }; out = f3() ` , 6 )
expect ( t , ` f1 := func() { return 99; 100 }; out = f1(); ` , 99 )
expect ( t , ` f1 := func() { return 99; return 100 }; out = f1(); ` , 99 )
expect ( t , ` f1 := func() { return 33; }; f2 := func() { return f1 }; out = f2()(); ` , 33 )
expect ( t , ` one := func() { one = 1; return one }; out = one() ` , 1 )
expect ( t , ` three := func() { one := 1; two := 2; return one + two }; out = three() ` , 3 )
expect ( t , ` three := func() { one := 1; two := 2; return one + two }; seven := func() { three := 3; four := 4; return three + four }; out = three() + seven() ` , 10 )
expect ( t , `
foo1 := func ( ) {
foo := 50
return foo
}
foo2 := func ( ) {
foo := 100
return foo
}
out = foo1 ( ) + foo2 ( ) ` , 150 )
expect ( t , `
g := 50 ;
minusOne := func ( ) {
n := 1 ;
2019-01-09 10:17:42 +03:00
return g - n ;
} ;
2019-01-11 09:34:28 +03:00
minusTwo := func ( ) {
n := 2 ;
2019-01-09 10:17:42 +03:00
return g - n ;
} ;
out = minusOne ( ) + minusTwo ( )
` , 97 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( ) {
f2 := func ( ) { return 1 ; }
2019-01-09 10:17:42 +03:00
return f2
} ;
out = f1 ( ) ( )
` , 1 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a ) { return a ; } ;
2019-01-09 10:17:42 +03:00
out = f1 ( 4 ) ` , 4 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a , b ) { return a + b ; } ;
2019-01-09 10:17:42 +03:00
out = f1 ( 1 , 2 ) ` , 3 )
expect ( t , `
2019-01-11 09:34:28 +03:00
sum := func ( a , b ) {
c := a + b ;
2019-01-09 10:17:42 +03:00
return c ;
} ;
out = sum ( 1 , 2 ) ; ` , 3 )
expect ( t , `
2019-01-11 09:34:28 +03:00
sum := func ( a , b ) {
c := a + b ;
2019-01-09 10:17:42 +03:00
return c ;
} ;
out = sum ( 1 , 2 ) + sum ( 3 , 4 ) ; ` , 10 )
expect ( t , `
2019-01-11 09:34:28 +03:00
sum := func ( a , b ) {
c := a + b
2019-01-09 10:17:42 +03:00
return c
} ;
2019-01-11 09:34:28 +03:00
outer := func ( ) {
2019-01-09 10:17:42 +03:00
return sum ( 1 , 2 ) + sum ( 3 , 4 )
} ;
out = outer ( ) ; ` , 10 )
expect ( t , `
2019-01-11 09:34:28 +03:00
g := 10 ;
2019-01-09 10:17:42 +03:00
2019-01-11 09:34:28 +03:00
sum := func ( a , b ) {
c := a + b ;
2019-01-09 10:17:42 +03:00
return c + g ;
}
2019-01-11 09:34:28 +03:00
outer := func ( ) {
2019-01-09 10:17:42 +03:00
return sum ( 1 , 2 ) + sum ( 3 , 4 ) + g ;
}
out = outer ( ) + g
` , 50 )
expectError ( t , ` func() { return 1; }(1) ` )
expectError ( t , ` func(a) { return a; }() ` )
expectError ( t , ` func(a, b) { return a + b; }(1) ` )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a ) {
2019-01-09 10:17:42 +03:00
return func ( ) { return a ; } ;
} ;
2019-01-11 09:34:28 +03:00
f2 := f1 ( 99 ) ;
2019-01-09 10:17:42 +03:00
out = f2 ( )
` , 99 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a , b ) {
2019-01-09 10:17:42 +03:00
return func ( c ) { return a + b + c } ;
} ;
2019-01-11 09:34:28 +03:00
f2 := f1 ( 1 , 2 ) ;
2019-01-09 10:17:42 +03:00
out = f2 ( 8 ) ;
` , 11 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a , b ) {
c := a + b ;
2019-01-09 10:17:42 +03:00
return func ( d ) { return c + d } ;
} ;
2019-01-11 09:34:28 +03:00
f2 := f1 ( 1 , 2 ) ;
2019-01-09 10:17:42 +03:00
out = f2 ( 8 ) ;
` , 11 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a , b ) {
c := a + b ;
2019-01-09 10:17:42 +03:00
return func ( d ) {
2019-01-11 09:34:28 +03:00
e := d + c ;
2019-01-09 10:17:42 +03:00
return func ( f ) { return e + f } ;
}
} ;
2019-01-11 09:34:28 +03:00
f2 := f1 ( 1 , 2 ) ;
f3 := f2 ( 3 ) ;
2019-01-09 10:17:42 +03:00
out = f3 ( 8 ) ;
` , 14 )
expect ( t , `
2019-01-11 09:34:28 +03:00
a := 1 ;
f1 := func ( b ) {
2019-01-09 10:17:42 +03:00
return func ( c ) {
return func ( d ) { return a + b + c + d }
} ;
} ;
2019-01-11 09:34:28 +03:00
f2 := f1 ( 2 ) ;
f3 := f2 ( 3 ) ;
2019-01-09 10:17:42 +03:00
out = f3 ( 8 ) ;
` , 14 )
expect ( t , `
2019-01-11 09:34:28 +03:00
f1 := func ( a , b ) {
one := func ( ) { return a ; } ;
two := func ( ) { return b ; } ;
2019-01-09 10:17:42 +03:00
return func ( ) { return one ( ) + two ( ) ; }
} ;
2019-01-11 09:34:28 +03:00
f2 := f1 ( 9 , 90 ) ;
2019-01-09 10:17:42 +03:00
out = f2 ( ) ;
` , 99 )
// fibonacci
expect ( t , `
2019-01-11 09:34:28 +03:00
fib := func ( x ) {
2019-01-09 10:17:42 +03:00
if ( x == 0 ) {
return 0 ;
} else {
if ( x == 1 ) {
return 1 ;
} else {
return fib ( x - 1 ) + fib ( x - 2 ) ;
}
}
} ;
out = fib ( 15 ) ;
` , 610 )
}