Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 382cb7aabd | |||
| dd9aa5d52d | |||
| 1d15b99740 |
+12
-2
@@ -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 = map[string]any{kern.ParamIndex: it.Index(), kern.ParamItem: item}
|
||||||
params[kern.ParamIndex] = it.Index()
|
params[kern.ParamIndex] = it.Index()
|
||||||
params[kern.ParamItem] = item
|
params[kern.ParamItem] = item
|
||||||
|
|
||||||
|
localCtx.UnsafeSetVar("_", it.Index())
|
||||||
|
localCtx.UnsafeSetVar("__", item)
|
||||||
|
|
||||||
|
abort := false
|
||||||
if _, err = op.InvokeNamed(localCtx, iterParamOperator, params); err != nil {
|
if _, err = op.InvokeNamed(localCtx, iterParamOperator, params); err != nil {
|
||||||
break
|
abort = true
|
||||||
} else if abortAny, exists := localCtx.GetVar(iterVarAbort); exists {
|
} else if abortAny, exists := localCtx.GetVar(iterVarAbort); exists {
|
||||||
if abort, ok := boolean.ToBool(abortAny); ok && abort {
|
if abort, ok := boolean.ToBool(abortAny); ok && abort {
|
||||||
break
|
abort = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
localCtx.DeleteVar("__")
|
||||||
|
localCtx.DeleteVar("_")
|
||||||
|
if abort {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-1
@@ -1583,7 +1583,33 @@ Module activation: +
|
|||||||
Syntax: +
|
Syntax: +
|
||||||
`{4sp}run(<iterator>, <operator>, <vars>) -> any`
|
`{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 "math.arith"
|
||||||
Module activation: +
|
Module activation: +
|
||||||
|
|||||||
+18
-17
@@ -17,6 +17,8 @@ import (
|
|||||||
type IntIterator struct {
|
type IntIterator struct {
|
||||||
count int64
|
count int64
|
||||||
index int64
|
index int64
|
||||||
|
next int64
|
||||||
|
current any
|
||||||
start int64
|
start int64
|
||||||
stop int64
|
stop int64
|
||||||
step 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) {
|
func (it *IntIterator) Current() (item any, err error) {
|
||||||
if it.start <= it.stop {
|
return it.current, nil
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (it *IntIterator) Next() (item any, err error) {
|
func (it *IntIterator) Next() (item any, err error) {
|
||||||
it.index += it.step
|
item = it.next
|
||||||
if item, err = it.Current(); err != io.EOF {
|
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.count++
|
||||||
|
it.next += it.step
|
||||||
|
it.current = item
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -143,7 +142,9 @@ func (it *IntIterator) Count() int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (it *IntIterator) Reset() error {
|
func (it *IntIterator) Reset() error {
|
||||||
it.index = it.start - it.step
|
it.index = -1
|
||||||
|
it.next = it.start
|
||||||
|
it.current = nil
|
||||||
it.count = 0
|
it.count = 0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -45,9 +45,10 @@ func TestIteratorParser(t *testing.T) {
|
|||||||
/* 26 */ {`it=$(1..5..2); it++`, int64(1), nil},
|
/* 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)`},
|
/* 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)`},
|
/* 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)
|
RunTestSuite(t, section, inputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user