diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/robertkrimen/otto/value_string.go')
-rw-r--r-- | Godeps/_workspace/src/github.com/robertkrimen/otto/value_string.go | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/robertkrimen/otto/value_string.go b/Godeps/_workspace/src/github.com/robertkrimen/otto/value_string.go new file mode 100644 index 000000000..0fbfd6b25 --- /dev/null +++ b/Godeps/_workspace/src/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)) +} |