88 lines
2.0 KiB
Go
88 lines
2.0 KiB
Go
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
// All rights reserved.
|
|
|
|
// helpers.go
|
|
package expr
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func EvalString(ctx 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 := NewSimpleStore()
|
|
for _, arg := range args {
|
|
if isFunc(arg.Value) {
|
|
if f, ok := arg.Value.(FuncTemplate); ok {
|
|
functor := NewGolangFunctor(f)
|
|
// ctx.RegisterFunc(arg.Name, functor, 0, -1)
|
|
ctx.RegisterFunc(arg.Name, functor, TypeAny, []ExprFuncParam{
|
|
NewFuncParamFlagDef(ParamValue, PfDefault|PfRepeat, 0),
|
|
})
|
|
} else {
|
|
err = fmt.Errorf("invalid function specification: %q", arg.Name)
|
|
}
|
|
} else if integer, ok := anyInteger(arg.Value); ok {
|
|
ctx.SetVar(arg.Name, integer)
|
|
} else if float, ok := 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 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 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
|
|
}
|