222 lines
5.0 KiB
Go
222 lines
5.0 KiB
Go
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
// All rights reserved.
|
|
|
|
// operator-rel.go
|
|
package expr
|
|
|
|
//-------- equal term
|
|
|
|
func newEqualTerm(tk *Token) (inst *term) {
|
|
return &term{
|
|
tk: *tk,
|
|
// class: classOperator,
|
|
// kind: kindBool,
|
|
children: make([]*term, 0, 2),
|
|
position: posInfix,
|
|
priority: priRelational,
|
|
evalFunc: evalEqual,
|
|
}
|
|
}
|
|
|
|
func evalEqual(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
|
|
}
|
|
|
|
//-------- not equal term
|
|
|
|
func newNotEqualTerm(tk *Token) (inst *term) {
|
|
return &term{
|
|
tk: *tk,
|
|
// class: classOperator,
|
|
// kind: kindBool,
|
|
children: make([]*term, 0, 2),
|
|
position: posInfix,
|
|
priority: priRelational,
|
|
evalFunc: evalNotEqual,
|
|
}
|
|
}
|
|
|
|
func evalNotEqual(ctx ExprContext, self *term) (v any, err error) {
|
|
if v, err = evalEqual(ctx, self); err == nil {
|
|
b, _ := toBool(v)
|
|
v = !b
|
|
}
|
|
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,
|
|
children: make([]*term, 0, 2),
|
|
position: posInfix,
|
|
priority: priRelational,
|
|
evalFunc: evalLess,
|
|
}
|
|
}
|
|
|
|
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)
|
|
}
|
|
return
|
|
}
|
|
|
|
//-------- less or equal term
|
|
|
|
func newLessEqualTerm(tk *Token) (inst *term) {
|
|
return &term{
|
|
tk: *tk,
|
|
children: make([]*term, 0, 2),
|
|
position: posInfix,
|
|
priority: priRelational,
|
|
evalFunc: evalLessEqual,
|
|
}
|
|
}
|
|
|
|
func evalLessEqual(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
|
|
}
|
|
|
|
//-------- greater term
|
|
|
|
func newGreaterTerm(tk *Token) (inst *term) {
|
|
return &term{
|
|
tk: *tk,
|
|
// class: classOperator,
|
|
// kind: kindBool,
|
|
children: make([]*term, 0, 2),
|
|
position: posInfix,
|
|
priority: priRelational,
|
|
evalFunc: evalGreater,
|
|
}
|
|
}
|
|
|
|
func evalGreater(ctx ExprContext, self *term) (v any, err error) {
|
|
if v, err = evalLessEqual(ctx, self); err == nil {
|
|
b, _ := toBool(v)
|
|
v = !b
|
|
}
|
|
return
|
|
}
|
|
|
|
//-------- greater or equal term
|
|
|
|
func newGreaterEqualTerm(tk *Token) (inst *term) {
|
|
return &term{
|
|
tk: *tk,
|
|
// class: classOperator,
|
|
// kind: kindBool,
|
|
children: make([]*term, 0, 2),
|
|
position: posInfix,
|
|
priority: priRelational,
|
|
evalFunc: evalGreaterEqual,
|
|
}
|
|
}
|
|
|
|
func evalGreaterEqual(ctx ExprContext, self *term) (v any, err error) {
|
|
if v, err = evalLess(ctx, self); err == nil {
|
|
b, _ := toBool(v)
|
|
v = !b
|
|
}
|
|
return
|
|
}
|
|
|
|
// init
|
|
func init() {
|
|
registerTermConstructor(SymDoubleEqual, newEqualTerm)
|
|
registerTermConstructor(SymNotEqual, newNotEqualTerm)
|
|
registerTermConstructor(SymLess, newLessTerm)
|
|
registerTermConstructor(SymLessOrEqual, newLessEqualTerm)
|
|
registerTermConstructor(SymGreater, newGreaterTerm)
|
|
registerTermConstructor(SymGreaterOrEqual, newGreaterEqualTerm)
|
|
}
|