in starlark/library.go [379:435]
func float(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
if len(kwargs) > 0 {
return nil, fmt.Errorf("float does not accept keyword arguments")
}
if len(args) == 0 {
return Float(0.0), nil
}
if len(args) != 1 {
return nil, fmt.Errorf("float got %d arguments, wants 1", len(args))
}
switch x := args[0].(type) {
case Bool:
if x {
return Float(1.0), nil
} else {
return Float(0.0), nil
}
case Int:
return x.finiteFloat()
case Float:
return x, nil
case String:
if x == "" {
return nil, fmt.Errorf("float: empty string")
}
// +/- NaN or Inf or Infinity (case insensitive)?
s := string(x)
switch x[len(x)-1] {
case 'y', 'Y':
if strings.EqualFold(s, "infinity") || strings.EqualFold(s, "+infinity") {
return inf, nil
} else if strings.EqualFold(s, "-infinity") {
return neginf, nil
}
case 'f', 'F':
if strings.EqualFold(s, "inf") || strings.EqualFold(s, "+inf") {
return inf, nil
} else if strings.EqualFold(s, "-inf") {
return neginf, nil
}
case 'n', 'N':
if strings.EqualFold(s, "nan") || strings.EqualFold(s, "+nan") || strings.EqualFold(s, "-nan") {
return nan, nil
}
}
f, err := strconv.ParseFloat(s, 64)
if math.IsInf(f, 0) {
return nil, fmt.Errorf("floating-point number too large")
}
if err != nil {
return nil, fmt.Errorf("invalid float literal: %s", s)
}
return Float(f), nil
default:
return nil, fmt.Errorf("float got %s, want number or string", x.Type())
}
}