Compare commits

..

3 Commits

4 changed files with 64 additions and 26 deletions
+12 -2
View File
@@ -92,13 +92,23 @@ func runFunc(ctx kern.ExprContext, name string, args map[string]any) (result any
// params = map[string]any{kern.ParamIndex: it.Index(), kern.ParamItem: item}
params[kern.ParamIndex] = it.Index()
params[kern.ParamItem] = item
localCtx.UnsafeSetVar("_", it.Index())
localCtx.UnsafeSetVar("__", item)
abort := false
if _, err = op.InvokeNamed(localCtx, iterParamOperator, params); err != nil {
break
abort = true
} else if abortAny, exists := localCtx.GetVar(iterVarAbort); exists {
if abort, ok := boolean.ToBool(abortAny); ok && abort {
break
abort = true
}
}
localCtx.DeleteVar("__")
localCtx.DeleteVar("_")
if abort {
break
}
}
}
+27 -1
View File
@@ -1583,7 +1583,33 @@ Module activation: +
Syntax: +
`{4sp}run(<iterator>, <operator>, <vars>) -> any`
Iterates over the specified iterator and applies the specified operator to the current value of the iterator.
where:
[horizontal]
iterator:: is any iterator.
operator:: is a function that accepts two optional parameters: _index_ and _item_.
vars:: is a dictionary defining a set of variables that are used to initialize the local context of run() and that will be inherited by each call to the operator.
TIP: Instead of using _index_ and _item_ parameter, the operator function can refere the two automatic variables `$_` and `$__` respectively.
_run()_ iterates over the specified iterator and applies the specified operator to the current value of the iterator.
It returns the value of the variable _status_ it defined, otherwise _nil_.
In addition to the variables defined in vars, the local context includes the function _abort()_. The operator can call _abort()_ to terminate iterations.
_abort()_ accepts the optional parameter _status_ used to change the value of of the variable of the same name and, therefore, of the value returned by _run()_.
.Examples
`>>>` [blue]`builtin "iterator"` [gray]__// enable the iterator builtin module__ +
[green]`1` +
`>>>` [blue]`run($(10..15), func(){status = $\_})` [gray]__// returns the last iteration's index__ +
[green]`4` +
`>>>` [blue]`run($(10..15), func(){status = $__})` [gray]_// returns the last iteration's item_ +
[green]`14` +
`>>>` [blue]`run($(1..5), func(index,item){ (index > 3) ? {abort()} :: {status = item} })` +
[green]`4` +
`>>>` [blue]`run($(1..5), func(index,item){ (index > 2) ? {abort("aborted")} :: {status = item} })` +
[green]`aborted`
==== Module "math.arith"
Module activation: +
+18 -17
View File
@@ -17,6 +17,8 @@ import (
type IntIterator struct {
count int64
index int64
next int64
current any
start int64
stop int64
step int64
@@ -110,26 +112,23 @@ func (it *IntIterator) CallOperation(name string, args map[string]any) (v any, e
}
func (it *IntIterator) Current() (item any, err error) {
if it.start <= it.stop {
if it.index >= it.start && it.index < it.stop {
item = it.index
} else {
err = io.EOF
}
} else {
if it.index > it.stop && it.index <= it.start {
item = it.index
} else {
err = io.EOF
}
}
return
return it.current, nil
}
func (it *IntIterator) Next() (item any, err error) {
it.index += it.step
if item, err = it.Current(); err != io.EOF {
item = it.next
if it.step > 0 {
if it.next+it.step > it.stop {
err = io.EOF
}
} else if it.next+it.step < it.stop {
err = io.EOF
}
if err == nil {
it.index++
it.count++
it.next += it.step
it.current = item
}
return
}
@@ -143,7 +142,9 @@ func (it *IntIterator) Count() int64 {
}
func (it *IntIterator) Reset() error {
it.index = it.start - it.step
it.index = -1
it.next = it.start
it.current = nil
it.count = 0
return nil
}
+2 -1
View File
@@ -45,9 +45,10 @@ func TestIteratorParser(t *testing.T) {
/* 26 */ {`it=$(1..5..2); it++`, int64(1), nil},
/* 27 */ {`it=$(1.5..5..2); it++`, nil, `[1:13] interval expression expected integer, got float (1.5)`},
/* 28 */ {`it=$(.."z"); it++`, nil, `[1:7] interval expression expected integer, got string (z)`},
/* 29 */ {`it=$(3..1); it++; it.index`, int64(0), nil},
}
// RunTestSuiteSpec(t, section, inputs, 27)
// RunTestSuiteSpec(t, section, inputs, 25)
RunTestSuite(t, section, inputs)
}