// 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) match = true } else if filterList, ok := caseData.filterList.value().([]*term); ok { if len(filterList) == 0 { var valueAsInt = int64(0) if b, ok := exprValue.(bool); ok { if !b { valueAsInt = 1 } } else if valueAsInt, ok = exprValue.(int64); !ok { return } if valueAsInt == int64(caseIndex) { selectedValue, err = caseData.caseExpr.Eval(ctx) 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) match = true break } } } } return } func evalSelector(ctx ExprContext, opTerm *term) (v any, err error) { var exprValue any var match bool if err = opTerm.checkOperands(); err != nil { return } exprTerm := opTerm.children[0] if exprValue, err = exprTerm.compute(ctx); err != nil { return } caseListTerm := opTerm.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) }