diff --git a/env.go b/env.go index dc18a68..0d1e08e 100644 --- a/env.go +++ b/env.go @@ -82,6 +82,12 @@ var baseEnv = initBaseEnv(map[string]Extension{ EvalContextHandler: nil, }, + "eval": { + Func: RunEval, + UndefinedHandler: defaultUndefinedHandler, + EvalContextHandler: defaultContextHandler, + }, + "unescape": { Func: jlib.Unescape, UndefinedHandler: defaultUndefinedHandler, @@ -410,12 +416,6 @@ var baseEnv = initBaseEnv(map[string]Extension{ UndefinedHandler: nil, EvalContextHandler: nil, }, - - "eval": { - Func: RunEval, - UndefinedHandler: defaultUndefinedHandler, - EvalContextHandler: defaultContextHandler, - }, }) func initBaseEnv(exts map[string]Extension) *environment { @@ -473,7 +473,6 @@ func undefinedHandlerAppend(argv []reflect.Value) bool { // Context handlers func contextHandlerSubstring(argv []reflect.Value) bool { - // If substring() is called with one or two numeric arguments, // use the evaluation context as the first argument. switch len(argv) { diff --git a/jsonata.go b/jsonata.go index c795278..0a3111c 100644 --- a/jsonata.go +++ b/jsonata.go @@ -180,29 +180,74 @@ func (e *Expr) EvalBytes(data []byte) ([]byte, error) { return json.Marshal(v) } -func RunEval(expression string) (interface{}, error) { +func RunEval(initialContext reflect.Value, expression ...interface{}) (interface{}, error) { var s evaluator s = simple{} - return s.Eval(expression) + var result interface{} + + var err error + + if len(expression) == 0 { + result, err = s.InitialEval(initialContext.Interface(), "$$") + if err != nil { + return nil, err + } + } + + for index := range expression { + expressionStr, ok := expression[index].(string) + if !ok { + return nil, fmt.Errorf("%v not able to be used as a string in eval statement", expression[index]) + } + if index == 0 { + result, err = s.InitialEval(initialContext.Interface(), expressionStr) + if err != nil { + return nil, err + } + continue + } + + result, err = s.InitialEval(result, expressionStr) + if err != nil { + return nil, err + } + } + + return result, nil } type evaluator interface { - Eval(expression string) (interface{}, error) + InitialEval(item interface{}, expression string) (interface{}, error) + Eval(override, expression string) (interface{}, error) } type simple struct { } -func (s simple) Eval(expression string) (interface{}, error) { +func (s simple) InitialEval(item interface{}, expression string) (interface{}, error) { + expr, err := Compile(expression) + if err != nil { + return nil, err + } + + result, err := expr.Eval(item) + if err != nil { + return nil, err + } + + return result, nil +} + +func (s simple) Eval(override, expression string) (interface{}, error) { expr, err := Compile(expression) if err != nil { return nil, err } - result, err := expr.Eval(``) + result, err := expr.Eval(override) if err != nil { return nil, err }