// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // operator-map.go package expr import ( "fmt" "io" ) //-------- map term func newMapTerm(tk *Token) (inst *term) { return &term{ tk: *tk, children: make([]*term, 0, 2), position: posInfix, priority: priIterOp, evalFunc: evalMap, } } func evalMap(ctx ExprContext, opTerm *term) (v any, err error) { var leftValue, rightValue any var it Iterator var item any if err = opTerm.checkOperands(); err != nil { return } if leftValue, err = opTerm.children[0].compute(ctx); err != nil { return } if it, err = NewIterator(leftValue); err != nil { return nil, fmt.Errorf("left operand of MAP must be an iterable data-source; got %s", TypeName(leftValue)) } values := newListA() for item, err = it.Next(); err == nil; item, err = it.Next() { ctx.SetVar("_", item) ctx.SetVar("_index", it.Index()) ctx.SetVar("_count", it.Count()) if rightValue, err = opTerm.children[1].compute(ctx); err == nil { values.appendItem(rightValue) } ctx.DeleteVar("_count") ctx.DeleteVar("_index") ctx.DeleteVar("_") if err != nil { break } } if err == io.EOF { err = nil } v = values return } // init func init() { registerTermConstructor(SymKwMap, newMapTerm) }