2021-08-29 09:13:12 +00:00
|
|
|
package eval
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"strings"
|
|
|
|
|
2021-08-30 01:19:34 +00:00
|
|
|
"github.com/antonmedv/expr"
|
2021-08-31 23:29:04 +00:00
|
|
|
"github.com/antonmedv/expr/ast"
|
2021-08-29 09:13:12 +00:00
|
|
|
)
|
|
|
|
|
2021-08-31 23:29:04 +00:00
|
|
|
// AST Visitor that changes Integer to Float
|
|
|
|
type patcher struct{}
|
|
|
|
|
|
|
|
func (p *patcher) Enter(_ *ast.Node) {}
|
|
|
|
func (p *patcher) Exit(node *ast.Node) {
|
|
|
|
n, ok := (*node).(*ast.IntegerNode)
|
|
|
|
if ok {
|
|
|
|
ast.Patch(node, &ast.FloatNode{Value: float64(n.Value)})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-01 07:03:36 +00:00
|
|
|
// EvaluateExpressionToFloat64 evaulates a simple math expression string to a float64
|
2021-09-01 00:35:23 +00:00
|
|
|
func EvaluateExpressionToFloat64(input string, env interface{}) (float64, error) {
|
2021-08-31 23:29:04 +00:00
|
|
|
input = strings.TrimSpace(input)
|
2021-08-29 10:22:14 +00:00
|
|
|
if input == "" {
|
2021-08-29 09:13:12 +00:00
|
|
|
return 0, nil
|
|
|
|
}
|
2021-09-01 00:35:23 +00:00
|
|
|
program, err := expr.Compile(input, expr.Env(env), expr.Patch(&patcher{}))
|
2021-08-31 23:29:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
2021-09-01 00:35:23 +00:00
|
|
|
result, err := expr.Run(program, env)
|
2021-08-29 09:13:12 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
f64, ok := result.(float64)
|
|
|
|
if !ok {
|
2021-09-01 00:35:23 +00:00
|
|
|
ival, ok := result.(int)
|
|
|
|
if !ok {
|
|
|
|
return 0, errors.New("expression did not return numeric type")
|
|
|
|
}
|
|
|
|
f64 = float64(ival)
|
2021-08-29 09:13:12 +00:00
|
|
|
}
|
|
|
|
return f64, nil
|
|
|
|
}
|