operator-dot.go: the '.' (dot) operator can now only be used to call member functions of iterators
This commit is contained in:
parent
fa136cb70b
commit
691c213d17
@ -4,8 +4,6 @@
|
|||||||
// operator-dot.go
|
// operator-dot.go
|
||||||
package expr
|
package expr
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// -------- dot term
|
// -------- dot term
|
||||||
func newDotTerm(tk *Token) (inst *term) {
|
func newDotTerm(tk *Token) (inst *term) {
|
||||||
return &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) {
|
func evalDot(ctx ExprContext, self *term) (v any, err error) {
|
||||||
var leftValue, rightValue any
|
var leftValue, rightValue any
|
||||||
|
|
||||||
@ -48,27 +28,8 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
|
|||||||
indexTerm := self.children[1]
|
indexTerm := self.children[1]
|
||||||
|
|
||||||
switch unboxedValue := leftValue.(type) {
|
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:
|
case ExtIterator:
|
||||||
if indexTerm.symbol() == SymVariable {
|
if indexTerm.symbol() == SymVariable /*|| indexTerm.symbol() == SymString */ {
|
||||||
opName := indexTerm.source()
|
opName := indexTerm.source()
|
||||||
if unboxedValue.HasOperation(opName) {
|
if unboxedValue.HasOperation(opName) {
|
||||||
v, err = unboxedValue.CallOperation(opName, []any{})
|
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)
|
err = indexTerm.Errorf("this iterator do not support the %q command", opName)
|
||||||
v = false
|
v = false
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
err = indexTerm.tk.ErrorExpectedGot("identifier")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
if rightValue, err = self.children[1].compute(ctx); err == nil {
|
||||||
err = self.errIncompatibleTypes(leftValue, rightValue)
|
err = self.errIncompatibleTypes(leftValue, rightValue)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user