expr/operator-dot.go

70 lines
1.7 KiB
Go

// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
// All rights reserved.
// operator-dot.go
package expr
import (
"git.portale-stac.it/go-pkg/expr/kern"
)
// -------- dot term
func newDotTerm(tk *Token) (inst *term) {
return &term{
tk: *tk,
children: make([]*term, 0, 2),
position: posInfix,
priority: priDot,
evalFunc: evalDot,
}
}
func evalDot(ctx kern.ExprContext, opTerm *term) (v any, err error) {
var leftValue, rightValue any
if err = opTerm.checkOperands(); err != nil {
return
}
if leftValue, err = opTerm.children[0].Compute(ctx); err != nil {
return
}
indexTerm := opTerm.children[1]
switch unboxedValue := leftValue.(type) {
case kern.ExtIterator:
if indexTerm.symbol() == SymVariable /*|| indexTerm.symbol() == SymString */ {
opName := indexTerm.Source()
if unboxedValue.HasOperation(opName) {
v, err = unboxedValue.CallOperation(opName, map[string]any{})
} else {
err = indexTerm.Errorf("this iterator do not support the %q command", opName)
v = false
}
} else {
err = indexTerm.tk.ErrorExpectedGot("identifier")
}
case *kern.DictType:
s := opTerm.children[1].symbol()
if s == SymVariable || s == SymString {
src := opTerm.children[1].Source()
if len(src) > 1 && src[0] == '"' && src[len(src)-1] == '"' {
src = src[1 : len(src)-1]
}
v, err = unboxedValue.GetItem(src)
} else if rightValue, err = opTerm.children[1].Compute(ctx); err == nil {
v, err = unboxedValue.GetItem(rightValue)
}
default:
if rightValue, err = opTerm.children[1].Compute(ctx); err == nil {
err = opTerm.errIncompatibleTypes(leftValue, rightValue)
}
}
return
}
// init
func init() {
registerTermConstructor(SymDot, newDotTerm)
}