builtin_number.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package otto
  2. import (
  3. "math"
  4. "strconv"
  5. )
  6. // Number
  7. func numberValueFromNumberArgumentList(argumentList []Value) Value {
  8. if len(argumentList) > 0 {
  9. return argumentList[0].numberValue()
  10. }
  11. return toValue_int(0)
  12. }
  13. func builtinNumber(call FunctionCall) Value {
  14. return numberValueFromNumberArgumentList(call.ArgumentList)
  15. }
  16. func builtinNewNumber(self *_object, argumentList []Value) Value {
  17. return toValue_object(self.runtime.newNumber(numberValueFromNumberArgumentList(argumentList)))
  18. }
  19. func builtinNumber_toString(call FunctionCall) Value {
  20. // Will throw a TypeError if ThisObject is not a Number
  21. value := call.thisClassObject(classNumber).primitiveValue()
  22. radix := 10
  23. radixArgument := call.Argument(0)
  24. if radixArgument.IsDefined() {
  25. integer := toIntegerFloat(radixArgument)
  26. if integer < 2 || integer > 36 {
  27. panic(call.runtime.panicRangeError("toString() radix must be between 2 and 36"))
  28. }
  29. radix = int(integer)
  30. }
  31. if radix == 10 {
  32. return toValue_string(value.string())
  33. }
  34. return toValue_string(numberToStringRadix(value, radix))
  35. }
  36. func builtinNumber_valueOf(call FunctionCall) Value {
  37. return call.thisClassObject(classNumber).primitiveValue()
  38. }
  39. func builtinNumber_toFixed(call FunctionCall) Value {
  40. precision := toIntegerFloat(call.Argument(0))
  41. if 20 < precision || 0 > precision {
  42. panic(call.runtime.panicRangeError("toFixed() precision must be between 0 and 20"))
  43. }
  44. if call.This.IsNaN() {
  45. return toValue_string("NaN")
  46. }
  47. value := call.This.float64()
  48. if math.Abs(value) >= 1e21 {
  49. return toValue_string(floatToString(value, 64))
  50. }
  51. return toValue_string(strconv.FormatFloat(call.This.float64(), 'f', int(precision), 64))
  52. }
  53. func builtinNumber_toExponential(call FunctionCall) Value {
  54. if call.This.IsNaN() {
  55. return toValue_string("NaN")
  56. }
  57. precision := float64(-1)
  58. if value := call.Argument(0); value.IsDefined() {
  59. precision = toIntegerFloat(value)
  60. if 0 > precision {
  61. panic(call.runtime.panicRangeError("toString() radix must be between 2 and 36"))
  62. }
  63. }
  64. return toValue_string(strconv.FormatFloat(call.This.float64(), 'e', int(precision), 64))
  65. }
  66. func builtinNumber_toPrecision(call FunctionCall) Value {
  67. if call.This.IsNaN() {
  68. return toValue_string("NaN")
  69. }
  70. value := call.Argument(0)
  71. if value.IsUndefined() {
  72. return toValue_string(call.This.string())
  73. }
  74. precision := toIntegerFloat(value)
  75. if 1 > precision {
  76. panic(call.runtime.panicRangeError("toPrecision() precision must be greater than 1"))
  77. }
  78. return toValue_string(strconv.FormatFloat(call.This.float64(), 'g', int(precision), 64))
  79. }
  80. func builtinNumber_isNaN(call FunctionCall) Value {
  81. if len(call.ArgumentList) < 1 {
  82. return toValue_bool(false)
  83. }
  84. return toValue_bool(call.Argument(0).IsNaN())
  85. }
  86. func builtinNumber_toLocaleString(call FunctionCall) Value {
  87. return builtinNumber_toString(call)
  88. }