aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeng-Ying Yang <garfield@dexon.org>2019-02-23 10:52:14 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:44:04 +0800
commit3fef4167b90d8340f53f89cfc12f270fab865aac (patch)
treea96f9d62cb25692a4ffc95bf8548d91e2754163e
parent8115f8c82f95e6581361fcd7e2d838406517ea4f (diff)
downloaddexon-3fef4167b90d8340f53f89cfc12f270fab865aac.tar.gz
dexon-3fef4167b90d8340f53f89cfc12f270fab865aac.tar.zst
dexon-3fef4167b90d8340f53f89cfc12f270fab865aac.zip
core: vm: sqlvm: add op testcases with template
We reduce code of funtion call and nested struct initialization by generating testcases with go template system. Run `go run cmd/gen-op-test/main.go` first before testing instructions, and commit generated code for fully testing on CI.
-rw-r--r--core/vm/sqlvm/cmd/gen-op-test/main.go21
-rw-r--r--core/vm/sqlvm/runtime/instructions_op_test.go3110
-rw-r--r--core/vm/sqlvm/runtime/instructions_test.go61
-rw-r--r--core/vm/sqlvm/runtime/instructions_tmpl.go82
-rw-r--r--core/vm/sqlvm/runtime/instructions_tmpl_data.go2934
-rw-r--r--core/vm/sqlvm/runtime/runtime.go8
6 files changed, 6207 insertions, 9 deletions
diff --git a/core/vm/sqlvm/cmd/gen-op-test/main.go b/core/vm/sqlvm/cmd/gen-op-test/main.go
new file mode 100644
index 000000000..60387dddf
--- /dev/null
+++ b/core/vm/sqlvm/cmd/gen-op-test/main.go
@@ -0,0 +1,21 @@
+package main
+
+import (
+ "flag"
+
+ "github.com/dexon-foundation/dexon/core/vm/sqlvm/runtime"
+)
+
+func main() {
+ var output string
+ flag.StringVar(
+ &output, "o", "./runtime/instructions_op_test.go",
+ "the output path of generated testcases",
+ )
+ flag.Parse()
+
+ err := runtime.RenderOpTest(output)
+ if err != nil {
+ panic(err)
+ }
+}
diff --git a/core/vm/sqlvm/runtime/instructions_op_test.go b/core/vm/sqlvm/runtime/instructions_op_test.go
new file mode 100644
index 000000000..f18fb0181
--- /dev/null
+++ b/core/vm/sqlvm/runtime/instructions_op_test.go
@@ -0,0 +1,3110 @@
+// Code generated - DO NOT EDIT.
+
+package runtime
+
+import (
+ "github.com/dexon-foundation/decimal"
+
+ "github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
+ "github.com/dexon-foundation/dexon/core/vm/sqlvm/errors"
+)
+
+func (s *instructionSuite) TestOpAdd() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(3)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(4)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(20)}},
+ {&Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(13)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate 2",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Overflow - Immediate",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(127)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Overflow None Immediate",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(126)}},
+ {&Raw{Value: decimal.NewFromFloat(126)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Underflow - Immediate",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-128)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeUnderflow,
+ },
+ {
+ "Underflow None Immediate",
+ Instruction{
+ Op: ADD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-127)}},
+ {&Raw{Value: decimal.NewFromFloat(-127)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeUnderflow,
+ },
+ }
+
+ s.run(testcases, opAdd)
+}
+
+func (s *instructionSuite) TestOpSub() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(3)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-4)}},
+ {&Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(7)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(9)}, &Raw{Value: decimal.NewFromFloat(12)}, &Raw{Value: decimal.NewFromFloat(20)}},
+ {&Raw{Value: decimal.NewFromFloat(-11)}, &Raw{Value: decimal.NewFromFloat(-8)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate 2",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}},
+ {&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-4)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Overflow - Immediate",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(127)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Overflow None Immediate",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(126)}},
+ {&Raw{Value: decimal.NewFromFloat(126)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Underflow - Immediate",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-128)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeUnderflow,
+ },
+ {
+ "Underflow None Immediate",
+ Instruction{
+ Op: SUB,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-127)}},
+ {&Raw{Value: decimal.NewFromFloat(-127)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeUnderflow,
+ },
+ }
+
+ s.run(testcases, opSub)
+}
+
+func (s *instructionSuite) TestOpMul() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-4)}, &Raw{Value: decimal.NewFromFloat(-100)}},
+ {&Raw{Value: decimal.NewFromFloat(100)}, &Raw{Value: decimal.NewFromFloat(100)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate - 2",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Overflow - Immediate",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(127)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Overflow None Immediate",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(126)}},
+ {&Raw{Value: decimal.NewFromFloat(126)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Underflow - Immediate",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-128)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeUnderflow,
+ },
+ {
+ "Underflow None Immediate",
+ Instruction{
+ Op: MUL,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-127)}},
+ {&Raw{Value: decimal.NewFromFloat(-127)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeUnderflow,
+ },
+ }
+
+ s.run(testcases, opMul)
+}
+
+func (s *instructionSuite) TestOpDiv() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}},
+ {&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}},
+ {&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}},
+ {&Raw{Value: decimal.NewFromFloat(6)}, &Raw{Value: decimal.NewFromFloat(-6)}},
+ {&Raw{Value: decimal.NewFromFloat(-6)}, &Raw{Value: decimal.NewFromFloat(6)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate 2",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(50)}, &Raw{Value: decimal.NewFromFloat(-50)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(9)}, &Raw{Value: decimal.NewFromFloat(9)}},
+ {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-9)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}},
+ {&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}},
+ {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}},
+ {&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "DivideByZero Immediate",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeDividedByZero,
+ },
+ {
+ "DivideByZero None Immediate",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeDividedByZero,
+ },
+ {
+ "Overflow - Immediate",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(-128)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ {
+ "Overflow None Immediate",
+ Instruction{
+ Op: DIV,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-128)}},
+ {&Raw{Value: decimal.NewFromFloat(-128)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(-2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeOverflow,
+ },
+ }
+
+ s.run(testcases, opDiv)
+}
+
+func (s *instructionSuite) TestOpMod() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: MOD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(3)}},
+ {&Raw{Value: decimal.NewFromFloat(-3)}, &Raw{Value: decimal.NewFromFloat(-3)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: MOD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}},
+ {&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(-3)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate - 2",
+ Instruction{
+ Op: MOD,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(31)}, &Raw{Value: decimal.NewFromFloat(-31)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}},
+ {&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}},
+ {&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}},
+ {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "ModideByZero Immediate",
+ Instruction{
+ Op: MOD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeDividedByZero,
+ },
+ {
+ "ModideByZero None Immediate",
+ Instruction{
+ Op: MOD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ {&Raw{Value: decimal.NewFromFloat(10)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeDividedByZero,
+ },
+ }
+
+ s.run(testcases, opMod)
+}
+
+func (s *instructionSuite) TestOpLt() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: LT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawTrue, rawTrue},
+ {rawFalse, rawFalse, rawTrue},
+ {rawFalse, rawFalse, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: LT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawFalse, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate - 2",
+ Instruction{
+ Op: LT,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opLt)
+}
+
+func (s *instructionSuite) TestOpGt() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: GT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawFalse, rawFalse},
+ {rawTrue, rawFalse, rawFalse},
+ {rawTrue, rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: GT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate - 2",
+ Instruction{
+ Op: GT,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawFalse, rawTrue},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opGt)
+}
+
+func (s *instructionSuite) TestOpEq() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: EQ,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue, rawTrue},
+ {rawTrue, rawFalse, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: EQ,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue, rawTrue},
+ {rawTrue, rawFalse, rawFalse},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opEq)
+}
+
+func (s *instructionSuite) TestOpAnd() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: AND,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: AND,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate - 2",
+ Instruction{
+ Op: AND,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Invalid Data Type",
+ Instruction{
+ Op: AND,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeInvalidDataType,
+ },
+ }
+
+ s.run(testcases, opAnd)
+}
+
+func (s *instructionSuite) TestOpOr() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: OR,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawFalse, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate",
+ Instruction{
+ Op: OR,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawTrue, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Immediate - 2",
+ Instruction{
+ Op: OR,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawTrue, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Invalid Data Type",
+ Instruction{
+ Op: OR,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeInvalidDataType,
+ },
+ }
+
+ s.run(testcases, opOr)
+}
+
+func (s *instructionSuite) TestOpNot() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: NOT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawTrue},
+ {rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Errors Invalid Data Type",
+ Instruction{
+ Op: NOT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeInvalidDataType,
+ },
+ }
+
+ s.run(testcases, opNot)
+}
+
+func (s *instructionSuite) TestOpUnion() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: UNION,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawFalse},
+ {rawFalse, rawTrue},
+ {rawTrue, rawFalse},
+ {rawTrue, rawTrue},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opUnion)
+}
+
+func (s *instructionSuite) TestOpIntxn() {
+ testcases := []opTestcase{
+ {
+ "None Immediate",
+ Instruction{
+ Op: INTXN,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawFalse, rawFalse},
+ {rawTrue, rawTrue},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opIntxn)
+}
+
+func (s *instructionSuite) TestOpLike() {
+ testcases := []opTestcase{
+ {
+ "Like %\\%b% escape \\",
+ Instruction{
+ Op: LIKE,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("a%bcdefg")}, &Raw{Bytes: []byte("gfedcba")}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("%\\%b%")}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("\\")}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Like t1 escape t2",
+ Instruction{
+ Op: LIKE,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("a%bcdefg")}},
+ {&Raw{Bytes: []byte("gfedcba")}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("%\\%b%")}},
+ {&Raw{Bytes: []byte("_fed%")}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("\\")}},
+ {&Raw{Bytes: []byte("")}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue},
+ {rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Like with valid and invalid UTF8",
+ Instruction{
+ Op: LIKE,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{226, 40, 161, 228, 189, 160, 229, 165, 189}}, &Raw{Bytes: []byte("gfedcba")}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{37, 228, 189, 160, 37}}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opLike)
+}
+
+func (s *instructionSuite) TestOpZip() {
+ testcases := []opTestcase{
+ {
+ "Zip two array",
+ Instruction{
+ Op: ZIP,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}},
+ {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "Zip immediate",
+ Instruction{
+ Op: ZIP,
+ Input: []*Operand{
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opZip)
+}
+
+func (s *instructionSuite) TestOpField() {
+ testcases := []opTestcase{
+ {
+ "Retrieve 2nd,3rd column",
+ Instruction{
+ Op: FIELD,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opField)
+}
+
+func (s *instructionSuite) TestOpPrune() {
+ testcases := []opTestcase{
+ {
+ "Prune 2nd,4th,5th column",
+ Instruction{
+ Op: PRUNE,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse, rawTrue},
+ {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue, rawFalse},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(4)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Value: decimal.NewFromFloat(1)}},
+ {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opPrune)
+}
+
+func (s *instructionSuite) TestOpFilter() {
+ testcases := []opTestcase{
+ {
+ "Filter first 2 rows",
+ Instruction{
+ Op: FILTER,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue},
+ {rawTrue},
+ {rawFalse},
+ {rawFalse},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ {rawFalse, rawTrue},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opFilter)
+}
+
+func (s *instructionSuite) TestOpCast() {
+ testcases := []opTestcase{
+ {
+ "None Immediate - int",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(127)}, &Raw{Value: decimal.NewFromFloat(127)}},
+ {&Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Value: decimal.NewFromFloat(-128)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 2),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 2),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(127)}, &Raw{Value: decimal.NewFromFloat(127)}},
+ {&Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Value: decimal.NewFromFloat(-128)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - int2",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - int3",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}},
+ {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawTrue},
+ {rawFalse, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - int4",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1), ast.ComposeDataType(3, 0),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1), ast.ComposeDataType(3, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0x80, 0x00}}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - uint",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(128)}, &Raw{Value: decimal.NewFromFloat(128)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(5, 0), ast.ComposeDataType(5, 2),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 0), ast.ComposeDataType(5, 2),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(128)}, &Raw{Value: decimal.NewFromFloat(128)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - uint2",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(6, 1),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(6, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Bytes: []byte{0x80, 0x00}}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - uint3",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue, rawFalse},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - uint4",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{0x00, 0x00}}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - uint5",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(3, 1),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(3, 1),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7f, 0xff}}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - bytes",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0xff, 0xff}}, &Raw{Bytes: []byte{0xff, 0xff}}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(6, 0), ast.ComposeDataType(6, 2),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(6, 0), ast.ComposeDataType(6, 2),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0xff}}, &Raw{Bytes: []byte{0xff, 0xff, 0x00}}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - bytes2",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{0x80, 0x00}}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 1), ast.ComposeDataType(5, 1),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}},
+ },
+ ),
+ nil,
+ },
+ {
+ "None Immediate - bytes3",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(6, 1),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0x7f, 0xff}}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(7, 1),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 1),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte{0x7f, 0xff}}},
+ },
+ ),
+ nil,
+ },
+ {
+ "Same type",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Error Invalid Type",
+ Instruction{
+ Op: CAST,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(4, 2),
+ },
+ []Tuple{
+ {&Raw{Value: decimal.NewFromFloat(-32768)}},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0),
+ },
+ []Tuple{},
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{},
+ []Tuple{},
+ ),
+ errors.ErrorCodeInvalidCastType,
+ },
+ }
+
+ s.run(testcases, opCast)
+}
+
+func (s *instructionSuite) TestOpSort() {
+ testcases := []opTestcase{
+ {
+ "Multi-column sorting",
+ Instruction{
+ Op: SORT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {rawFalse, &Raw{Value: decimal.NewFromFloat(1)}},
+ {rawTrue, &Raw{Value: decimal.NewFromFloat(2)}},
+ {rawFalse, &Raw{Value: decimal.NewFromFloat(0)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse},
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ },
+ ),
+ nil,
+ },
+ {
+ "Multi-column sorting - 2",
+ Instruction{
+ Op: SORT,
+ Input: []*Operand{
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ },
+ ),
+ makeOperand(
+ true,
+ []ast.DataType{
+ ast.ComposeDataType(2, 0), ast.ComposeDataType(4, 0),
+ },
+ []Tuple{
+ {rawTrue, &Raw{Value: decimal.NewFromFloat(0)}},
+ {rawTrue, &Raw{Value: decimal.NewFromFloat(1)}},
+ {rawFalse, &Raw{Value: decimal.NewFromFloat(2)}},
+ },
+ ),
+ },
+ Output: 0,
+ },
+ makeOperand(
+ false,
+ []ast.DataType{
+ ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0),
+ },
+ []Tuple{
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue},
+ {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse},
+ {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue},
+ {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse},
+ },
+ ),
+ nil,
+ },
+ }
+
+ s.run(testcases, opSort)
+}
diff --git a/core/vm/sqlvm/runtime/instructions_test.go b/core/vm/sqlvm/runtime/instructions_test.go
index 7c6bb2c5b..b679c366f 100644
--- a/core/vm/sqlvm/runtime/instructions_test.go
+++ b/core/vm/sqlvm/runtime/instructions_test.go
@@ -191,7 +191,7 @@ type decodeTestCase struct {
type opLoadTestCase struct {
title string
- outputIdx int
+ outputIdx uint
expectedOutput *Operand
expectedErr error
ids []uint64
@@ -410,3 +410,62 @@ func (s *opLoadSuite) TestOpLoad() {
func TestOpLoad(t *testing.T) {
suite.Run(t, new(opLoadSuite))
}
+
+func TestInstructions(t *testing.T) {
+ suite.Run(t, new(instructionSuite))
+}
+
+func makeOperand(im bool, meta []ast.DataType, pTuple []Tuple) (op *Operand) {
+ op = &Operand{IsImmediate: im, Meta: meta, Data: pTuple}
+ return
+}
+
+func loadRegister(input, registers []*Operand) {
+ for i, operand := range input {
+ if operand != nil && !operand.IsImmediate {
+ input[i] = registers[operand.RegisterIndex]
+ }
+ }
+}
+
+type opTestcase struct {
+ Name string
+ In Instruction
+ Output *Operand
+ Err error
+}
+
+type instructionSuite struct {
+ suite.Suite
+}
+
+func (s *instructionSuite) run(testcases []opTestcase, opfunc OpFunction) {
+ for idx, c := range testcases {
+ registers := make([]*Operand, len(c.In.Input))
+
+ for i, j := 0, 0; i < len(c.In.Input); i++ {
+ if !c.In.Input[i].IsImmediate {
+ registers[j] = c.In.Input[i]
+ j++
+ }
+ }
+ err := opfunc(
+ &common.Context{Opt: common.Option{SafeMath: true}},
+ c.In.Input, registers, c.In.Output)
+ s.Require().Equal(
+ c.Err, err,
+ "idx: %v, op: %v, case: %v\nerror not equal: %v != %v",
+ idx, c.In.Op, c.Name, c.Err, err,
+ )
+ if c.Err != nil {
+ continue
+ }
+
+ result := registers[0]
+ s.Require().True(
+ c.Output.Equal(result),
+ "idx: %v, op: %v, case: %v\noutput not equal.\nExpect: %v\nResult: %v\n",
+ idx, c.In.Op, c.Name, c.Output, result,
+ )
+ }
+}
diff --git a/core/vm/sqlvm/runtime/instructions_tmpl.go b/core/vm/sqlvm/runtime/instructions_tmpl.go
new file mode 100644
index 000000000..22c6bef88
--- /dev/null
+++ b/core/vm/sqlvm/runtime/instructions_tmpl.go
@@ -0,0 +1,82 @@
+package runtime
+
+import "github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
+
+type tmplData struct {
+ BinOpCollections []tmplTestCollection
+}
+
+type tmplTestCollection struct {
+ TestName string
+ Cases []tmplTestCase
+ OpFunc string
+}
+
+type tmplTestCase struct {
+ Name string
+ OpCode string
+ Inputs []tmplOp
+ Output tmplOp
+ Error string
+}
+
+type tmplOp struct {
+ Im bool
+ Metas []tmplOpMeta
+ Data []string
+}
+
+type tmplOpMeta struct {
+ Major ast.DataTypeMajor
+ Minor ast.DataTypeMinor
+}
+
+const binOpTmplStr = `
+// Code generated - DO NOT EDIT.
+
+package runtime
+
+import (
+ "github.com/dexon-foundation/decimal"
+
+ "github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
+ "github.com/dexon-foundation/dexon/core/vm/sqlvm/errors"
+)
+
+{{range .BinOpCollections}}
+func (s *instructionSuite) Test{{.TestName}}() {
+ testcases := []opTestcase{ {{range .Cases}}
+ {
+ "{{.Name}}",
+ Instruction{
+ Op: {{.OpCode}},
+ Input: []*Operand{ {{range .Inputs}}
+ makeOperand(
+ {{.Im}},
+ []ast.DataType{
+ {{range .Metas}}ast.ComposeDataType({{.Major}}, {{.Minor}}),{{end}}
+ },
+ []Tuple{ {{range .Data}}
+ {{.}},{{end}}
+ },
+ ),{{end}}
+ },
+ Output: 0,
+ },
+ makeOperand(
+ {{.Output.Im}},
+ []ast.DataType{
+ {{range .Output.Metas}}ast.ComposeDataType({{.Major}}, {{.Minor}}),{{end}}
+ },
+ []Tuple{ {{range .Output.Data}}
+ {{.}},{{end}}
+ },
+ ),
+ {{.Error}},
+ },{{end}}
+ }
+
+ s.run(testcases, {{.OpFunc}})
+}
+{{end}}
+`
diff --git a/core/vm/sqlvm/runtime/instructions_tmpl_data.go b/core/vm/sqlvm/runtime/instructions_tmpl_data.go
new file mode 100644
index 000000000..345d200ec
--- /dev/null
+++ b/core/vm/sqlvm/runtime/instructions_tmpl_data.go
@@ -0,0 +1,2934 @@
+package runtime
+
+import (
+ "bytes"
+ "go/format"
+ "os"
+ "text/template"
+
+ "github.com/dexon-foundation/dexon/core/vm/sqlvm/ast"
+)
+
+// RenderOpTest render op test to test file.
+func RenderOpTest(output string) (err error) {
+ binOpT, err := template.New("binOp").Parse(binOpTmplStr)
+ if err != nil {
+ return
+ }
+
+ b := new(bytes.Buffer)
+
+ err = binOpT.Execute(b, testData)
+ if err != nil {
+ return
+ }
+
+ src, err := format.Source(b.Bytes())
+ if err != nil {
+ return
+ }
+
+ f, err := os.Create(output)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+
+ _, err = f.Write(src)
+ return
+}
+
+var testData = tmplData{
+ BinOpCollections: []tmplTestCollection{
+ {
+ TestName: "OpAdd", OpFunc: "opAdd",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(3)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(4)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(20)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(13)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate 2",
+ Error: "nil", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ {
+ Name: "Overflow - Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Overflow None Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(126)}}",
+ "{&Raw{Value: decimal.NewFromFloat(126)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Underflow - Immediate",
+ Error: "errors.ErrorCodeUnderflow", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-128)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Underflow None Immediate",
+ Error: "errors.ErrorCodeUnderflow", OpCode: "ADD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-127)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of ADD
+ {
+ TestName: "OpSub", OpFunc: "opSub",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(3)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-4)}}",
+ "{&Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(7)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(9)}, &Raw{Value: decimal.NewFromFloat(12)}, &Raw{Value: decimal.NewFromFloat(20)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-11)}, &Raw{Value: decimal.NewFromFloat(-8)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate 2",
+ Error: "nil", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}}",
+ "{&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-4)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ {
+ Name: "Overflow - Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Overflow None Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(126)}}",
+ "{&Raw{Value: decimal.NewFromFloat(126)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Underflow - Immediate",
+ Error: "errors.ErrorCodeUnderflow", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-128)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Underflow None Immediate",
+ Error: "errors.ErrorCodeUnderflow", OpCode: "SUB",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-127)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of SUB
+ {
+ TestName: "OpMul", OpFunc: "opMul",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-4)}, &Raw{Value: decimal.NewFromFloat(-100)}}",
+ "{&Raw{Value: decimal.NewFromFloat(100)}, &Raw{Value: decimal.NewFromFloat(100)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate - 2",
+ Error: "nil", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ {
+ Name: "Overflow - Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Overflow None Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(126)}}",
+ "{&Raw{Value: decimal.NewFromFloat(126)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Underflow - Immediate",
+ Error: "errors.ErrorCodeUnderflow", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-128)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Underflow None Immediate",
+ Error: "errors.ErrorCodeUnderflow", OpCode: "MUL",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-127)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of MUL
+ {
+ TestName: "OpDiv", OpFunc: "opDiv",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}}",
+ "{&Raw{Value: decimal.NewFromFloat(6)}, &Raw{Value: decimal.NewFromFloat(-6)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-6)}, &Raw{Value: decimal.NewFromFloat(6)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate 2",
+ Error: "nil", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(50)}, &Raw{Value: decimal.NewFromFloat(-50)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(9)}, &Raw{Value: decimal.NewFromFloat(9)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-9)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}}",
+ "{&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}}",
+ },
+ },
+ },
+ {
+ Name: "DivideByZero Immediate",
+ Error: "errors.ErrorCodeDividedByZero", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "DivideByZero None Immediate",
+ Error: "errors.ErrorCodeDividedByZero", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Overflow - Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-128)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "Overflow None Immediate",
+ Error: "errors.ErrorCodeOverflow", OpCode: "DIV",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-128)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-128)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-2)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of DIV
+ {
+ TestName: "OpMod", OpFunc: "opMod",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "MOD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(3)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-3)}, &Raw{Value: decimal.NewFromFloat(-3)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "MOD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(-3)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ {
+ Name: "Immediate - 2",
+ Error: "nil", OpCode: "MOD",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(31)}, &Raw{Value: decimal.NewFromFloat(-31)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}",
+ "{&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}",
+ },
+ },
+ },
+ {
+ Name: "ModideByZero Immediate",
+ Error: "errors.ErrorCodeDividedByZero", OpCode: "MOD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ {
+ Name: "ModideByZero None Immediate",
+ Error: "errors.ErrorCodeDividedByZero", OpCode: "MOD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ "{&Raw{Value: decimal.NewFromFloat(10)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of MOD
+ {
+ TestName: "OpLt", OpFunc: "opLt",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "LT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawTrue, rawTrue}",
+ "{rawFalse, rawFalse, rawTrue}",
+ "{rawFalse, rawFalse, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "LT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawFalse, rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Immediate - 2",
+ Error: "nil", OpCode: "LT",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawTrue, rawFalse}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of LT
+ {
+ TestName: "OpGt", OpFunc: "opGt",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "GT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawFalse, rawFalse}",
+ "{rawTrue, rawFalse, rawFalse}",
+ "{rawTrue, rawTrue, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "GT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawTrue, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "Immediate - 2",
+ Error: "nil", OpCode: "GT",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawFalse, rawTrue}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of GT
+ {
+ TestName: "OpEq", OpFunc: "opEq",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "EQ",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue, rawTrue}",
+ "{rawTrue, rawFalse, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "EQ",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue, rawTrue}",
+ "{rawTrue, rawFalse, rawFalse}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of EQ
+ {
+ TestName: "OpAnd", OpFunc: "opAnd",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "AND",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "AND",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Immediate - 2",
+ Error: "nil", OpCode: "AND",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Invalid Data Type",
+ Error: "errors.ErrorCodeInvalidDataType", OpCode: "AND",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of AND
+ {
+ TestName: "OpOr", OpFunc: "opOr",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "OR",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Immediate",
+ Error: "nil", OpCode: "OR",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawTrue, rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Immediate - 2",
+ Error: "nil", OpCode: "OR",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawTrue, rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Invalid Data Type",
+ Error: "errors.ErrorCodeInvalidDataType", OpCode: "OR",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of OR
+ {
+ TestName: "OpNot", OpFunc: "opNot",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "NOT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawTrue}",
+ "{rawTrue, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "Errors Invalid Data Type",
+ Error: "errors.ErrorCodeInvalidDataType", OpCode: "NOT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}}",
+ },
+ },
+ },
+ Output: tmplOp{},
+ },
+ },
+ },
+ // -- end of NOT
+ {
+ TestName: "OpUnion", OpFunc: "opUnion",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "UNION",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawFalse}",
+ "{rawFalse, rawTrue}",
+ "{rawTrue, rawFalse}",
+ "{rawTrue, rawTrue}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of UNION
+ {
+ TestName: "OpIntxn", OpFunc: "opIntxn",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate",
+ Error: "nil", OpCode: "INTXN",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, rawFalse}",
+ "{rawTrue, rawTrue}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of INTXN
+ {
+ TestName: "OpLike", OpFunc: "opLike",
+ Cases: []tmplTestCase{
+ {
+ Name: `Like %\\%b% escape \\`, // \\ is raw string escape for \
+ Error: "nil", OpCode: "LIKE",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("a%bcdefg")}, &Raw{Bytes: []byte("gfedcba")}}`,
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{`{&Raw{Bytes: []byte("%\\%b%")}}`},
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{`{&Raw{Bytes: []byte("\\")}}`},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: `Like t1 escape t2`,
+ Error: "nil", OpCode: "LIKE",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("a%bcdefg")}}`,
+ `{&Raw{Bytes: []byte("gfedcba")}}`,
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("%\\%b%")}}`,
+ `{&Raw{Bytes: []byte("_fed%")}}`,
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("\\")}}`,
+ `{&Raw{Bytes: []byte("")}}`,
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue}",
+ "{rawTrue}",
+ },
+ },
+ },
+ {
+ Name: `Like with valid and invalid UTF8`,
+ Error: "nil", OpCode: "LIKE",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte{226, 40, 161, 228, 189, 160, 229, 165, 189}}, &Raw{Bytes: []byte("gfedcba")}}`,
+ // "\xe2(\xa1你好"
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte{37, 228, 189, 160, 37}}}`,
+ // "%你%"
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of LIKE
+ {
+ TestName: "OpZip", OpFunc: "opZip",
+ Cases: []tmplTestCase{
+ {
+ Name: "Zip two array",
+ Error: "nil", OpCode: "ZIP",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}}`,
+ `{&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}}`,
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, rawTrue}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ },
+ },
+ },
+ {
+ Name: "Zip immediate",
+ Error: "nil", OpCode: "ZIP",
+ Inputs: []tmplOp{
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}}`,
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, rawTrue}",
+ "{&Raw{Value: decimal.NewFromFloat(2)}, rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ },
+ },
+ },
+ },
+ },
+ // -- end of ZIP
+ {
+ TestName: "OpField", OpFunc: "opField",
+ Cases: []tmplTestCase{
+ {
+ Name: "Retrieve 2nd,3rd column",
+ Error: "nil", OpCode: "FIELD",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}}`,
+ `{&Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}}`,
+ },
+ },
+ },
+ },
+ },
+ // -- end of FIELD
+ {
+ TestName: "OpPrune", OpFunc: "opPrune",
+ Cases: []tmplTestCase{
+ {
+ Name: "Prune 2nd,4th,5th column",
+ Error: "nil", OpCode: "PRUNE",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse, rawTrue}`,
+ `{&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue, rawFalse}`,
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(4)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Value: decimal.NewFromFloat(1)}}`,
+ `{&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Value: decimal.NewFromFloat(2)}}`,
+ },
+ },
+ },
+ },
+ },
+ // -- end of PRUNE
+ {
+ TestName: "OpFilter", OpFunc: "opFilter",
+ Cases: []tmplTestCase{
+ {
+ Name: "Filter first 2 rows",
+ Error: "nil", OpCode: "FILTER",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ "{rawTrue, rawTrue}",
+ "{rawFalse, rawFalse}",
+ },
+ },
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue}",
+ "{rawTrue}",
+ "{rawFalse}",
+ "{rawFalse}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ "{rawFalse, rawTrue}",
+ },
+ },
+ },
+ },
+ },
+ // -- end of FILTER
+ {
+ TestName: "OpCast", OpFunc: "opCast",
+ Cases: []tmplTestCase{
+ {
+ Name: "None Immediate - int",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> int8
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> int24
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(127)}, &Raw{Value: decimal.NewFromFloat(127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Value: decimal.NewFromFloat(-128)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 2},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 2},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(127)}, &Raw{Value: decimal.NewFromFloat(127)}}",
+ "{&Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Value: decimal.NewFromFloat(-128)}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - int2",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> uint16
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> uint16
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1},
+ {Major: ast.DataTypeMajorUint, Minor: 1},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1},
+ {Major: ast.DataTypeMajorUint, Minor: 1},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - int3",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> bool
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> bool
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}}",
+ "{&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawTrue}", "{rawFalse, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - int4",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> bytes16
+ {Major: ast.DataTypeMajorInt, Minor: 1}, // int16 -> address
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ {Major: ast.DataTypeMajorAddress, Minor: 0},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ {Major: ast.DataTypeMajorAddress, Minor: 0},
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0x80,0x00}}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - uint",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> uint8
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> uint24
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(128)}, &Raw{Value: decimal.NewFromFloat(128)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 0},
+ {Major: ast.DataTypeMajorUint, Minor: 2},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 0},
+ {Major: ast.DataTypeMajorUint, Minor: 2},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(128)}, &Raw{Value: decimal.NewFromFloat(128)}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - uint2",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> int16
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> byte16
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1},
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1},
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Bytes: []byte{0x80,0x00}}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - uint3",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> bool
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> bool
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, rawFalse}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - uint4",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> bytes
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> bytes
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1},
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{0x00, 0x00}}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - uint5",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorUint, Minor: 1}, // uint16 -> address
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorAddress, Minor: 1},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorAddress, Minor: 1},
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x7f,0xff}}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - bytes",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1}, // byte16 -> byte8
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1}, // byte16 -> byte24
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0xff, 0xff}}, &Raw{Bytes: []byte{0xff, 0xff}}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 0},
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 2},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 0},
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 2},
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0xff}}, &Raw{Bytes: []byte{0xff, 0xff, 0x00}}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - bytes2",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1}, // byte16 -> int16
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1}, // byte16 -> uint16
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{0x80, 0x00}}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1},
+ {Major: ast.DataTypeMajorUint, Minor: 1},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 1},
+ {Major: ast.DataTypeMajorUint, Minor: 1},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}}",
+ },
+ },
+ },
+ {
+ Name: "None Immediate - bytes3",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorFixedBytes, Minor: 1}, // byte16 -> dyn
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0x7f, 0xff}}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 1},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 1},
+ },
+ Data: []string{
+ "{&Raw{Bytes: []byte{0x7f, 0xff}}}",
+ },
+ },
+ },
+ {
+ Name: "Same type",
+ Error: "nil", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue}",
+ },
+ },
+ },
+ {
+ Name: "Error Invalid Type",
+ Error: "errors.ErrorCodeInvalidCastType", OpCode: "CAST",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorInt, Minor: 2},
+ },
+ Data: []string{
+ "{&Raw{Value: decimal.NewFromFloat(-32768)}}",
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ },
+ Data: []string{},
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{},
+ Data: []string{},
+ },
+ },
+ },
+ },
+ // -- end of CAST
+ {
+ TestName: "OpSort", OpFunc: "opSort",
+ Cases: []tmplTestCase{
+ {
+ Name: "Multi-column sorting",
+ Error: "nil", OpCode: "SORT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{rawFalse, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{rawTrue, &Raw{Value: decimal.NewFromFloat(2)}}",
+ "{rawFalse, &Raw{Value: decimal.NewFromFloat(0)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ },
+ },
+ },
+ {
+ Name: "Multi-column sorting - 2",
+ Error: "nil", OpCode: "SORT",
+ Inputs: []tmplOp{
+ {
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ },
+ },
+ {
+ Im: true,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ },
+ Data: []string{
+ "{rawTrue, &Raw{Value: decimal.NewFromFloat(0)}}",
+ "{rawTrue, &Raw{Value: decimal.NewFromFloat(1)}}",
+ "{rawFalse, &Raw{Value: decimal.NewFromFloat(2)}}",
+ },
+ },
+ },
+ Output: tmplOp{
+ Im: false,
+ Metas: []tmplOpMeta{
+ {Major: ast.DataTypeMajorDynamicBytes, Minor: 0},
+ {Major: ast.DataTypeMajorInt, Minor: 0},
+ {Major: ast.DataTypeMajorBool, Minor: 0},
+ },
+ Data: []string{
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}`,
+ `{&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}`,
+ },
+ },
+ },
+ },
+ },
+ // -- end of SORT
+ },
+}
diff --git a/core/vm/sqlvm/runtime/runtime.go b/core/vm/sqlvm/runtime/runtime.go
index e6a3a0006..5cae111c9 100644
--- a/core/vm/sqlvm/runtime/runtime.go
+++ b/core/vm/sqlvm/runtime/runtime.go
@@ -29,11 +29,3 @@ func Run(stateDB vm.StateDB, ins []Instruction, registers []*Operand) (ret []byt
// TODO: ret = ABIEncode(ins[len(ins)-1].Output)
return
}
-
-func loadRegister(input, registers []*Operand) {
- for i, operand := range input {
- if operand != nil && !operand.IsImmediate {
- input[i] = registers[operand.RegisterIndex]
- }
- }
-}