github.com/MontFerret/ferret@v0.18.0/pkg/runtime/expressions/operators/math.go (about) 1 package operators 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/runtime/core" 7 "github.com/MontFerret/ferret/pkg/runtime/values" 8 ) 9 10 type ( 11 MathOperatorVariant string 12 13 MathOperator struct { 14 *baseOperator 15 variant MathOperatorVariant 16 fn OperatorFunc 17 leftOnly bool 18 } 19 ) 20 21 const ( 22 MathOperatorVariantAdd MathOperatorVariant = "+" 23 MathOperatorVariantSubtract MathOperatorVariant = "-" 24 MathOperatorVariantMultiply MathOperatorVariant = "*" 25 MathOperatorVariantDivide MathOperatorVariant = "/" 26 MathOperatorVariantModulus MathOperatorVariant = "%" 27 MathOperatorVariantIncrement MathOperatorVariant = "++" 28 MathOperatorVariantDecrement MathOperatorVariant = "--" 29 ) 30 31 var mathOperatorVariants = map[MathOperatorVariant]OperatorFunc{ 32 MathOperatorVariantAdd: Add, 33 MathOperatorVariantSubtract: Subtract, 34 MathOperatorVariantMultiply: Multiply, 35 MathOperatorVariantDivide: Divide, 36 MathOperatorVariantModulus: Modulus, 37 MathOperatorVariantIncrement: Increment, 38 MathOperatorVariantDecrement: Decrement, 39 } 40 41 func NewMathOperator( 42 src core.SourceMap, 43 left core.Expression, 44 right core.Expression, 45 variantStr string, 46 ) (*MathOperator, error) { 47 variant := MathOperatorVariant(variantStr) 48 fn, exists := mathOperatorVariants[variant] 49 50 if !exists { 51 return nil, core.Error(core.ErrInvalidArgument, "operator type") 52 } 53 54 var leftOnly bool 55 56 if variant == "++" || variant == "--" { 57 leftOnly = true 58 } 59 60 return &MathOperator{ 61 &baseOperator{src, left, right}, 62 variant, 63 fn, 64 leftOnly, 65 }, nil 66 } 67 68 func (operator *MathOperator) Type() MathOperatorVariant { 69 return operator.variant 70 } 71 72 func (operator *MathOperator) Exec(ctx context.Context, scope *core.Scope) (core.Value, error) { 73 left, err := operator.left.Exec(ctx, scope) 74 75 if err != nil { 76 return nil, err 77 } 78 79 if operator.leftOnly { 80 return operator.Eval(ctx, left, values.None) 81 } 82 83 right, err := operator.right.Exec(ctx, scope) 84 85 if err != nil { 86 return nil, err 87 } 88 89 return operator.Eval(ctx, left, right) 90 } 91 92 func (operator *MathOperator) Eval(_ context.Context, left, right core.Value) (core.Value, error) { 93 if operator.leftOnly { 94 return operator.fn(left, values.None), nil 95 } 96 97 return operator.fn(left, right), nil 98 }