package otto import ( "math" "math/rand" ) // Math func builtinMath_abs(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Abs(number)) } func builtinMath_acos(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Acos(number)) } func builtinMath_asin(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Asin(number)) } func builtinMath_atan(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Atan(number)) } func builtinMath_atan2(call FunctionCall) Value { y := toFloat(call.Argument(0)) if math.IsNaN(y) { return NaNValue() } x := toFloat(call.Argument(1)) if math.IsNaN(x) { return NaNValue() } return toValue_float64(math.Atan2(y, x)) } func builtinMath_cos(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Cos(number)) } func builtinMath_ceil(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Ceil(number)) } func builtinMath_exp(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Exp(number)) } func builtinMath_floor(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Floor(number)) } func builtinMath_log(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Log(number)) } func builtinMath_max(call FunctionCall) Value { switch len(call.ArgumentList) { case 0: return negativeInfinityValue() case 1: return toValue_float64(toFloat(call.ArgumentList[0])) } result := toFloat(call.ArgumentList[0]) if math.IsNaN(result) { return NaNValue() } for _, value := range call.ArgumentList[1:] { value := toFloat(value) if math.IsNaN(value) { return NaNValue() } result = math.Max(result, value) } return toValue_float64(result) } func builtinMath_min(call FunctionCall) Value { switch len(call.ArgumentList) { case 0: return positiveInfinityValue() case 1: return toValue_float64(toFloat(call.ArgumentList[0])) } result := toFloat(call.ArgumentList[0]) if math.IsNaN(result) { return NaNValue() } for _, value := range call.ArgumentList[1:] { value := toFloat(value) if math.IsNaN(value) { return NaNValue() } result = math.Min(result, value) } return toValue_float64(result) } func builtinMath_pow(call FunctionCall) Value { // TODO Make sure this works according to the specification (15.8.2.13) x := toFloat(call.Argument(0)) y := toFloat(call.Argument(1)) if math.Abs(x) == 1 && math.IsInf(y, 0) { return NaNValue() } return toValue_float64(math.Pow(x, y)) } func builtinMath_random(call FunctionCall) Value { return toValue_float64(rand.Float64()) } func builtinMath_round(call FunctionCall) Value { number := toFloat(call.Argument(0)) value := math.Floor(number + 0.5) if value == 0 { value = math.Copysign(0, number) } return toValue_float64(value) } func builtinMath_sin(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Sin(number)) } func builtinMath_sqrt(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Sqrt(number)) } func builtinMath_tan(call FunctionCall) Value { number := toFloat(call.Argument(0)) return toValue_float64(math.Tan(number)) }