operator-dot.go: refactoring
This commit is contained in:
parent
60effe8f1b
commit
c99be491df
@ -17,6 +17,20 @@ func newDotTerm(tk *Token) (inst *term) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func verifyIndex(indexTerm *term, indexValue any, maxValue int) (index int, err error) {
|
||||||
|
var v int
|
||||||
|
if v, err = indexTerm.toInt(indexValue, "index expression value must be integer"); err == nil {
|
||||||
|
if v >= 0 && v < maxValue {
|
||||||
|
index = v
|
||||||
|
} else if index >= -maxValue {
|
||||||
|
index = maxValue + 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
|
||||||
|
|
||||||
@ -26,41 +40,23 @@ func evalDot(ctx ExprContext, self *term) (v any, err error) {
|
|||||||
|
|
||||||
indexTerm := self.children[1]
|
indexTerm := self.children[1]
|
||||||
|
|
||||||
if isList(leftValue) {
|
switch unboxedValue := leftValue.(type) {
|
||||||
|
case []any:
|
||||||
var index int
|
var index int
|
||||||
if index, err = indexTerm.toInt(rightValue, "index expression value must be integer"); err != nil {
|
if index, err = verifyIndex(indexTerm, rightValue, len(unboxedValue)); err == nil {
|
||||||
return
|
v = unboxedValue[index]
|
||||||
}
|
}
|
||||||
|
case string:
|
||||||
list, _ := leftValue.([]any)
|
|
||||||
if index >= 0 && index < len(list) {
|
|
||||||
v = list[index]
|
|
||||||
} else if index >= -len(list) {
|
|
||||||
v = list[len(list)+index]
|
|
||||||
} else {
|
|
||||||
err = indexTerm.Errorf("index %v out of bounds", index)
|
|
||||||
}
|
|
||||||
} else if isString(leftValue) {
|
|
||||||
var index int
|
var index int
|
||||||
if index, err = indexTerm.toInt(rightValue, "index expression value must be integer"); err != nil {
|
if index, err = verifyIndex(indexTerm, rightValue, len(unboxedValue)); err == nil {
|
||||||
return
|
v = unboxedValue[index]
|
||||||
}
|
}
|
||||||
|
case map[any]any:
|
||||||
s, _ := leftValue.(string)
|
|
||||||
if index >= 0 && index < len(s) {
|
|
||||||
v = string(s[index])
|
|
||||||
} else if index >= -len(s) {
|
|
||||||
v = string(s[len(s)+index])
|
|
||||||
} else {
|
|
||||||
err = indexTerm.Errorf("index %v out of bounds", index)
|
|
||||||
}
|
|
||||||
} else if isDict(leftValue) {
|
|
||||||
var ok bool
|
var ok bool
|
||||||
d, _ := leftValue.(map[any]any)
|
if v, ok = unboxedValue[rightValue]; !ok {
|
||||||
if v, ok = d[rightValue]; !ok {
|
|
||||||
err = fmt.Errorf("key %v does not belong to the dictionary", rightValue)
|
err = fmt.Errorf("key %v does not belong to the dictionary", rightValue)
|
||||||
}
|
}
|
||||||
} else {
|
default:
|
||||||
err = self.errIncompatibleTypes(leftValue, rightValue)
|
err = self.errIncompatibleTypes(leftValue, rightValue)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user