diff --git a/data-cursor.go b/data-cursor.go index ea72d66..cff0c0d 100644 --- a/data-cursor.go +++ b/data-cursor.go @@ -85,7 +85,7 @@ func (dc *dataCursor) HasOperation(name string) (exists bool) { return } -func (dc *dataCursor) CallOperation(name string, args []any) (value any, err error) { +func (dc *dataCursor) CallOperation(name string, args map[string]any) (value any, err error) { if name == IndexName { value = int64(dc.Index()) } else if functor, ok := dc.ds[name]; ok && isFunctor(functor) { @@ -95,7 +95,7 @@ func (dc *dataCursor) CallOperation(name string, args []any) (value any, err err value, err = dc.Reset() } else { ctx := cloneContext(dc.ctx) - value, err = functor.InvokeNamed(ctx, name, map[string]any{}) + value, err = functor.InvokeNamed(ctx, name, args) exportObjects(dc.ctx, ctx) } } else { @@ -239,16 +239,3 @@ func (dc *dataCursor) Count() int { return dc.count } - -func buildActualParams(functor Functor, args []any) (actualParams map[string]any) { - formalParams := functor.GetParams() - actualParams = make(map[string]any, len(formalParams)) - for i, spec := range formalParams { - if i < len(formalParams) { - actualParams[spec.Name()] = args[i] - } else { - actualParams[spec.Name()] = nil - } - } - return -} diff --git a/function.go b/function.go index 3f8dbaf..c0a29bf 100644 --- a/function.go +++ b/function.go @@ -6,6 +6,7 @@ package expr import ( "fmt" + "strconv" "strings" ) @@ -223,13 +224,17 @@ func (info *funcInfo) checkExistingParam(paramName string) (exists bool) { return } -func (info *funcInfo) initActualParams(ctx ExprContext, name string, callTerm *term) (params map[string]any, err error) { +func (info *funcInfo) initActualParams(ctx ExprContext, name string, callTerm *term) (actualParams map[string]any, err error) { var varArgs []any var varName string namedParamsStarted := false - actualParams := make(map[string]any, len(info.formalParams)) + actualParams = make(map[string]any, len(info.formalParams)) + if callTerm == nil { + return + } + for i, tree := range callTerm.children { var paramValue any paramCtx := ctx.Clone() @@ -268,7 +273,6 @@ func (info *funcInfo) initActualParams(ctx ExprContext, name string, callTerm *t if varArgs != nil { actualParams[varName] = varArgs } - params = actualParams } return } @@ -319,7 +323,7 @@ func getAssignVarName(t *term) (name string, ok bool) { return } -func CallFunction3(parentCtx ExprContext, name string, callTerm *term) (result any, err error) { +func CallFunction(parentCtx ExprContext, name string, callTerm *term) (result any, err error) { var actualParams map[string]any if info, exists := GetFuncInfo(parentCtx, name); exists { var ctx ExprContext @@ -333,3 +337,25 @@ func CallFunction3(parentCtx ExprContext, name string, callTerm *term) (result a } return } + +func GetParam(args map[string]any, paramName string, paramNum int) (value any, exists bool) { + if value, exists = args[paramName]; !exists { + if paramNum > 0 && paramNum <= len(args) { + value, exists = args["arg"+strconv.Itoa(paramNum)] + } + } + return +} + +func buildActualParams(functor Functor, args []any) (actualParams map[string]any) { + formalParams := functor.GetParams() + actualParams = make(map[string]any, len(args)) + for i, arg := range args { + if i < len(formalParams) { + actualParams[formalParams[i].Name()] = arg + } else { + actualParams["arg"+strconv.Itoa(i+1)] = arg + } + } + return +}