1use super::Symbol;
8use crate::symtable::SymTable;
9
10#[cfg(feature = "f64-floats")]
11impl SymTable {
12 pub fn stdlib() -> Self {
53 Self::from_symbols(vec![
54 Symbol::Const {
56 name: "pi".into(),
57 value: std::f64::consts::PI,
58 description: Some("π (3.14159...)".into()),
59 local: false,
60 },
61 Symbol::Const {
62 name: "e".into(),
63 value: std::f64::consts::E,
64 description: Some("Euler's number (2.71828...)".into()),
65 local: false,
66 },
67 Symbol::Const {
68 name: "tau".into(),
69 value: std::f64::consts::TAU,
70 description: Some("2π (6.28318...)".into()),
71 local: false,
72 },
73 Symbol::Const {
74 name: "ln2".into(),
75 value: std::f64::consts::LN_2,
76 description: Some("Natural logarithm of 2".into()),
77 local: false,
78 },
79 Symbol::Const {
80 name: "ln10".into(),
81 value: std::f64::consts::LN_10,
82 description: Some("Natural logarithm of 10".into()),
83 local: false,
84 },
85 Symbol::Const {
86 name: "sqrt2".into(),
87 value: std::f64::consts::SQRT_2,
88 description: Some("Square root of 2".into()),
89 local: false,
90 },
91 Symbol::Func {
93 name: "sin".into(),
94 args: 1,
95 variadic: false,
96 callback: |args| Ok(args[0].sin()),
97 description: Some("Sine".into()),
98 local: false,
99 },
100 Symbol::Func {
101 name: "cos".into(),
102 args: 1,
103 variadic: false,
104 callback: |args| Ok(args[0].cos()),
105 description: Some("Cosine".into()),
106 local: false,
107 },
108 Symbol::Func {
109 name: "tan".into(),
110 args: 1,
111 variadic: false,
112 callback: |args| Ok(args[0].tan()),
113 description: Some("Tangent".into()),
114 local: false,
115 },
116 Symbol::Func {
117 name: "asin".into(),
118 args: 1,
119 variadic: false,
120 callback: |args| Ok(args[0].asin()),
121 description: Some("Arcsine".into()),
122 local: false,
123 },
124 Symbol::Func {
125 name: "acos".into(),
126 args: 1,
127 variadic: false,
128 callback: |args| Ok(args[0].acos()),
129 description: Some("Arccosine".into()),
130 local: false,
131 },
132 Symbol::Func {
133 name: "atan".into(),
134 args: 1,
135 variadic: false,
136 callback: |args| Ok(args[0].atan()),
137 description: Some("Arctangent".into()),
138 local: false,
139 },
140 Symbol::Func {
141 name: "atan2".into(),
142 args: 2,
143 variadic: false,
144 callback: |args| Ok(args[0].atan2(args[1])),
145 description: Some("Two-argument arctangent".into()),
146 local: false,
147 },
148 Symbol::Func {
149 name: "sinh".into(),
150 args: 1,
151 variadic: false,
152 callback: |args| Ok(args[0].sinh()),
153 description: Some("Hyperbolic sine".into()),
154 local: false,
155 },
156 Symbol::Func {
157 name: "cosh".into(),
158 args: 1,
159 variadic: false,
160 callback: |args| Ok(args[0].cosh()),
161 description: Some("Hyperbolic cosine".into()),
162 local: false,
163 },
164 Symbol::Func {
165 name: "tanh".into(),
166 args: 1,
167 variadic: false,
168 callback: |args| Ok(args[0].tanh()),
169 description: Some("Hyperbolic tangent".into()),
170 local: false,
171 },
172 Symbol::Func {
174 name: "sqrt".into(),
175 args: 1,
176 variadic: false,
177 callback: |args| Ok(args[0].sqrt()),
178 description: Some("Square root".into()),
179 local: false,
180 },
181 Symbol::Func {
182 name: "cbrt".into(),
183 args: 1,
184 variadic: false,
185 callback: |args| Ok(args[0].cbrt()),
186 description: Some("Cube root".into()),
187 local: false,
188 },
189 Symbol::Func {
190 name: "pow".into(),
191 args: 2,
192 variadic: false,
193 callback: |args| Ok(args[0].powf(args[1])),
194 description: Some("x raised to power y".into()),
195 local: false,
196 },
197 Symbol::Func {
199 name: "log".into(),
200 args: 1,
201 variadic: false,
202 callback: |args| Ok(args[0].ln()),
203 description: Some("Natural logarithm".into()),
204 local: false,
205 },
206 Symbol::Func {
207 name: "log2".into(),
208 args: 1,
209 variadic: false,
210 callback: |args| Ok(args[0].log2()),
211 description: Some("Base-2 logarithm".into()),
212 local: false,
213 },
214 Symbol::Func {
215 name: "log10".into(),
216 args: 1,
217 variadic: false,
218 callback: |args| Ok(args[0].log10()),
219 description: Some("Base-10 logarithm".into()),
220 local: false,
221 },
222 Symbol::Func {
223 name: "exp".into(),
224 args: 1,
225 variadic: false,
226 callback: |args| Ok(args[0].exp()),
227 description: Some("e raised to power x".into()),
228 local: false,
229 },
230 Symbol::Func {
231 name: "exp2".into(),
232 args: 1,
233 variadic: false,
234 callback: |args| Ok(args[0].exp2()),
235 description: Some("2 raised to power x".into()),
236 local: false,
237 },
238 Symbol::Func {
240 name: "abs".into(),
241 args: 1,
242 variadic: false,
243 callback: |args| Ok(args[0].abs()),
244 description: Some("Absolute value".into()),
245 local: false,
246 },
247 Symbol::Func {
248 name: "sign".into(),
249 args: 1,
250 variadic: false,
251 callback: |args| {
252 let x = args[0];
253 if x > 0.0 {
254 Ok(1.0)
255 } else if x < 0.0 {
256 Ok(-1.0)
257 } else {
258 Ok(0.0)
259 }
260 },
261 description: Some("Sign function (-1, 0, or 1)".into()),
262 local: false,
263 },
264 Symbol::Func {
265 name: "floor".into(),
266 args: 1,
267 variadic: false,
268 callback: |args| Ok(args[0].floor()),
269 description: Some("Floor function".into()),
270 local: false,
271 },
272 Symbol::Func {
273 name: "ceil".into(),
274 args: 1,
275 variadic: false,
276 callback: |args| Ok(args[0].ceil()),
277 description: Some("Ceiling function".into()),
278 local: false,
279 },
280 Symbol::Func {
281 name: "round".into(),
282 args: 1,
283 variadic: false,
284 callback: |args| Ok(args[0].round()),
285 description: Some("Round to nearest integer".into()),
286 local: false,
287 },
288 Symbol::Func {
289 name: "trunc".into(),
290 args: 1,
291 variadic: false,
292 callback: |args| Ok(args[0].trunc()),
293 description: Some("Truncate to integer".into()),
294 local: false,
295 },
296 Symbol::Func {
297 name: "fract".into(),
298 args: 1,
299 variadic: false,
300 callback: |args| Ok(args[0].fract()),
301 description: Some("Fractional part".into()),
302 local: false,
303 },
304 Symbol::Func {
305 name: "mod".into(),
306 args: 2,
307 variadic: false,
308 callback: |args| Ok(args[0] % args[1]),
309 description: Some("Remainder of x/y".into()),
310 local: false,
311 },
312 Symbol::Func {
313 name: "hypot".into(),
314 args: 2,
315 variadic: false,
316 callback: |args| Ok(args[0].hypot(args[1])),
317 description: Some("Euclidean distance sqrt(x²+y²)".into()),
318 local: false,
319 },
320 Symbol::Func {
321 name: "clamp".into(),
322 args: 3,
323 variadic: false,
324 callback: |args| Ok(args[0].clamp(args[1].min(args[2]), args[2].max(args[1]))),
325 description: Some("Constrain value between bounds".into()),
326 local: false,
327 },
328 Symbol::Func {
330 name: "min".into(),
331 args: 1,
332 variadic: true,
333 callback: |args| Ok(args.iter().fold(f64::INFINITY, |acc, &x| acc.min(x))),
334 description: Some("Minimum value".into()),
335 local: false,
336 },
337 Symbol::Func {
338 name: "max".into(),
339 args: 1,
340 variadic: true,
341 callback: |args| Ok(args.iter().fold(f64::NEG_INFINITY, |acc, &x| acc.max(x))),
342 description: Some("Maximum value".into()),
343 local: false,
344 },
345 Symbol::Func {
346 name: "sum".into(),
347 args: 1,
348 variadic: true,
349 callback: |args| Ok(args.iter().sum()),
350 description: Some("Sum of values".into()),
351 local: false,
352 },
353 Symbol::Func {
354 name: "avg".into(),
355 args: 1,
356 variadic: true,
357 callback: |args| {
358 let sum: f64 = args.iter().sum();
359 let count = args.len() as f64;
360 Ok(sum / count)
361 },
362 description: Some("Average of values".into()),
363 local: false,
364 },
365 ])
366 }
367}