2024-02-24 21:00:04 +00:00
|
|
|
package otto
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math"
|
|
|
|
"math/rand"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Math
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathAbs(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Abs(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathAcos(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Acos(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathAcosh(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Acosh(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathAsin(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Asin(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathAsinh(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Asinh(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathAtan(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Atan(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathAtan2(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
y := call.Argument(0).float64()
|
|
|
|
if math.IsNaN(y) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
|
|
|
x := call.Argument(1).float64()
|
|
|
|
if math.IsNaN(x) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Atan2(y, x))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathAtanh(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Atanh(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathCbrt(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Cbrt(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathCos(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Cos(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathCeil(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Ceil(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathCosh(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Cosh(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathExp(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Exp(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathExpm1(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Expm1(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathFloor(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Floor(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathLog(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Log(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathLog10(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Log10(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathLog1p(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Log1p(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathLog2(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Log2(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathMax(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
switch len(call.ArgumentList) {
|
|
|
|
case 0:
|
|
|
|
return negativeInfinityValue()
|
|
|
|
case 1:
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(call.ArgumentList[0].float64())
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
result := call.ArgumentList[0].float64()
|
|
|
|
if math.IsNaN(result) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
|
|
|
for _, value := range call.ArgumentList[1:] {
|
|
|
|
value := value.float64()
|
|
|
|
if math.IsNaN(value) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
|
|
|
result = math.Max(result, value)
|
|
|
|
}
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(result)
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathMin(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
switch len(call.ArgumentList) {
|
|
|
|
case 0:
|
|
|
|
return positiveInfinityValue()
|
|
|
|
case 1:
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(call.ArgumentList[0].float64())
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
result := call.ArgumentList[0].float64()
|
|
|
|
if math.IsNaN(result) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
|
|
|
for _, value := range call.ArgumentList[1:] {
|
|
|
|
value := value.float64()
|
|
|
|
if math.IsNaN(value) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
|
|
|
result = math.Min(result, value)
|
|
|
|
}
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(result)
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathPow(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
// TODO Make sure this works according to the specification (15.8.2.13)
|
|
|
|
x := call.Argument(0).float64()
|
|
|
|
y := call.Argument(1).float64()
|
|
|
|
if math.Abs(x) == 1 && math.IsInf(y, 0) {
|
|
|
|
return NaNValue()
|
|
|
|
}
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Pow(x, y))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathRandom(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
var v float64
|
|
|
|
if call.runtime.random != nil {
|
|
|
|
v = call.runtime.random()
|
|
|
|
} else {
|
2024-04-04 14:46:14 +00:00
|
|
|
v = rand.Float64() //nolint: gosec
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(v)
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathRound(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
|
|
|
value := math.Floor(number + 0.5)
|
|
|
|
if value == 0 {
|
|
|
|
value = math.Copysign(0, number)
|
|
|
|
}
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(value)
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathSin(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Sin(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathSinh(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Sinh(number))
|
|
|
|
}
|
|
|
|
|
|
|
|
func builtinMathSqrt(call FunctionCall) Value {
|
|
|
|
number := call.Argument(0).float64()
|
|
|
|
return float64Value(math.Sqrt(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathTan(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Tan(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathTanh(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Tanh(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 14:46:14 +00:00
|
|
|
func builtinMathTrunc(call FunctionCall) Value {
|
2024-02-24 21:00:04 +00:00
|
|
|
number := call.Argument(0).float64()
|
2024-04-04 14:46:14 +00:00
|
|
|
return float64Value(math.Trunc(number))
|
2024-02-24 21:00:04 +00:00
|
|
|
}
|