aboutsummaryrefslogtreecommitdiff
path: root/starlark/library.go
diff options
context:
space:
mode:
Diffstat (limited to 'starlark/library.go')
-rw-r--r--starlark/library.go41
1 files changed, 37 insertions, 4 deletions
diff --git a/starlark/library.go b/starlark/library.go
index 9036877..e9e2f94 100644
--- a/starlark/library.go
+++ b/starlark/library.go
@@ -12,6 +12,7 @@ package starlark
import (
"errors"
"fmt"
+ "math"
"math/big"
"os"
"sort"
@@ -46,7 +47,7 @@ func init() {
"dir": NewBuiltin("dir", dir),
"enumerate": NewBuiltin("enumerate", enumerate),
"fail": NewBuiltin("fail", fail),
- "float": NewBuiltin("float", float), // requires resolve.AllowFloat
+ "float": NewBuiltin("float", float),
"getattr": NewBuiltin("getattr", getattr),
"hasattr": NewBuiltin("hasattr", hasattr),
"hash": NewBuiltin("hash", hash),
@@ -330,13 +331,39 @@ func float(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error
return Float(0.0), nil
}
case Int:
- return x.Float(), nil
+ return x.finiteFloat()
case Float:
return x, nil
case String:
- f, err := strconv.ParseFloat(string(x), 64)
+ 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, nameErr(b, err)
+ return nil, fmt.Errorf("invalid float literal: %s", s)
}
return Float(f), nil
default:
@@ -344,6 +371,12 @@ func float(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error
}
}
+var (
+ inf = Float(math.Inf(+1))
+ neginf = Float(math.Inf(-1))
+ nan = Float(math.NaN())
+)
+
// https://github.com/google/starlark-go/blob/master/doc/spec.md#getattr
func getattr(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {
var object, dflt Value