// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // helpers.go package expr import ( "fmt" "io" "os" "strings" "git.portale-stac.it/go-pkg/expr/kern" "git.portale-stac.it/go-pkg/expr/util" ) func EvalString(ctx kern.ExprContext, source string) (result any, err error) { var tree *ast r := strings.NewReader(source) scanner := NewScanner(r, DefaultTranslations()) parser := NewParser() if tree, err = parser.Parse(scanner); err == nil { result, err = tree.Eval(ctx) } return } type Arg struct { Name string Value any } func EvalStringA(source string, args ...Arg) (result any, err error) { return EvalStringV(source, args) } func EvalStringV(source string, args []Arg) (result any, err error) { ctx := NewSimpleStoreWithoutGlobalContext() for _, arg := range args { if util.IsFunc(arg.Value) { if f, ok := arg.Value.(kern.FuncTemplate); ok { functor := kern.NewGolangFunctor(f) // ctx.RegisterFunc(arg.Name, functor, 0, -1) ctx.RegisterFunc(arg.Name, functor, kern.TypeAny, []kern.ExprFuncParam{ NewFuncParamFlagDef(kern.ParamValue, PfDefault|PfRepeat, 0), }) } else { err = fmt.Errorf("invalid function specification: %q", arg.Name) } } else if integer, ok := kern.AnyInteger(arg.Value); ok { ctx.SetVar(arg.Name, integer) } else if float, ok := kern.AnyFloat(arg.Value); ok { ctx.SetVar(arg.Name, float) } else if _, ok := arg.Value.(string); ok { ctx.SetVar(arg.Name, arg.Value) } else if _, ok := arg.Value.(bool); ok { ctx.SetVar(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 } func EvalStream(ctx kern.ExprContext, r io.Reader) (result any, err error) { var tree *ast scanner := NewScanner(r, DefaultTranslations()) parser := NewParser() if tree, err = parser.Parse(scanner); err == nil { result, err = tree.Eval(ctx) } return } func EvalFile(ctx kern.ExprContext, filePath string) (result any, err error) { var fh *os.File if fh, err = os.Open(filePath); err != nil { return nil, err } defer fh.Close() result, err = EvalStream(ctx, fh) return }