aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/robertkrimen/otto/value_string.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/robertkrimen/otto/value_string.go')
-rw-r--r--vendor/github.com/robertkrimen/otto/value_string.go103
1 files changed, 103 insertions, 0 deletions
diff --git a/vendor/github.com/robertkrimen/otto/value_string.go b/vendor/github.com/robertkrimen/otto/value_string.go
new file mode 100644
index 000000000..0fbfd6b25
--- /dev/null
+++ b/vendor/github.com/robertkrimen/otto/value_string.go
@@ -0,0 +1,103 @@
+package otto
+
+import (
+ "fmt"
+ "math"
+ "regexp"
+ "strconv"
+ "unicode/utf16"
+)
+
+var matchLeading0Exponent = regexp.MustCompile(`([eE][\+\-])0+([1-9])`) // 1e-07 => 1e-7
+
+// FIXME
+// https://code.google.com/p/v8/source/browse/branches/bleeding_edge/src/conversions.cc?spec=svn18082&r=18082
+func floatToString(value float64, bitsize int) string {
+ // TODO Fit to ECMA-262 9.8.1 specification
+ if math.IsNaN(value) {
+ return "NaN"
+ } else if math.IsInf(value, 0) {
+ if math.Signbit(value) {
+ return "-Infinity"
+ }
+ return "Infinity"
+ }
+ exponent := math.Log10(math.Abs(value))
+ if exponent >= 21 || exponent < -6 {
+ return matchLeading0Exponent.ReplaceAllString(strconv.FormatFloat(value, 'g', -1, bitsize), "$1$2")
+ }
+ return strconv.FormatFloat(value, 'f', -1, bitsize)
+}
+
+func numberToStringRadix(value Value, radix int) string {
+ float := value.float64()
+ if math.IsNaN(float) {
+ return "NaN"
+ } else if math.IsInf(float, 1) {
+ return "Infinity"
+ } else if math.IsInf(float, -1) {
+ return "-Infinity"
+ }
+ // FIXME This is very broken
+ // Need to do proper radix conversion for floats, ...
+ // This truncates large floats (so bad).
+ return strconv.FormatInt(int64(float), radix)
+}
+
+func (value Value) string() string {
+ if value.kind == valueString {
+ switch value := value.value.(type) {
+ case string:
+ return value
+ case []uint16:
+ return string(utf16.Decode(value))
+ }
+ }
+ if value.IsUndefined() {
+ return "undefined"
+ }
+ if value.IsNull() {
+ return "null"
+ }
+ switch value := value.value.(type) {
+ case bool:
+ return strconv.FormatBool(value)
+ case int:
+ return strconv.FormatInt(int64(value), 10)
+ case int8:
+ return strconv.FormatInt(int64(value), 10)
+ case int16:
+ return strconv.FormatInt(int64(value), 10)
+ case int32:
+ return strconv.FormatInt(int64(value), 10)
+ case int64:
+ return strconv.FormatInt(value, 10)
+ case uint:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint8:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint16:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint32:
+ return strconv.FormatUint(uint64(value), 10)
+ case uint64:
+ return strconv.FormatUint(value, 10)
+ case float32:
+ if value == 0 {
+ return "0" // Take care not to return -0
+ }
+ return floatToString(float64(value), 32)
+ case float64:
+ if value == 0 {
+ return "0" // Take care not to return -0
+ }
+ return floatToString(value, 64)
+ case []uint16:
+ return string(utf16.Decode(value))
+ case string:
+ return value
+ case *_object:
+ return value.DefaultValue(defaultValueHintString).string()
+ }
+ panic(fmt.Errorf("%v.string( %T)", value.value, value.value))
+}