1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use alloc::vec::Vec;
macro_rules! unary {
($( $(#[$meta:meta])* $name:ident => $js:literal ),* $(,)?) => {$(
$(#[$meta])*
#[inline]
pub fn $name(x: f64) -> f64 {
Self::obj().call($js, &[x.into()]).as_::<f64>()
}
)*};
}
/// Namespace only; no value is ever instantiated.
pub struct Math;
impl Math {
#[inline(always)]
fn obj() -> emlite::Val {
emlite::Val::global("Math")
}
pub const E: f64 = core::f64::consts::E;
pub const LN2: f64 = core::f64::consts::LN_2;
pub const LN10: f64 = core::f64::consts::LN_10;
pub const LOG2E: f64 = core::f64::consts::LOG2_E;
pub const LOG10E: f64 = core::f64::consts::LOG10_E;
pub const PI: f64 = core::f64::consts::PI;
pub const SQRT1_2: f64 = core::f64::consts::FRAC_1_SQRT_2; // 1/√2
pub const SQRT2: f64 = core::f64::consts::SQRT_2;
unary! {
/// `Math.abs`
abs => "abs",
/// `Math.acos`
/// `Math.acos`
acos => "acos",
/// `Math.acosh`
acosh => "acosh",
/// `Math.asin`
asin => "asin",
/// `Math.asinh`
asinh => "asinh",
/// `Math.atan`
atan => "atan",
/// `Math.atanh`
atanh => "atanh",
/// `Math.cbrt`
cbrt => "cbrt",
/// `Math.ceil`
ceil => "ceil",
/// `Math.clz32`
clz32 => "clz32",
/// `Math.cos`
cos => "cos",
/// `Math.cosh`
cosh => "cosh",
/// `Math.exp`
exp => "exp",
/// `Math.expm1`
expm1 => "expm1",
/// `Math.floor`
floor => "floor",
/// `Math.fround`
fround => "fround",
/// `Math.log`
log => "log",
/// `Math.log1p`
log1p => "log1p",
/// `Math.log2`
log2 => "log2",
/// `Math.log10`
log10 => "log10",
/// `Math.round`
round => "round",
/// `Math.sign`
sign => "sign",
/// `Math.sin`
sin => "sin",
/// `Math.sinh`
sinh => "sinh",
/// `Math.sqrt`
sqrt => "sqrt",
/// `Math.tan`
tan => "tan",
/// `Math.tanh`
tanh => "tanh",
/// `Math.trunc`
trunc => "trunc",
}
/// `Math.atan2`
#[inline]
pub fn atan2(y: f64, x: f64) -> f64 {
Self::obj()
.call("atan2", &[y.into(), x.into()])
.as_::<f64>()
}
/// `Math.pow`
#[inline]
pub fn pow(x: f64, y: f64) -> f64 {
Self::obj().call("pow", &[x.into(), y.into()]).as_::<f64>()
}
/// `Math.imul`
#[inline]
pub fn imul(a: i32, b: i32) -> i32 {
Self::obj().call("imul", &[a.into(), b.into()]).as_::<i32>()
}
/// `Math.max`
#[inline]
pub fn max(nums: &[f64]) -> f64 {
Self::obj()
.call(
"max",
&nums.iter().copied().map(Into::into).collect::<Vec<_>>(),
)
.as_::<f64>()
}
/// `Math.min`
#[inline]
pub fn min(nums: &[f64]) -> f64 {
Self::obj()
.call(
"min",
&nums.iter().copied().map(Into::into).collect::<Vec<_>>(),
)
.as_::<f64>()
}
/// `Math.hypot`
#[inline]
pub fn hypot(nums: &[f64]) -> f64 {
Self::obj()
.call(
"hypot",
&nums.iter().copied().map(Into::into).collect::<Vec<_>>(),
)
.as_::<f64>()
}
/// `Math.random`
#[inline]
pub fn random() -> f64 {
Self::obj().call("random", &[]).as_::<f64>()
}
}