github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/expressions/exp06.go (about)

     1  package expressions
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/lmorg/murex/lang/expressions/primitives"
     7  	"github.com/lmorg/murex/lang/expressions/symbols"
     8  	"github.com/lmorg/murex/lang/types"
     9  )
    10  
    11  func expGtLt(tree *ParserT, compareFloat ltGtFT, compareString ltGtST) error {
    12  	leftNode, rightNode, err := tree.getLeftAndRightSymbols()
    13  	if err != nil {
    14  		return err
    15  	}
    16  
    17  	var value bool
    18  
    19  	lv, rv, err := compareTypes(tree, leftNode, rightNode)
    20  	if err != nil {
    21  		return err
    22  	}
    23  
    24  	left, err := leftNode.dt.GetValue()
    25  	if err != nil { // error should have been captured with compareTypes() but doesn't hurt to be cautious
    26  		return err
    27  	}
    28  
    29  	switch lv.(type) {
    30  	case float64, int:
    31  		value = compareFloat(convertNumber(lv), convertNumber(rv))
    32  
    33  	case string:
    34  		value = compareString(lv.(string), rv.(string))
    35  
    36  	default:
    37  		return raiseError(tree.expression, tree.currentSymbol(), 0, fmt.Sprintf(
    38  			"cannot %s with %s types", tree.currentSymbol().key, left.Primitive,
    39  		))
    40  	}
    41  
    42  	return tree.foldAst(&astNodeT{
    43  		key: symbols.Exp(left.Primitive),
    44  		pos: tree.ast[tree.astPos].pos,
    45  		dt:  primitives.NewPrimitive(primitives.Boolean, value),
    46  	})
    47  }
    48  
    49  type ltGtFT func(float64, float64) bool
    50  type ltGtST func(string, string) bool
    51  
    52  func _ltF(lv, rv float64) bool   { return lv < rv }
    53  func _ltEqF(lv, rv float64) bool { return lv <= rv }
    54  func _gtEqF(lv, rv float64) bool { return lv >= rv }
    55  func _gtF(lv, rv float64) bool   { return lv > rv }
    56  func _ltS(lv, rv string) bool    { return lv < rv }
    57  func _ltEqS(lv, rv string) bool  { return lv <= rv }
    58  func _gtEqS(lv, rv string) bool  { return lv >= rv }
    59  func _gtS(lv, rv string) bool    { return lv > rv }
    60  
    61  func convertNumber(v any) float64 {
    62  	f, err := types.ConvertGoType(v, types.Number)
    63  	if err != nil {
    64  		return 0
    65  	}
    66  	return f.(float64)
    67  }