From 95d7d729ada36b602d90e159e4b3279ad531368f Mon Sep 17 00:00:00 2001 From: Robert Krimen Date: Tue, 19 Feb 2013 13:42:26 -0800 Subject: [PATCH] Add floatToString and streamline toString floatToString does not properly implement ECMA-262 9.8.1 yet --- number_test.go | 4 ++++ value_string.go | 58 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/number_test.go b/number_test.go index 7922454..69976a7 100644 --- a/number_test.go +++ b/number_test.go @@ -25,4 +25,8 @@ func TestNumber_toString(t *testing.T) { test(`raise: new Number(451).toString(1); `, "RangeError: RangeError: toString() radix must be between 2 and 36") + + test(`raise: + new Number(451).toString(Infinity); + `, "RangeError: RangeError: toString() radix must be between 2 and 36") } diff --git a/value_string.go b/value_string.go index 685269e..985f9bb 100644 --- a/value_string.go +++ b/value_string.go @@ -3,8 +3,22 @@ package otto import ( "fmt" "math" + "strconv" ) +func floatToString(value float64, bitsize int) string { + // TODO Reimplement according to ECMA-262 9.8.1 + if math.IsNaN(value) { + return "NaN" + } else if math.IsInf(value, 0) { + if math.Signbit(value) { + return "-Infinity" + } + return "Infinity" + } + return strconv.FormatFloat(value, 'g', -1, bitsize) +} + func toString(value Value) string { if value._valueType == valueString { return value.value.(string) @@ -15,29 +29,37 @@ func toString(value Value) string { if value.IsNull() { return "null" } - switch realValue := value.value.(type) { + switch value := value.value.(type) { case bool: - return fmt.Sprintf("%v", realValue) - case int, int8, int16, int32, int64: - return fmt.Sprintf("%v", realValue) - case uint, uint8, uint16, uint32, uint64: - return fmt.Sprintf("%v", realValue) + 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: - return fmt.Sprintf("%v", realValue) + return floatToString(float64(value), 32) case float64: - if math.IsNaN(realValue) { - return "NaN" - } else if math.IsInf(realValue, 0) { - if math.Signbit(realValue) { - return "-Infinity" - } - return "Infinity" - } - return fmt.Sprintf("%v", realValue) + return floatToString(value, 64) case string: - return realValue + return value case *_object: - return toString(realValue.DefaultValue(defaultValueHintString)) + return toString(value.DefaultValue(defaultValueHintString)) } panic(fmt.Errorf("toString(%v %T)", value.value, value.value)) }