Iterator operator: automatic temporary variables _index and _count changed with '__' and '_#' respectively. Note that, sinc '#' is not an identifier allowed char, '_#' requires himBHsnotation: -cover

This commit is contained in:
Celestino Amoroso 2026-05-02 15:06:12 +02:00
parent 3b2ef7927b
commit 2ebc52891c
4 changed files with 14 additions and 13 deletions

View File

@ -43,8 +43,8 @@ func evalDigest(ctx kern.ExprContext, opTerm *term) (v any, err error) {
lastValue = nil lastValue = nil
for item, err = it.Next(); err == nil; item, err = it.Next() { for item, err = it.Next(); err == nil; item, err = it.Next() {
ctx.SetVar("_", item) ctx.SetVar("_", item)
ctx.SetVar("_index", it.Index()) ctx.SetVar("__", it.Index())
ctx.SetVar("_count", it.Count()) ctx.SetVar("_#", it.Count())
if rightValue, err = opTerm.children[1].Compute(ctx); err == nil { if rightValue, err = opTerm.children[1].Compute(ctx); err == nil {
if rightValue == nil { if rightValue == nil {
break break
@ -52,8 +52,8 @@ func evalDigest(ctx kern.ExprContext, opTerm *term) (v any, err error) {
lastValue = rightValue lastValue = rightValue
} }
} }
ctx.DeleteVar("_count") ctx.DeleteVar("_#")
ctx.DeleteVar("_index") ctx.DeleteVar("__")
ctx.DeleteVar("_") ctx.DeleteVar("_")
if err != nil { if err != nil {
break break

View File

@ -43,8 +43,8 @@ func evalFilter(ctx kern.ExprContext, opTerm *term) (v any, err error) {
values := kern.NewListA() values := kern.NewListA()
for item, err = it.Next(); err == nil; item, err = it.Next() { for item, err = it.Next(); err == nil; item, err = it.Next() {
ctx.SetVar("_", item) ctx.SetVar("_", item)
ctx.SetVar("_index", it.Index()) ctx.SetVar("__", it.Index())
ctx.SetVar("_count", it.Count()) ctx.SetVar("_#", it.Count())
if rightValue, err = opTerm.children[1].Compute(ctx); err == nil { if rightValue, err = opTerm.children[1].Compute(ctx); err == nil {
if success, valid := kern.ToBool(rightValue); valid { if success, valid := kern.ToBool(rightValue); valid {
if success { if success {
@ -54,8 +54,8 @@ func evalFilter(ctx kern.ExprContext, opTerm *term) (v any, err error) {
err = fmt.Errorf("filter expression must return a boolean or a castable to boolean, got %v [%T]", rightValue, rightValue) err = fmt.Errorf("filter expression must return a boolean or a castable to boolean, got %v [%T]", rightValue, rightValue)
} }
} }
ctx.DeleteVar("_count") ctx.DeleteVar("_#")
ctx.DeleteVar("_index") ctx.DeleteVar("__")
ctx.DeleteVar("_") ctx.DeleteVar("_")
if err != nil { if err != nil {
break break

View File

@ -43,13 +43,13 @@ func evalMap(ctx kern.ExprContext, opTerm *term) (v any, err error) {
values := kern.NewListA() values := kern.NewListA()
for item, err = it.Next(); err == nil; item, err = it.Next() { for item, err = it.Next(); err == nil; item, err = it.Next() {
ctx.SetVar("_", item) ctx.SetVar("_", item)
ctx.SetVar("_index", it.Index()) ctx.SetVar("__", it.Index())
ctx.SetVar("_count", it.Count()) ctx.SetVar("_#", it.Count())
if rightValue, err = opTerm.children[1].Compute(ctx); err == nil { if rightValue, err = opTerm.children[1].Compute(ctx); err == nil {
values.AppendItem(rightValue) values.AppendItem(rightValue)
} }
ctx.DeleteVar("_count") ctx.DeleteVar("_#")
ctx.DeleteVar("_index") ctx.DeleteVar("__")
ctx.DeleteVar("_") ctx.DeleteVar("_")
if err != nil { if err != nil {
break break

View File

@ -35,7 +35,7 @@ func TestIteratorParser(t *testing.T) {
/* 20 */ {`it=$({1:"one",2:"two",3:"three"}, "default", "value"); it++`, "one", nil}, /* 20 */ {`it=$({1:"one",2:"two",3:"three"}, "default", "value"); it++`, "one", nil},
/* 21 */ {`it=$({1:"one",2:"two",3:"three"}, "desc", "key"); it++`, int64(3), nil}, /* 21 */ {`it=$({1:"one",2:"two",3:"three"}, "desc", "key"); it++`, int64(3), nil},
/* 22 */ {`it=$({1:"one",2:"two",3:"three"}, "asc", "item"); it++`, kern.NewList([]any{int64(1), "one"}), nil}, /* 22 */ {`it=$({1:"one",2:"two",3:"three"}, "asc", "item"); it++`, kern.NewList([]any{int64(1), "one"}), nil},
/* 23 */ {`builtin "os.file"; fileReadIterator("test-file.txt") map ${_index}`, kern.NewList([]any{int64(0), int64(1)}), nil}, /* 23 */ {`builtin "os.file"; fileReadIterator("test-file.txt") map ${__}`, kern.NewList([]any{int64(0), int64(1)}), nil},
/* 24 */ {`builtin "os.file"; #(fileReadIterator("test-file.txt") filter (#${_} == 2))`, int64(0), nil}, /* 24 */ {`builtin "os.file"; #(fileReadIterator("test-file.txt") filter (#${_} == 2))`, int64(0), nil},
/* 25 */ {`builtin "os.file"; #(fileReadIterator("test-file.txt") filter (#${_} == 3))`, int64(2), nil}, /* 25 */ {`builtin "os.file"; #(fileReadIterator("test-file.txt") filter (#${_} == 3))`, int64(2), nil},
/* 26 */ {`#($(10) map ${_})`, int64(10), nil}, /* 26 */ {`#($(10) map ${_})`, int64(10), nil},
@ -43,6 +43,7 @@ func TestIteratorParser(t *testing.T) {
/* 28 */ {`$(10) digest ${_}`, int64(9), nil}, /* 28 */ {`$(10) digest ${_}`, int64(9), nil},
/* 29 */ {`$(10,0) digest ${_}`, int64(1), nil}, /* 29 */ {`$(10,0) digest ${_}`, int64(1), nil},
/* 30 */ {`$(10,0,-2) digest ${_}`, int64(2), nil}, /* 30 */ {`$(10,0,-2) digest ${_}`, int64(2), nil},
/* 31 */ {`[3,4,5] map ${_#}`, kern.NewList([]any{int64(1), int64(2), int64(3)}), nil},
} }
// runTestSuiteSpec(t, section, inputs, 10) // runTestSuiteSpec(t, section, inputs, 10)