operator-dot.go: the '.' (dot) operator can now only be used to call member functions of iterators

This commit is contained in:
Celestino Amoroso 2024-05-25 03:35:17 +02:00
parent fa136cb70b
commit 691c213d17

View File

@ -4,8 +4,6 @@
// operator-dot.go
package expr
import "fmt"
// -------- dot term
func newDotTerm(tk *Token) (inst *term) {
return &term{
@ -17,24 +15,6 @@ func newDotTerm(tk *Token) (inst *term) {
}
}
func verifyDotIndex(ctx ExprContext, indexTerm *term, maxValue int) (index int, err error) {
var v int
var indexValue any
if indexValue, err = indexTerm.compute(ctx); err == nil {
if v, err = indexTerm.toInt(indexValue, "index expression value must be integer"); err == nil {
if v < 0 && v >= -maxValue {
v = maxValue + v
}
if v >= 0 && v < maxValue {
index = v
} else {
err = indexTerm.Errorf("index %d out of bounds", v)
}
}
}
return
}
func evalDot(ctx ExprContext, self *term) (v any, err error) {
var leftValue, rightValue any
@ -48,27 +28,8 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
indexTerm := self.children[1]
switch unboxedValue := leftValue.(type) {
case *ListType:
var index int
array := ([]any)(*unboxedValue)
if index, err = verifyDotIndex(ctx, indexTerm, len(array)); err == nil {
v = array[index]
}
case string:
var index int
if index, err = verifyDotIndex(ctx, indexTerm, len(unboxedValue)); err == nil {
v = string(unboxedValue[index])
}
case *DictType:
var ok bool
var indexValue any
if indexValue, err = indexTerm.compute(ctx); err == nil {
if v, ok = (*unboxedValue)[indexValue]; !ok {
err = fmt.Errorf("key %v does not belong to the dictionary", rightValue)
}
}
case ExtIterator:
if indexTerm.symbol() == SymVariable {
if indexTerm.symbol() == SymVariable /*|| indexTerm.symbol() == SymString */ {
opName := indexTerm.source()
if unboxedValue.HasOperation(opName) {
v, err = unboxedValue.CallOperation(opName, []any{})
@ -76,10 +37,14 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
err = indexTerm.Errorf("this iterator do not support the %q command", opName)
v = false
}
} else {
err = indexTerm.tk.ErrorExpectedGot("identifier")
}
default:
if rightValue, err = self.children[1].compute(ctx); err == nil {
err = self.errIncompatibleTypes(leftValue, rightValue)
}
}
return
}