2020-05-08 13:10:33 +00:00
|
|
|
package compiler_test
|
|
|
|
|
|
|
|
import (
|
2020-06-29 13:57:38 +00:00
|
|
|
"fmt"
|
2020-05-08 13:10:33 +00:00
|
|
|
"math/big"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestChangeGlobal(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
var a int
|
|
|
|
func Main() int {
|
|
|
|
setLocal()
|
|
|
|
set42()
|
|
|
|
setLocal()
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
func set42() { a = 42 }
|
|
|
|
func setLocal() { a := 10; _ = a }`
|
|
|
|
|
|
|
|
eval(t, src, big.NewInt(42))
|
|
|
|
}
|
2020-05-19 13:47:43 +00:00
|
|
|
|
|
|
|
func TestMultiDeclaration(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
var a, b, c int
|
|
|
|
func Main() int {
|
|
|
|
a = 1
|
|
|
|
b = 2
|
|
|
|
c = 3
|
|
|
|
return a + b + c
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(6))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMultiDeclarationLocal(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
func Main() int {
|
|
|
|
var a, b, c int
|
|
|
|
a = 1
|
|
|
|
b = 2
|
|
|
|
c = 3
|
|
|
|
return a + b + c
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(6))
|
|
|
|
}
|
2020-05-19 13:50:20 +00:00
|
|
|
|
|
|
|
func TestMultiDeclarationLocalCompound(t *testing.T) {
|
|
|
|
src := `package foo
|
|
|
|
func Main() int {
|
|
|
|
var a, b, c []int
|
|
|
|
a = append(a, 1)
|
|
|
|
b = append(b, 2)
|
|
|
|
c = append(c, 3)
|
|
|
|
return a[0] + b[0] + c[0]
|
|
|
|
}`
|
|
|
|
eval(t, src, big.NewInt(6))
|
|
|
|
}
|
2020-06-29 13:57:38 +00:00
|
|
|
|
|
|
|
func TestShadow(t *testing.T) {
|
|
|
|
srcTmpl := `package foo
|
|
|
|
func Main() int {
|
|
|
|
x := 1
|
|
|
|
y := 10
|
|
|
|
%s
|
|
|
|
x += 1 // increase old local
|
|
|
|
x := 30 // introduce new local
|
|
|
|
y += x // make sure is means something
|
|
|
|
}
|
|
|
|
return x+y
|
|
|
|
}`
|
|
|
|
|
|
|
|
runCase := func(b string) func(t *testing.T) {
|
|
|
|
return func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, b)
|
|
|
|
eval(t, src, big.NewInt(42))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run("If", runCase("if true {"))
|
|
|
|
t.Run("For", runCase("for i := 0; i < 1; i++ {"))
|
|
|
|
t.Run("Range", runCase("for range []int{1} {"))
|
|
|
|
t.Run("Switch", runCase("switch true {\ncase false: x += 2\ncase true:"))
|
2020-06-29 13:59:13 +00:00
|
|
|
t.Run("Block", runCase("{"))
|
2020-06-29 13:57:38 +00:00
|
|
|
}
|
2020-06-30 07:41:45 +00:00
|
|
|
|
|
|
|
func TestArgumentLocal(t *testing.T) {
|
|
|
|
srcTmpl := `package foo
|
|
|
|
func some(a int) int {
|
|
|
|
if a > 42 {
|
|
|
|
a := 24
|
|
|
|
_ = a
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
func Main() int {
|
|
|
|
return some(%d)
|
|
|
|
}`
|
|
|
|
t.Run("Override", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, 50)
|
|
|
|
eval(t, src, big.NewInt(50))
|
|
|
|
})
|
|
|
|
t.Run("NoOverride", func(t *testing.T) {
|
|
|
|
src := fmt.Sprintf(srcTmpl, 40)
|
|
|
|
eval(t, src, big.NewInt(40))
|
|
|
|
})
|
|
|
|
}
|