builtin_math.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package goja
  2. import (
  3. "math"
  4. )
  5. func (r *Runtime) math_abs(call FunctionCall) Value {
  6. return floatToValue(math.Abs(call.Argument(0).ToFloat()))
  7. }
  8. func (r *Runtime) math_acos(call FunctionCall) Value {
  9. return floatToValue(math.Acos(call.Argument(0).ToFloat()))
  10. }
  11. func (r *Runtime) math_asin(call FunctionCall) Value {
  12. return floatToValue(math.Asin(call.Argument(0).ToFloat()))
  13. }
  14. func (r *Runtime) math_atan(call FunctionCall) Value {
  15. return floatToValue(math.Atan(call.Argument(0).ToFloat()))
  16. }
  17. func (r *Runtime) math_atan2(call FunctionCall) Value {
  18. y := call.Argument(0).ToFloat()
  19. x := call.Argument(1).ToFloat()
  20. return floatToValue(math.Atan2(y, x))
  21. }
  22. func (r *Runtime) math_ceil(call FunctionCall) Value {
  23. return floatToValue(math.Ceil(call.Argument(0).ToFloat()))
  24. }
  25. func (r *Runtime) math_cos(call FunctionCall) Value {
  26. return floatToValue(math.Cos(call.Argument(0).ToFloat()))
  27. }
  28. func (r *Runtime) math_exp(call FunctionCall) Value {
  29. return floatToValue(math.Exp(call.Argument(0).ToFloat()))
  30. }
  31. func (r *Runtime) math_floor(call FunctionCall) Value {
  32. return floatToValue(math.Floor(call.Argument(0).ToFloat()))
  33. }
  34. func (r *Runtime) math_log(call FunctionCall) Value {
  35. return floatToValue(math.Log(call.Argument(0).ToFloat()))
  36. }
  37. func (r *Runtime) math_max(call FunctionCall) Value {
  38. if len(call.Arguments) == 0 {
  39. return _negativeInf
  40. }
  41. result := call.Arguments[0].ToFloat()
  42. if math.IsNaN(result) {
  43. return _NaN
  44. }
  45. for _, arg := range call.Arguments[1:] {
  46. f := arg.ToFloat()
  47. if math.IsNaN(f) {
  48. return _NaN
  49. }
  50. result = math.Max(result, f)
  51. }
  52. return floatToValue(result)
  53. }
  54. func (r *Runtime) math_min(call FunctionCall) Value {
  55. if len(call.Arguments) == 0 {
  56. return _positiveInf
  57. }
  58. result := call.Arguments[0].ToFloat()
  59. if math.IsNaN(result) {
  60. return _NaN
  61. }
  62. for _, arg := range call.Arguments[1:] {
  63. f := arg.ToFloat()
  64. if math.IsNaN(f) {
  65. return _NaN
  66. }
  67. result = math.Min(result, f)
  68. }
  69. return floatToValue(result)
  70. }
  71. func (r *Runtime) math_pow(call FunctionCall) Value {
  72. x := call.Argument(0)
  73. y := call.Argument(1)
  74. if x, ok := x.(valueInt); ok {
  75. if y, ok := y.(valueInt); ok && y >= 0 && y < 64 {
  76. if y == 0 {
  77. return intToValue(1)
  78. }
  79. if x == 0 {
  80. return intToValue(0)
  81. }
  82. ip := ipow(int64(x), int64(y))
  83. if ip != 0 {
  84. return intToValue(ip)
  85. }
  86. }
  87. }
  88. return floatToValue(math.Pow(x.ToFloat(), y.ToFloat()))
  89. }
  90. func (r *Runtime) math_random(call FunctionCall) Value {
  91. return floatToValue(r.rand())
  92. }
  93. func (r *Runtime) math_round(call FunctionCall) Value {
  94. f := call.Argument(0).ToFloat()
  95. if math.IsNaN(f) {
  96. return _NaN
  97. }
  98. if f == 0 && math.Signbit(f) {
  99. return _negativeZero
  100. }
  101. t := math.Trunc(f)
  102. if f >= 0 {
  103. if f-t >= 0.5 {
  104. return floatToValue(t + 1)
  105. }
  106. } else {
  107. if t-f > 0.5 {
  108. return floatToValue(t - 1)
  109. }
  110. }
  111. return floatToValue(t)
  112. }
  113. func (r *Runtime) math_sin(call FunctionCall) Value {
  114. return floatToValue(math.Sin(call.Argument(0).ToFloat()))
  115. }
  116. func (r *Runtime) math_sqrt(call FunctionCall) Value {
  117. return floatToValue(math.Sqrt(call.Argument(0).ToFloat()))
  118. }
  119. func (r *Runtime) math_tan(call FunctionCall) Value {
  120. return floatToValue(math.Tan(call.Argument(0).ToFloat()))
  121. }
  122. func (r *Runtime) createMath(val *Object) objectImpl {
  123. m := &baseObject{
  124. class: "Math",
  125. val: val,
  126. extensible: true,
  127. prototype: r.global.ObjectPrototype,
  128. }
  129. m.init()
  130. m._putProp("E", valueFloat(math.E), false, false, false)
  131. m._putProp("LN10", valueFloat(math.Ln10), false, false, false)
  132. m._putProp("LN2", valueFloat(math.Ln2), false, false, false)
  133. m._putProp("LOG2E", valueFloat(math.Log2E), false, false, false)
  134. m._putProp("LOG10E", valueFloat(math.Log10E), false, false, false)
  135. m._putProp("PI", valueFloat(math.Pi), false, false, false)
  136. m._putProp("SQRT1_2", valueFloat(sqrt1_2), false, false, false)
  137. m._putProp("SQRT2", valueFloat(math.Sqrt2), false, false, false)
  138. m._putProp("abs", r.newNativeFunc(r.math_abs, nil, "abs", nil, 1), true, false, true)
  139. m._putProp("acos", r.newNativeFunc(r.math_acos, nil, "acos", nil, 1), true, false, true)
  140. m._putProp("asin", r.newNativeFunc(r.math_asin, nil, "asin", nil, 1), true, false, true)
  141. m._putProp("atan", r.newNativeFunc(r.math_atan, nil, "atan", nil, 1), true, false, true)
  142. m._putProp("atan2", r.newNativeFunc(r.math_atan2, nil, "atan2", nil, 2), true, false, true)
  143. m._putProp("ceil", r.newNativeFunc(r.math_ceil, nil, "ceil", nil, 1), true, false, true)
  144. m._putProp("cos", r.newNativeFunc(r.math_cos, nil, "cos", nil, 1), true, false, true)
  145. m._putProp("exp", r.newNativeFunc(r.math_exp, nil, "exp", nil, 1), true, false, true)
  146. m._putProp("floor", r.newNativeFunc(r.math_floor, nil, "floor", nil, 1), true, false, true)
  147. m._putProp("log", r.newNativeFunc(r.math_log, nil, "log", nil, 1), true, false, true)
  148. m._putProp("max", r.newNativeFunc(r.math_max, nil, "max", nil, 2), true, false, true)
  149. m._putProp("min", r.newNativeFunc(r.math_min, nil, "min", nil, 2), true, false, true)
  150. m._putProp("pow", r.newNativeFunc(r.math_pow, nil, "pow", nil, 2), true, false, true)
  151. m._putProp("random", r.newNativeFunc(r.math_random, nil, "random", nil, 0), true, false, true)
  152. m._putProp("round", r.newNativeFunc(r.math_round, nil, "round", nil, 1), true, false, true)
  153. m._putProp("sin", r.newNativeFunc(r.math_sin, nil, "sin", nil, 1), true, false, true)
  154. m._putProp("sqrt", r.newNativeFunc(r.math_sqrt, nil, "sqrt", nil, 1), true, false, true)
  155. m._putProp("tan", r.newNativeFunc(r.math_tan, nil, "tan", nil, 1), true, false, true)
  156. return m
  157. }
  158. func (r *Runtime) initMath() {
  159. r.addToGlobal("Math", r.newLazyObject(r.createMath))
  160. }