in starlark/value.go [1269:1330]
func CompareDepth(op syntax.Token, x, y Value, depth int) (bool, error) {
if depth < 1 {
return false, fmt.Errorf("comparison exceeded maximum recursion depth")
}
if sameType(x, y) {
if xcomp, ok := x.(Comparable); ok {
return xcomp.CompareSameType(op, y, depth)
}
// use identity comparison
switch op {
case syntax.EQL:
return x == y, nil
case syntax.NEQ:
return x != y, nil
}
return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
}
// different types
// int/float ordered comparisons
switch x := x.(type) {
case Int:
if y, ok := y.(Float); ok {
var cmp int
if y != y {
cmp = -1 // y is NaN
} else if !math.IsInf(float64(y), 0) {
cmp = x.rational().Cmp(y.rational()) // y is finite
} else if y > 0 {
cmp = -1 // y is +Inf
} else {
cmp = +1 // y is -Inf
}
return threeway(op, cmp), nil
}
case Float:
if y, ok := y.(Int); ok {
var cmp int
if x != x {
cmp = +1 // x is NaN
} else if !math.IsInf(float64(x), 0) {
cmp = x.rational().Cmp(y.rational()) // x is finite
} else if x > 0 {
cmp = +1 // x is +Inf
} else {
cmp = -1 // x is -Inf
}
return threeway(op, cmp), nil
}
}
// All other values of different types compare unequal.
switch op {
case syntax.EQL:
return false, nil
case syntax.NEQ:
return true, nil
}
return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y.Type())
}