// funcs-math.go package expr import ( "fmt" "io" ) func checkNumberParamExpected(funcName string, paramValue any, paramPos int) (err error) { if !(isNumber(paramValue) || isList(paramValue)) { err = fmt.Errorf("%s(): param nr %d has wrong type %T, number expected", funcName, paramPos+1, paramValue) } return } func doAdd(ctx ExprContext, name string, it Iterator) (result any, err error) { var sumAsFloat = false var floatSum float64 = 0.0 var intSum int64 = 0 var v any for v, err = it.Next(); err == nil; v, err = it.Next() { if err = checkNumberParamExpected(name, v, it.Index()); err != nil { break } if array, ok := v.([]any); ok { if v, err = doAdd(ctx, name, NewFlatArrayIterator(array)); err != nil { break } } if !sumAsFloat && isFloat(v) { sumAsFloat = true floatSum = float64(intSum) } if sumAsFloat { floatSum += numAsFloat(v) } else { iv, _ := v.(int64) intSum += iv } } if err == nil || err == io.EOF { err = nil if sumAsFloat { result = floatSum } else { result = intSum } } return } func addFunc(ctx ExprContext, name string, args []any) (result any, err error) { result, err = doAdd(ctx, name, NewFlatArrayIterator(args)) return } func doMul(ctx ExprContext, name string, it Iterator) (result any, err error) { var mulAsFloat = false var floatProd float64 = 1.0 var intProd int64 = 1 var v any for v, err = it.Next(); err == nil; v, err = it.Next() { if err = checkNumberParamExpected(name, v, it.Index()); err != nil { break } if array, ok := v.([]any); ok { if v, err = doAdd(ctx, name, NewFlatArrayIterator(array)); err != nil { break } } if !mulAsFloat && isFloat(v) { mulAsFloat = true floatProd = float64(intProd) } if mulAsFloat { floatProd *= numAsFloat(v) } else { iv, _ := v.(int64) intProd *= iv } } if err == nil || err == io.EOF { err = nil if mulAsFloat { result = floatProd } else { result = intProd } } return } func mulFunc(ctx ExprContext, name string, args []any) (result any, err error) { result, err = doMul(ctx, name, NewFlatArrayIterator(args)) return } func ImportMathFuncs(ctx ExprContext) { ctx.RegisterFunc("add", &simpleFunctor{f: addFunc}, 0, -1) ctx.RegisterFunc("mul", &simpleFunctor{f: mulFunc}, 0, -1) }