From 6d8c6f5154af5c4fe9fd55e9022123209d2f9675 Mon Sep 17 00:00:00 2001 From: Celestino Amoroso Date: Thu, 28 Mar 2024 06:32:37 +0100 Subject: [PATCH] helpers.go provides easy functions to parse and evaluate expressions --- helpers.go | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 helpers.go diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..f62e5f7 --- /dev/null +++ b/helpers.go @@ -0,0 +1,57 @@ +// helpers.go +package expr + +import ( + "fmt" + "strings" +) + +func EvalString(ctx exprContext, source string) (result any, err error) { + var tree *ast + + r := strings.NewReader(source) + scanner := NewScanner(r, DefaultTranslations()) + parser := NewParser(ctx) + + if tree, err = parser.parse(scanner); err == nil { + result, err = tree.eval(ctx) + } + return +} + +type EvalArg struct { + name string + value any +} + +func EvalStringA(source string, args ...EvalArg) (result any, err error) { + return EvalStringV(source, args) +} + +func EvalStringV(source string, args []EvalArg) (result any, err error) { + ctx := NewSimpleFuncStore() + for _, arg := range args { + if isFunc(arg.value) { + if f, ok := arg.value.(FuncTemplate); ok { + ctx.addFunc(arg.name, f) + } else { + err = fmt.Errorf("invalid function specification: %q", arg.name) + } + } else if integer, ok := anyInteger(arg.value); ok { + ctx.SetValue(arg.name, integer) + } else if float, ok := anyFloat(arg.value); ok { + ctx.SetValue(arg.name, float) + } else if _, ok := arg.value.(string); ok { + ctx.SetValue(arg.name, arg.value) + } else if _, ok := arg.value.(bool); ok { + ctx.SetValue(arg.name, arg.value) + } else { + err = fmt.Errorf("unsupported type %T specified for item %q", arg.value, arg.name) + } + } + + if err == nil { + result, err = EvalString(ctx, source) + } + return +}