diff --git a/data-cursor.go b/data-cursor.go index fc6c44d..388140e 100644 --- a/data-cursor.go +++ b/data-cursor.go @@ -133,7 +133,7 @@ func (dc *dataCursor) Current() (item any, err error) { // must return io.EOF at return } -func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after the last item +func (dc *dataCursor) _Next() (item any, err error) { // must return io.EOF after the last item if dc.resource != nil { ctx := cloneContext(dc.ctx) // fmt.Printf("Entering Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0)) @@ -153,6 +153,40 @@ func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after return } +const filterName = "filter" +func (dc *dataCursor) filter(item any) (filterdItem any, err error) { + if filter, ok := dc.ds[filterName]; ok { + ctx := cloneContext(dc.ctx) + filterdItem, err = filter.Invoke(ctx, filterName, []any{item, dc.index}); + } else { + filterdItem = item + } + return +} + +func (dc *dataCursor) Next() (item any, err error) { // must return io.EOF after the last item + if dc.resource != nil { + ctx := cloneContext(dc.ctx) + // fmt.Printf("Entering Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0)) + for item == nil && err == nil { + if item, err = dc.nextFunc.Invoke(ctx, nextName, []any{dc.resource}); err == nil { + if item == nil { + err = io.EOF + } else { + dc.index++ + item, err = dc.filter(item) + } + } + } + // fmt.Printf("Exiting Inner-Ctx [%p]: %s\n", ctx, CtxToString(ctx, 0)) + exportObjects(dc.ctx, ctx) + // fmt.Printf("Outer-Ctx [%p]: %s\n", dc.ctx, CtxToString(dc.ctx, 0)) + } else { + err = errInvalidDataSource() + } + return +} + func (dc *dataCursor) Index() int { return dc.index } diff --git a/t_funcs_test.go b/t_funcs_test.go index 09fc220..cebcb51 100644 --- a/t_funcs_test.go +++ b/t_funcs_test.go @@ -30,12 +30,13 @@ func TestFuncs(t *testing.T) { /* 17 */ {`f=func(x,n){1}; f(3,4,)`, nil, `[1:24] expected "function-param-value", got ")"`}, /* 18 */ {`factory=func(base){func(){@base=base+1}}; inc10=factory(10); inc5=factory(5); inc10(); inc5(); inc10()`, int64(12), nil}, /* 19 */ {`f=func(a,y=1,z="sos"){}; string(f)`, `f(a, y=1, z="sos"):any{}`, nil}, +// /* 20 */ {`m={}; m["f"]=func(){3}; m["f"]()`, int64(3), nil}, // /* 18 */ {`f=func(a){a*2}`, nil, errors.New(`[1:24] expected "function-param-value", got ")"`)}, } // t.Setenv("EXPR_PATH", ".") - // runTestSuiteSpec(t, section, inputs, 17) + // runTestSuiteSpec(t, section, inputs, 20) runTestSuite(t, section, inputs) } @@ -52,6 +53,7 @@ func TestFunctionToStringSimple(t *testing.T) { } } + func TestFunctionGetFunc(t *testing.T) { source := NewGolangFunctor(dummy) want := ExprFunc(nil) diff --git a/term.go b/term.go index 62af546..eb4e8fc 100644 --- a/term.go +++ b/term.go @@ -145,7 +145,7 @@ func (term *term) value() any { func (term *term) compute(ctx ExprContext) (v any, err error) { if term.evalFunc == nil { - err = term.tk.Errorf("undefined eval-func for %q term", term.source()) + err = term.Errorf("undefined eval-func for %q term", term.source()) } else { v, err = term.evalFunc(ctx, term) }