// funcs-math.go package expr import ( "fmt" "io" ) // func addFunc(ctx exprContext, name string, args []any) (result any, err error) { // var sumAsFloat = false // var floatSum float64 = 0.0 // var intSum int64 = 0 // for i, v := range args { // if !isNumber(v) { // err = fmt.Errorf("add(): param nr %d has wrong type %T, number expected", i+1, v) // break // } // if !sumAsFloat && isFloat(v) { // sumAsFloat = true // floatSum = float64(intSum) // } // if sumAsFloat { // floatSum += numAsFloat(v) // } else { // iv, _ := v.(int64) // intSum += iv // } // } // if err == nil { // if sumAsFloat { // result = floatSum // } else { // result = intSum // } // } // return // } 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", addFunc, 0, -1) ctx.RegisterFunc("mul", mulFunc, 0, -1) }