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