A lot of changes. Main ones are:

- fraction type renamed as FractionType and moved from operator-fraction.go to fraction-type.go
- ListType moved from operator-list.go to list-type.go
- all test file were renamed adding the "t_" prefix
- defined a test template in file t_temple_test.go
- new test file t_relational_test.go where relational tests are collected
- lists can now compared as set using operators <, <=, >, and >= (IMPORTANT: here = menas same content, not same list)
This commit is contained in:
2024-05-28 07:26:05 +02:00
parent 78cbb7b36f
commit 3736214c5a
25 changed files with 722 additions and 554 deletions
+121 -92
View File
@@ -4,13 +4,13 @@
// operator-rel.go
package expr
import "reflect"
//-------- equal term
func newEqualTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindBool,
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priRelational,
@@ -18,6 +18,29 @@ func newEqualTerm(tk *Token) (inst *term) {
}
}
func equals(a, b any) (eq bool, err error) {
if isNumOrFract(a) && isNumOrFract(b) {
if IsNumber(a) && IsNumber(b) {
if IsInteger(a) && IsInteger(b) {
li, _ := a.(int64)
ri, _ := b.(int64)
eq = li == ri
} else {
eq = numAsFloat(a) == numAsFloat(b)
}
} else {
var cmp int
if cmp, err = cmpAnyFract(a, b); err == nil {
eq = cmp == 0
}
}
} else {
eq = reflect.DeepEqual(a, b)
}
return
}
func evalEqual(ctx ExprContext, self *term) (v any, err error) {
var leftValue, rightValue any
@@ -25,21 +48,7 @@ func evalEqual(ctx ExprContext, self *term) (v any, err error) {
return
}
if IsNumber(leftValue) && IsNumber(rightValue) {
if IsInteger(leftValue) && IsInteger(rightValue) {
li, _ := leftValue.(int64)
ri, _ := rightValue.(int64)
v = li == ri
} else {
v = numAsFloat(leftValue) == numAsFloat(rightValue)
}
} else if IsString(leftValue) && IsString(rightValue) {
ls, _ := leftValue.(string)
rs, _ := rightValue.(string)
v = ls == rs
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
}
v, err = equals(leftValue, rightValue)
return
}
@@ -47,9 +56,7 @@ func evalEqual(ctx ExprContext, self *term) (v any, err error) {
func newNotEqualTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindBool,
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priRelational,
@@ -65,38 +72,11 @@ func evalNotEqual(ctx ExprContext, self *term) (v any, err error) {
return
}
// func evalNotEqual(ctx exprContext, self *term) (v any, err error) {
// var leftValue, rightValue any
// if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
// return
// }
// if isNumber(leftValue) && isNumber(rightValue) {
// if isInteger(leftValue) && isInteger(rightValue) {
// li, _ := leftValue.(int64)
// ri, _ := rightValue.(int64)
// v = li != ri
// } else {
// v = numAsFloat(leftValue) != numAsFloat(rightValue)
// }
// } else if isString(leftValue) && isString(rightValue) {
// ls, _ := leftValue.(string)
// rs, _ := rightValue.(string)
// v = ls != rs
// } else {
// err = self.errIncompatibleTypes(leftValue, rightValue)
// }
// return
// }
//-------- less term
func newLessTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindBool,
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priRelational,
@@ -104,28 +84,52 @@ func newLessTerm(tk *Token) (inst *term) {
}
}
func lessThan(self *term, a, b any) (isLess bool, err error) {
if isNumOrFract(a) && isNumOrFract(b) {
if IsNumber(a) && IsNumber(b) {
if IsInteger(a) && IsInteger(b) {
li, _ := a.(int64)
ri, _ := b.(int64)
isLess = li < ri
} else {
isLess = numAsFloat(a) < numAsFloat(b)
}
} else {
var cmp int
if cmp, err = cmpAnyFract(a, b); err == nil {
isLess = cmp < 0
}
}
} else if IsString(a) && IsString(b) {
ls, _ := a.(string)
rs, _ := b.(string)
isLess = ls < rs
// Inclusion test
} else if IsList(a) && IsList(b) {
aList, _ := a.(*ListType)
bList, _ := b.(*ListType)
isLess = len(*aList) < len(*bList)
if isLess {
for _, item := range *aList {
if bList.indexDeepCmp(item) < 0 {
isLess = false
break
}
}
}
} else {
err = self.errIncompatibleTypes(a, b)
}
return
}
func evalLess(ctx ExprContext, self *term) (v any, err error) {
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
return
}
if IsNumber(leftValue) && IsNumber(rightValue) {
if IsInteger(leftValue) && IsInteger(rightValue) {
li, _ := leftValue.(int64)
ri, _ := rightValue.(int64)
v = li < ri
} else {
v = numAsFloat(leftValue) < numAsFloat(rightValue)
}
} else if IsString(leftValue) && IsString(rightValue) {
ls, _ := leftValue.(string)
rs, _ := rightValue.(string)
v = ls < rs
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
}
v, err = lessThan(self, leftValue, rightValue)
return
}
@@ -141,6 +145,33 @@ func newLessEqualTerm(tk *Token) (inst *term) {
}
}
func sameContent(a, b any) (same bool, err error) {
la, _ := a.(*ListType)
lb, _ := b.(*ListType)
if len(*la) == len(*lb) {
same = true
for i, item := range *la {
if same, err = equals(item, (*lb)[i]); err != nil || !same {
break
}
}
}
return
}
func lessThanOrEqual(self *term, a, b any) (isLessEq bool, err error) {
if isLessEq, err = lessThan(self, a, b); err == nil {
if !isLessEq {
if IsList(a) && IsList(b) {
isLessEq, err = sameContent(a, b)
} else {
isLessEq, err = equals(a, b)
}
}
}
return
}
func evalLessEqual(ctx ExprContext, self *term) (v any, err error) {
var leftValue, rightValue any
@@ -148,21 +179,8 @@ func evalLessEqual(ctx ExprContext, self *term) (v any, err error) {
return
}
if IsNumber(leftValue) && IsNumber(rightValue) {
if IsInteger(leftValue) && IsInteger(rightValue) {
li, _ := leftValue.(int64)
ri, _ := rightValue.(int64)
v = li <= ri
} else {
v = numAsFloat(leftValue) <= numAsFloat(rightValue)
}
} else if IsString(leftValue) && IsString(rightValue) {
ls, _ := leftValue.(string)
rs, _ := rightValue.(string)
v = ls <= rs
} else {
err = self.errIncompatibleTypes(leftValue, rightValue)
}
v, err = lessThanOrEqual(self, leftValue, rightValue)
return
}
@@ -170,9 +188,7 @@ func evalLessEqual(ctx ExprContext, self *term) (v any, err error) {
func newGreaterTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindBool,
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priRelational,
@@ -181,10 +197,18 @@ func newGreaterTerm(tk *Token) (inst *term) {
}
func evalGreater(ctx ExprContext, self *term) (v any, err error) {
if v, err = evalLessEqual(ctx, self); err == nil {
b, _ := toBool(v)
v = !b
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
return
}
v, err = lessThan(self, rightValue, leftValue)
// if v, err = evalLessEqual(ctx, self); err == nil {
// b, _ := toBool(v)
// v = !b
// }
return
}
@@ -192,9 +216,7 @@ func evalGreater(ctx ExprContext, self *term) (v any, err error) {
func newGreaterEqualTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
// class: classOperator,
// kind: kindBool,
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priRelational,
@@ -203,10 +225,17 @@ func newGreaterEqualTerm(tk *Token) (inst *term) {
}
func evalGreaterEqual(ctx ExprContext, self *term) (v any, err error) {
if v, err = evalLess(ctx, self); err == nil {
b, _ := toBool(v)
v = !b
var leftValue, rightValue any
if leftValue, rightValue, err = self.evalInfix(ctx); err != nil {
return
}
v, err = lessThanOrEqual(self, rightValue, leftValue)
// if v, err = evalLess(ctx, self); err == nil {
// b, _ := toBool(v)
// v = !b
// }
return
}