// 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, class: classOperator, kind: kindUnknown, 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) }