compiler: make use of extended JMP* opcodes
This commit is contained in:
parent
51f3baf68e
commit
9dc3edf351
2 changed files with 163 additions and 3 deletions
|
@ -1,6 +1,7 @@
|
|||
package compiler_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
@ -262,3 +263,101 @@ var binaryExprTestCases = []testCase{
|
|||
func TestBinaryExprs(t *testing.T) {
|
||||
runTestCases(t, binaryExprTestCases)
|
||||
}
|
||||
|
||||
func getBoolExprTestFunc(val bool, cond string) func(t *testing.T) {
|
||||
srcTmpl := `package foo
|
||||
var s = "str"
|
||||
var v = 9
|
||||
var cond = %s
|
||||
func Main() int {
|
||||
if %s {
|
||||
return 42
|
||||
} %s
|
||||
return 17
|
||||
%s
|
||||
}`
|
||||
res := big.NewInt(42)
|
||||
if !val {
|
||||
res.SetInt64(17)
|
||||
}
|
||||
return func(t *testing.T) {
|
||||
t.Run("AsExpression", func(t *testing.T) {
|
||||
src := fmt.Sprintf(srcTmpl, cond, "cond", "", "")
|
||||
eval(t, src, res)
|
||||
})
|
||||
t.Run("InCondition", func(t *testing.T) {
|
||||
src := fmt.Sprintf(srcTmpl, "true", cond, "", "")
|
||||
eval(t, src, res)
|
||||
})
|
||||
t.Run("InConditionWithElse", func(t *testing.T) {
|
||||
src := fmt.Sprintf(srcTmpl, "true", cond, " else {", "}")
|
||||
eval(t, src, res)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestBooleanExprs enumerates a lot of possible combinations of boolean expressions
|
||||
// and tests if the result matches to that of Go.
|
||||
func TestBooleanExprs(t *testing.T) {
|
||||
trueExpr := []string{"true", "v < 10", "v <= 9", "v > 8", "v >= 9", "v == 9", "v != 8", `s == "str"`}
|
||||
falseExpr := []string{"false", "v > 9", "v >= 10", "v < 9", "v <= 8", "v == 8", "v != 9", `s == "a"`}
|
||||
t.Run("Single", func(t *testing.T) {
|
||||
for _, s := range trueExpr {
|
||||
t.Run(s, getBoolExprTestFunc(true, s))
|
||||
}
|
||||
for _, s := range falseExpr {
|
||||
t.Run(s, getBoolExprTestFunc(false, s))
|
||||
}
|
||||
})
|
||||
|
||||
type arg struct {
|
||||
val bool
|
||||
s string
|
||||
}
|
||||
t.Run("Combine", func(t *testing.T) {
|
||||
var double []arg
|
||||
for _, e := range trueExpr {
|
||||
double = append(double, arg{true, e + " || false"})
|
||||
double = append(double, arg{true, e + " && true"})
|
||||
}
|
||||
for _, e := range falseExpr {
|
||||
double = append(double, arg{false, e + " && true"})
|
||||
double = append(double, arg{false, e + " || false"})
|
||||
}
|
||||
for i := range double {
|
||||
t.Run(double[i].s, getBoolExprTestFunc(double[i].val, double[i].s))
|
||||
}
|
||||
|
||||
var triple []arg
|
||||
for _, a1 := range double {
|
||||
for _, a2 := range double {
|
||||
triple = append(triple, arg{a1.val || a2.val, fmt.Sprintf("(%s) || (%s)", a1.s, a2.s)})
|
||||
triple = append(triple, arg{a1.val && a2.val, fmt.Sprintf("(%s) && (%s)", a1.s, a2.s)})
|
||||
}
|
||||
}
|
||||
for i := range triple {
|
||||
t.Run(triple[i].s, getBoolExprTestFunc(triple[i].val, triple[i].s))
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func TestShortCircuit(t *testing.T) {
|
||||
srcTmpl := `package foo
|
||||
var a = 1
|
||||
func inc() bool { a += 1; return %s }
|
||||
func Main() int {
|
||||
if %s {
|
||||
return 41 + a
|
||||
}
|
||||
return 16 + a
|
||||
}`
|
||||
t.Run("||", func(t *testing.T) {
|
||||
src := fmt.Sprintf(srcTmpl, "true", "a == 1 || inc()")
|
||||
eval(t, src, big.NewInt(42))
|
||||
})
|
||||
t.Run("&&", func(t *testing.T) {
|
||||
src := fmt.Sprintf(srcTmpl, "false", "a == 2 && inc()")
|
||||
eval(t, src, big.NewInt(17))
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue