123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- 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))
- }
|