// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). // All rights reserved. // operator-selector.go package expr //-------- selector term func newSelectorTerm(tk *Token) (inst *term) { return &term{ tk: *tk, children: make([]*term, 0, 3), position: posInfix, priority: priSelector, evalFunc: evalSelector, } } func trySelectorCase(ctx ExprContext, exprValue, caseSel any, caseIndex int) (match bool, selectedValue any, err error) { caseData, _ := caseSel.(*selectorCase) if caseData.filterList == nil { selectedValue, err = caseData.caseExpr.eval(ctx, false) match = true } else if filterList, ok := caseData.filterList.value().([]*term); ok { if len(filterList) == 0 && exprValue == int64(caseIndex) { selectedValue, err = caseData.caseExpr.eval(ctx, false) match = true } else { var caseValue any for _, caseTerm := range filterList { if caseValue, err = caseTerm.compute(ctx); err != nil || caseValue == exprValue { selectedValue, err = caseData.caseExpr.eval(ctx, false) match = true break } } } } return } func evalSelector(ctx ExprContext, self *term) (v any, err error) { var exprValue any var match bool if err = self.checkOperands(); err != nil { return } exprTerm := self.children[0] if exprValue, err = exprTerm.compute(ctx); err != nil { return } caseListTerm := self.children[1] caseList, _ := caseListTerm.value().([]*term) for i, caseTerm := range caseList { caseSel := caseTerm.value() if match, v, err = trySelectorCase(ctx, exprValue, caseSel, i); err != nil || match { break } } if err == nil && !match { err = exprTerm.tk.Errorf("no case catches the value (%v) of the selection expression", exprValue) } return } // init func init() { registerTermConstructor(SymSelector, newSelectorTerm) }