1use std::io::Read;
2use std::io::Write;
3use std::time::SystemTime;
4use std::time::UNIX_EPOCH;
5
6use libloading::Library;
7use rand::Rng;
8use seq_macro::seq;
9use malachite::Integer;
10use malachite::num::arithmetic::traits::Abs;
11use serde::Deserialize;
12use serde::Serialize;
13
14use crate::annotations::Annotation;
15use crate::compilation::CompiledRynaExpr;
16use crate::integer_ext::*;
17use crate::parser::Location;
18use crate::ARR_IT_OF;
19use crate::ARR_OF;
20use crate::types::*;
21use crate::object::*;
22use crate::context::RynaContext;
23
24pub type FunctionOverloadFn = fn(&Vec<Type>, &Type, Vec<Object>, &RynaContext) -> Result<Object, String>;
32pub type OptFunctionOverloadFn = Option<FunctionOverloadFn>;
33
34#[derive(Clone, Serialize, Deserialize)]
35pub struct FunctionOverload {
36 pub location: Location,
37 pub annotations: Vec<Annotation>,
38 pub templates: usize,
39 pub args: Type,
40 pub ret: Type,
41
42 #[serde(skip)]
43 pub function: OptFunctionOverloadFn
44}
45
46pub type FunctionOverloads = Vec<FunctionOverload>;
47
48const EMPTY_FUNC: FunctionOverloadFn = |_, _, _, _| Ok(Object::empty());
49
50#[derive(Clone, Serialize, Deserialize)]
51pub struct Function {
52 pub id: usize,
53 pub name: String,
54 pub overloads: FunctionOverloads
55}
56
57macro_rules! define_unary_function {
64 ($ctx: ident, $id: expr, $inner_type: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $deref: ident, $result: expr) => {
65 $ctx.define_native_function_overload(
66 $id, 0,
67 &[$inner_type],
68 $return_type,
69 |_, _, v, _| {
70 let $a = v[0].$deref::<$unwrap_type>();
71 return Ok(Object::new($result));
72 }
73 ).unwrap();
74 };
75}
76
77macro_rules! define_binary_function {
78 ($ctx: ident, $id: expr, $inner_type_a: expr, $inner_type_b: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $deref_a: ident, $b: ident, $deref_b: ident, $result: expr) => {
79 $ctx.define_native_function_overload(
80 $id, 0,
81 &[$inner_type_a, $inner_type_b],
82 $return_type,
83 |_, _, v, _| {
84 let $a = v[0].$deref_a::<$unwrap_type>();
85 let $b = v[1].$deref_b::<$unwrap_type>();
86
87 return Ok(Object::new($result));
88 }
89 ).unwrap();
90 };
91}
92
93macro_rules! define_unary_function_overloads {
94 ($ctx: ident, $id: expr, $inner_type: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $result: expr) => {
95 define_unary_function!($ctx, $id, $inner_type, $return_type, $unwrap_type, $a, get, $result);
96 define_unary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $result);
97 define_unary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $result);
98 };
99}
100
101macro_rules! define_binary_function_overloads {
102 ($ctx: ident, $id: expr, $inner_type: expr, $return_type: expr, $unwrap_type: ident, $a: ident, $b: ident, $result: expr) => {
103 define_binary_function!($ctx, $id, $inner_type, $inner_type, $return_type, $unwrap_type, $a, get, $b, get, $result);
104 define_binary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), $inner_type, $return_type, $unwrap_type, $a, deref, $b, get, $result);
105 define_binary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), $inner_type, $return_type, $unwrap_type, $a, deref, $b, get, $result);
106 define_binary_function!($ctx, $id, $inner_type, Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, get, $b, deref, $result);
107 define_binary_function!($ctx, $id, $inner_type, Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, get, $b, deref, $result);
108 define_binary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
109 define_binary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), Type::Ref(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
110 define_binary_function!($ctx, $id, Type::Ref(Box::new($inner_type)), Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
111 define_binary_function!($ctx, $id, Type::MutRef(Box::new($inner_type)), Type::MutRef(Box::new($inner_type)), $return_type, $unwrap_type, $a, deref, $b, deref, $result);
112 };
113}
114
115pub const ITERATOR_FUNC_ID: usize = 10;
117pub const NEXT_FUNC_ID: usize = 11;
118pub const IS_CONSUMED_FUNC_ID: usize = 12;
119
120pub fn standard_functions(ctx: &mut RynaContext) {
121 let idx = ctx.define_function("inc".into()).unwrap();
122
123 ctx.define_native_function_overload(idx, 0, &[INT.to_mut()], Type::Empty, EMPTY_FUNC).unwrap();
124
125 let idx = ctx.define_function("print".into()).unwrap();
126
127 ctx.define_native_function_overload(idx, 0, &[INT], Type::Empty, |_, _, v, _| {
128 print!("{}", v[0].get::<Integer>());
129
130 Ok(Object::empty())
131 }).unwrap();
132
133 ctx.define_native_function_overload(idx, 0, &[FLOAT], Type::Empty, |_, _, v, _| {
134 print!("{}", v[0].get::<f64>());
135
136 Ok(Object::empty())
137 }).unwrap();
138
139 ctx.define_native_function_overload(idx, 0, &[BOOL], Type::Empty, |_, _, v, _| {
140 print!("{}", v[0].get::<bool>());
141
142 Ok(Object::empty())
143 }).unwrap();
144
145 ctx.define_native_function_overload(idx, 0, &[STR], Type::Empty, |_, _, v, _| {
146 print!("{}", v[0].get::<String>());
147
148 Ok(Object::empty())
149 }).unwrap();
150
151 ctx.define_native_function_overload(idx, 0, &[INT.to_ref().or(INT.to_mut())], Type::Empty, |_, _, v, _| {
152 print!("{}", v[0].deref::<Integer>());
153
154 Ok(Object::empty())
155 }).unwrap();
156
157 ctx.define_native_function_overload(idx, 0, &[FLOAT.to_ref().or(FLOAT.to_mut())], Type::Empty, |_, _, v, _| {
158 print!("{}", v[0].deref::<f64>());
159
160 Ok(Object::empty())
161 }).unwrap();
162
163 ctx.define_native_function_overload(idx, 0, &[BOOL.to_ref().or(BOOL.to_mut())], Type::Empty, |_, _, v, _| {
164 print!("{}", v[0].deref::<bool>());
165
166 Ok(Object::empty())
167 }).unwrap();
168
169 ctx.define_native_function_overload(idx, 0, &[STR.to_ref().or(STR.to_mut())], Type::Empty, |_, _, v, _| {
170 print!("{}", v[0].deref::<String>());
171
172 Ok(Object::empty())
173 }).unwrap();
174
175 let idx = ctx.define_function("deref".into()).unwrap();
176
177 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], T_0, EMPTY_FUNC).unwrap();
178 ctx.define_native_function_overload(idx, 1, &[T_0.to_ref()], T_0, EMPTY_FUNC).unwrap();
179
180 let idx = ctx.define_function("ref".into()).unwrap();
181
182 ctx.define_native_function_overload(idx, 1, &[T_0], T_0.to_ref(), EMPTY_FUNC).unwrap();
183
184 let idx = ctx.define_function("mut".into()).unwrap();
185
186 ctx.define_native_function_overload(idx, 1, &[T_0], T_0.to_mut(), EMPTY_FUNC).unwrap();
187
188 let idx = ctx.define_function("demut".into()).unwrap();
189
190 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], T_0.to_ref(), EMPTY_FUNC).unwrap();
191
192 let idx = ctx.define_function("arr".into()).unwrap();
193
194 ctx.define_native_function_overload(idx, 1, &[], ARR_OF!(T_0), |t, _, _, _| Ok(Object::arr(vec!(), t[0].clone()))).unwrap();
195
196 let idx = ctx.define_function("push".into()).unwrap();
197
198 ctx.define_native_function_overload(
199 idx,
200 1,
201 &[ARR_OF!(T_0).to_mut(), T_0],
202 Type::Empty,
203 |_, _, v, _| {
204 let array = v[0].deref::<RynaArray>();
205 array.elements.push(v[1].clone());
206
207 Ok(Object::empty())
208 }
209 ).unwrap();
210
211 let idx = ctx.define_function("reserve".into()).unwrap();
212
213 ctx.define_native_function_overload(
214 idx,
215 1,
216 &[ARR_OF!(T_0).to_mut(), INT],
217 Type::Empty,
218 |_, _, v, _| {
219 let array = v[0].deref::<RynaArray>();
220 let size = v[1].get::<Integer>();
221
222 if is_valid_index(size) && array.elements.try_reserve_exact(to_usize(size)).is_ok() {
223 Ok(Object::empty())
224
225 } else {
226 Err(format!("Unable to reserve {} elements", size))
227 }
228 }
229 ).unwrap();
230
231 let idx = ctx.define_function("capacity".into()).unwrap();
232
233 ctx.define_native_function_overload(
234 idx,
235 1,
236 &[ARR_OF!(T_0).to_ref()],
237 INT,
238 |_, _, mut v, _| Ok(Object::new(Integer::from(v.pop().unwrap().deref::<RynaArray>().elements.capacity() as u64)))
239 ).unwrap();
240
241 ctx.define_native_function_overload(
242 idx,
243 1,
244 &[ARR_OF!(T_0).to_mut()],
245 INT,
246 |_, _, mut v, _| Ok(Object::new(Integer::from(v.pop().unwrap().deref::<RynaArray>().elements.capacity() as u64)))
247 ).unwrap();
248
249 let idx = ctx.define_function("iterator".into()).unwrap();
250
251 ctx.define_native_function_overload(
252 idx,
253 1,
254 &[ARR_OF!(T_0).to_mut()],
255 ARR_IT_OF!(T_0, T_0.to_mut()),
256 |t, _, v, _| {
257 return Ok(Object::arr_it(
258 t[0].clone(),
259 Type::MutRef(Box::new(t[0].clone())),
260 v[0].inner.borrow().dereference().clone(),
261 0
262 ));
263 }
264 ).unwrap();
265
266 ctx.define_native_function_overload(
267 idx,
268 1,
269 &[ARR_OF!(T_0).to_ref()],
270 ARR_IT_OF!(T_0, T_0.to_ref()),
271 |t, _, v, _| {
272 return Ok(Object::arr_it(
273 t[0].clone(),
274 Type::Ref(Box::new(t[0].clone())),
275 v[0].inner.borrow().dereference().clone(),
276 0
277 ));
278 }
279 ).unwrap();
280
281 ctx.define_native_function_overload(
282 idx,
283 1,
284 &[ARR_OF!(T_0)],
285 ARR_IT_OF!(T_0, T_0.to_mut()),
286 |t, _, v, _| {
287 Ok(Object::arr_it(
288 t[0].clone(),
289 Type::MutRef(Box::new(t[0].clone())),
290 v[0].inner.clone(),
291 0
292 ))
293 }
294 ).unwrap();
295
296 ctx.define_native_function_overload(
297 idx,
298 1,
299 &[ARR_IT_OF!(T_0, T_0.to_mut())],
300 ARR_IT_OF!(T_0, T_0.to_mut()),
301 |_, _, mut v, _| Ok(v.pop().unwrap())
302 ).unwrap();
303
304 ctx.define_native_function_overload(
305 idx,
306 1,
307 &[ARR_IT_OF!(T_0, T_0.to_ref())],
308 ARR_IT_OF!(T_0, T_0.to_ref()),
309 |_, _, mut v, _| Ok(v.pop().unwrap())
310 ).unwrap();
311
312 let idx = ctx.define_function("next".into()).unwrap();
313
314 ctx.define_native_function_overload(
315 idx,
316 1,
317 &[Type::MutRef(Box::new(ARR_IT_OF!(T_0, T_0.to_mut())))],
318 T_0.to_mut(),
319 |_, _, v, _| {
320 let iterator = v[0].deref::<RynaArrayIt>();
321 let item;
322
323 {
324 let reference = iterator.block.borrow_mut();
325 let array = &reference.mut_inner::<RynaArray>();
326 item = array.elements[iterator.pos].get_mut();
327 }
328
329 iterator.pos += 1;
330
331 Ok(item)
332 }
333 ).unwrap();
334
335 ctx.define_native_function_overload(
336 idx,
337 1,
338 &[Type::MutRef(Box::new(ARR_IT_OF!(T_0, T_0.to_ref())))],
339 T_0.to_ref(),
340 |_, _, v, _| {
341 let iterator = v[0].deref::<RynaArrayIt>();
342 let item;
343
344 {
345 let reference = iterator.block.borrow_mut();
346 let array = &reference.mut_inner::<RynaArray>();
347 item = array.elements[iterator.pos].get_ref();
348 }
349
350 iterator.pos += 1;
351
352 Ok(item)
353 }
354 ).unwrap();
355
356 let idx = ctx.define_function("is_consumed".into()).unwrap();
357
358 ctx.define_native_function_overload(
359 idx,
360 1,
361 &[ARR_IT_OF!(T_0, T_0.to_mut()).to_mut()],
362 BOOL,
363 |_, _, v, _| {
364 let iterator = v[0].deref::<RynaArrayIt>();
365
366 return Ok(Object::new(iterator.pos >= iterator.block.borrow().get_inner::<RynaArray>().elements.len()));
367 }
368 ).unwrap();
369
370 ctx.define_native_function_overload(
371 idx,
372 1,
373 &[ARR_IT_OF!(T_0, T_0.to_ref()).to_mut()],
374 BOOL,
375 |_, _, v, _| {
376 let iterator = v[0].deref::<RynaArrayIt>();
377
378 return Ok(Object::new(iterator.pos >= iterator.block.borrow().get_inner::<RynaArray>().elements.len()));
379 }
380 ).unwrap();
381
382 let idx = ctx.define_function("$container".into()).unwrap();
383
384 ctx.define_native_function_overload( idx,
386 1,
387 &[ARR_IT_OF!(T_0, Type::Wildcard).to_mut()],
388 ARR_OF!(T_0).to_ref(),
389 |_, _, v, _| {
390 let iterator = v[0].deref::<RynaArrayIt>();
391
392 return Ok(iterator.get_container_ref());
393 }
394 ).unwrap();
395
396 ctx.define_native_function_overload( idx,
398 1,
399 &[ARR_IT_OF!(T_0, Type::Wildcard).to_ref()],
400 ARR_OF!(T_0).to_ref(),
401 |_, _, v, _| {
402 let iterator = v[0].deref::<RynaArrayIt>();
403
404 return Ok(iterator.get_container_ref());
405 }
406 ).unwrap();
407
408 let idx = ctx.define_function("panic".into()).unwrap();
409
410 ctx.define_native_function_overload(
411 idx,
412 0,
413 &[STR],
414 Type::Empty,
415 |_, _, v, _| {
416 return Err(v[0].get::<String>().clone());
417 }
418 ).unwrap();
419
420 let idx = ctx.define_function("len".into()).unwrap();
421
422 ctx.define_native_function_overload(
423 idx,
424 0,
425 &[ARR_OF!(Type::Wildcard).to_ref()],
426 INT,
427 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<RynaArray>().elements.len() as u64)))
428 ).unwrap();
429
430 ctx.define_native_function_overload(
431 idx,
432 0,
433 &[ARR_OF!(Type::Wildcard).to_mut()],
434 INT,
435 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<RynaArray>().elements.len() as u64)))
436 ).unwrap();
437
438 ctx.define_native_function_overload(
439 idx,
440 0,
441 &[STR.to_ref()],
442 INT,
443 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<String>().len() as u64)))
444 ).unwrap();
445
446 ctx.define_native_function_overload(
447 idx,
448 0,
449 &[STR.to_mut()],
450 INT,
451 |_, _, v, _| Ok(Object::new(Integer::from(v[0].deref::<String>().len() as u64)))
452 ).unwrap();
453
454 let idx = ctx.define_function("sin".into()).unwrap();
455
456 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).sin());
457 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.sin());
458
459 let idx = ctx.define_function("cos".into()).unwrap();
460
461 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).cos());
462 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.cos());
463
464 let idx = ctx.define_function("tan".into()).unwrap();
465
466 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).tan());
467 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.tan());
468
469 let idx = ctx.define_function("sinh".into()).unwrap();
470
471 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).sinh());
472 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.sinh());
473
474 let idx = ctx.define_function("cosh".into()).unwrap();
475
476 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).cosh());
477 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.cosh());
478
479 let idx = ctx.define_function("tanh".into()).unwrap();
480
481 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).tanh());
482 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.tanh());
483
484 let idx = ctx.define_function("ln".into()).unwrap();
485
486 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).ln());
487 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.ln());
488
489 let idx = ctx.define_function("log2".into()).unwrap();
490
491 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).log2());
492 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.log2());
493
494 let idx = ctx.define_function("log10".into()).unwrap();
495
496 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).log10());
497 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.log10());
498
499 let idx = ctx.define_function("exp".into()).unwrap();
500
501 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).exp());
502 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.exp());
503
504 let idx = ctx.define_function("floor".into()).unwrap();
505
506 define_unary_function_overloads!(ctx, idx, FLOAT, INT, f64, a, Integer::from(a.floor() as u64));
507
508 let idx = ctx.define_function("round".into()).unwrap();
509
510 define_unary_function_overloads!(ctx, idx, FLOAT, INT, f64, a, Integer::from(a.round() as u64));
511
512 let idx = ctx.define_function("ceil".into()).unwrap();
513
514 define_unary_function_overloads!(ctx, idx, FLOAT, INT, f64, a, Integer::from(a.ceil() as u64));
515
516 let idx = ctx.define_function("fract".into()).unwrap();
517
518 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.fract());
519
520 let idx = ctx.define_function("sqrt".into()).unwrap();
521
522 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a).sqrt());
523 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.sqrt());
524
525 let idx = ctx.define_function("abs".into()).unwrap();
526
527 define_unary_function_overloads!(ctx, idx, INT, INT, Integer, a, a.clone().abs());
528 define_unary_function_overloads!(ctx, idx, FLOAT, FLOAT, f64, a, a.abs());
529
530 let idx = ctx.define_function("rand".into()).unwrap();
531
532 ctx.define_native_function_overload(idx, 0, &[], FLOAT, |_, _, _, _| Ok(Object::new(rand::thread_rng().gen_range(0.0..1.0)))).unwrap();
533
534 let idx = ctx.define_function("rand_int".into()).unwrap();
535
536 define_binary_function_overloads!(ctx, idx, INT, INT, Integer, a, b, randint(a.clone(), b.clone()));
537
538 let idx = ctx.define_function("as_float".into()).unwrap();
539
540 define_unary_function_overloads!(ctx, idx, INT, FLOAT, Integer, a, to_f64(a));
541
542 let idx = ctx.define_function("is".into()).unwrap();
543
544 ctx.define_native_function_overload(
545 idx,
546 1,
547 &[Type::Wildcard],
548 BOOL,
549 |t, _, v, ctx| Ok(Object::new(v[0].get_type().bindable_to(&t[0], ctx)))
550 ).unwrap();
551
552 let idx = ctx.define_function("as".into()).unwrap();
553
554 ctx.define_native_function_overload(
555 idx,
556 1,
557 &[Type::Wildcard],
558 T_0,
559 |t, _, mut v, ctx| {
560 let obj = v.pop().unwrap();
561 let obj_type = obj.get_type();
562
563 if !obj_type.bindable_to(&t[0], ctx) {
564 Err(format!("Unable to get value of type {} as {}", obj_type.get_name(ctx), t[0].get_name(ctx)))
565
566 } else {
567 Ok(obj)
568 }
569 }
570 ).unwrap();
571
572 let idx = ctx.define_function("$unsafe_as".into()).unwrap(); ctx.define_native_function_overload(
575 idx,
576 1,
577 &[Type::Wildcard],
578 T_0,
579 |_, _, mut v, _| {
580 let obj = v.pop().unwrap();
581
582 Ok(obj.unsafe_move_contents().get_ref())
583 }
584 ).unwrap();
585
586 let idx = ctx.define_function("drop".into()).unwrap();
587
588 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], Type::Empty, |_, _, mut v, _| {
589 v.pop().unwrap().drop_contents();
590 Ok(Object::empty())
591 }).unwrap();
592
593 let idx = ctx.define_function("$drop_unsafe".into()).unwrap(); ctx.define_native_function_overload(
596 idx,
597 0,
598 &[ARR_OF!(Type::Wildcard).to_ref(), INT],
599 Type::Empty,
600 |_, _, v, _| {
601 let array = v[0].deref::<RynaArray>();
602 let idx = v[1].get::<Integer>();
603
604 if !is_valid_index(idx) {
605 return Err(format!("{} is not a valid index", idx));
606
607 } else if array.elements.len() <= to_usize(idx) {
608 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
609 }
610
611 array.elements[to_usize(idx)] = Object::no_value();
612
613 Ok(Object::empty())
614 }
615 ).unwrap();
616
617 let idx = ctx.define_function("$drop_attr_unsafe".into()).unwrap(); ctx.define_native_function_overload(idx, 0, &[Type::Wildcard.to_ref(), INT], Type::Empty, |_, _, v, _| {
620 let obj = v[0].deref::<TypeInstance>();
621 let attr = v[1].get::<Integer>();
622
623 obj.attributes[to_usize(attr)] = Object::no_value();
624
625 Ok(Object::empty())
626 }).unwrap();
627
628 let idx = ctx.define_function("move".into()).unwrap();
629
630 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut()], T_0, EMPTY_FUNC).unwrap();
631
632 let idx = ctx.define_function("fwd".into()).unwrap();
633
634 ctx.define_native_function_overload(idx, 1, &[Type::Wildcard], T_0, |a, _, mut v, ctx| {
635 let type_arg = a.last().unwrap();
636 let param_arg = v.last().unwrap().get_type();
637
638 match (type_arg, ¶m_arg) {
639 (Type::Ref(a), Type::Ref(b)) if a == b => Ok(v.pop().unwrap()),
640 (Type::MutRef(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap()),
641 (Type::Ref(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap().get_ref()),
642
643 (a, Type::MutRef(b)) if *a == **b => Ok(v.pop().unwrap().move_contents()),
644 (a, Type::Ref(b)) if *a == **b => Ok(v.pop().unwrap().deref_obj().deep_clone()),
645
646 (Type::MutRef(b), a) if *a == **b => Ok(v.pop().unwrap().get_mut_nostack()),
647 (Type::Ref(b), a) if *a == **b => Ok(v.pop().unwrap().get_ref_nostack()),
648
649 (a, b) if a == b => Ok(v.pop().unwrap().move_contents()),
650
651 _ => Err(format!(
652 "Unable to forward value of type {} as type {}",
653 param_arg.get_name(ctx),
654 type_arg.get_name(ctx)
655 ))
656 }
657 }).unwrap();
658
659 let idx = ctx.define_function("cfwd".into()).unwrap();
660
661 ctx.define_native_function_overload(idx, 1, &[Type::Wildcard], T_0, |a, _, mut v, ctx| {
662 let type_arg = a.last().unwrap();
663 let param_arg = v.last().unwrap().get_type();
664
665 match (type_arg, ¶m_arg) {
666 (Type::Ref(a), Type::Ref(b)) if a == b => Ok(v.pop().unwrap()),
667 (Type::MutRef(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap()),
668 (Type::Ref(a), Type::MutRef(b)) if a == b => Ok(v.pop().unwrap().get_ref()),
669
670 (a, Type::MutRef(b)) if *a == **b => Ok(v.pop().unwrap().deref_obj().deep_clone()),
671 (a, Type::Ref(b)) if *a == **b => Ok(v.pop().unwrap().deref_obj().deep_clone()),
672
673 (Type::MutRef(b), a) if *a == **b => Ok(v.pop().unwrap().get_mut_nostack()),
674 (Type::Ref(b), a) if *a == **b => Ok(v.pop().unwrap().get_ref_nostack()),
675
676 (a, b) if a == b => Ok(v.pop().unwrap().deep_clone()),
677
678 _ => Err(format!(
679 "Unable to forward value of type {} as type {}",
680 param_arg.get_name(ctx),
681 type_arg.get_name(ctx)
682 ))
683 }
684 }).unwrap();
685
686 let idx = ctx.define_function("swap".into()).unwrap();
687
688 ctx.define_native_function_overload(idx, 1, &[T_0.to_mut(), T_0.to_mut()], Type::Empty, |_, _, mut v, _| {
689 let a = v.pop().unwrap();
690 let b = v.pop().unwrap();
691
692 a.swap_contents(&b);
693
694 Ok(Object::empty())
695 }).unwrap();
696
697 let idx = ctx.define_function("get_file".into()).unwrap();
698
699 ctx.define_native_function_overload(idx, 0, &[STR], FILE, |_, _, v, _| {
700 let path = v[0].get::<String>();
701 let pathbuf = std::path::Path::new(path);
702
703 Ok(Object::file(pathbuf.into()))
704 }).unwrap();
705
706 let idx = ctx.define_function("open".into()).unwrap();
707
708 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), BOOL, BOOL, BOOL], Type::Empty, |_, _, v, _| {
709 let file = &mut *v[0].deref::<RynaFile>();
710 let read = *v[1].get::<bool>();
711 let write = *v[2].get::<bool>();
712 let append = *v[3].get::<bool>();
713
714 file.open(read, write, append)?;
715
716 Ok(Object::empty())
717 }).unwrap();
718
719 let idx = ctx.define_function("close".into()).unwrap();
720
721 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], Type::Empty, |_, _, v, _| {
722 let file = &mut *v[0].deref::<RynaFile>();
723 file.close()?;
724
725 Ok(Object::empty())
726 }).unwrap();
727
728 let idx = ctx.define_function("exists".into()).unwrap();
729
730 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], BOOL, |_, _, v, _| {
731 let file = &*v[0].deref::<RynaFile>();
732
733 Ok(ObjectBlock::Bool(file.exists()?).to_obj())
734 }).unwrap();
735
736 let idx = ctx.define_function("delete".into()).unwrap();
737
738 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], BOOL, |_, _, v, _| {
739 let file = &mut *v[0].deref::<RynaFile>();
740
741 Ok(ObjectBlock::Bool(file.delete()?).to_obj())
742 }).unwrap();
743
744 let idx = ctx.define_function("read_str".into()).unwrap();
745
746 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], STR, |_, _, v, _| {
747 let file = v[0].deref::<RynaFile>();
748 let mut buf = String::new();
749
750 if !file.is_open() {
751 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
752 }
753
754 let res = file.file.as_ref().unwrap().borrow_mut().read_to_string(&mut buf);
755
756 match res {
757 Ok(_) => Ok(ObjectBlock::Str(buf).to_obj()),
758 Err(_) => Err("Unable to read file".into())
759 }
760 }).unwrap();
761
762 let idx = ctx.define_function("read_bytes".into()).unwrap();
763
764 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut()], ARR_OF!(INT), |_, _, v, _| {
765 let file = v[0].deref::<RynaFile>();
766 let mut buf = vec!();
767
768 if !file.is_open() {
769 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
770 }
771
772 let res = file.file.as_ref().unwrap().borrow_mut().read_to_end(&mut buf);
773
774 match res {
775 Ok(_) => {
776 let arr = buf.into_iter().map(|i| ObjectBlock::Int(Integer::from(i as u32)).to_obj()).collect();
777 Ok(Object::arr(arr, INT))
778 },
779 Err(_) => Err("Unable to read file".into())
780 }
781 }).unwrap();
782
783 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), INT], ARR_OF!(INT), |_, _, v, _| {
784 let file = v[0].deref::<RynaFile>();
785 let num_bytes = v[1].get::<Integer>();
786
787 if !is_valid_index(num_bytes) || *num_bytes == *ZERO {
788 return Err(format!("Unable to read {} bytes from file", num_bytes));
789 }
790
791 if !file.is_open() {
792 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
793 }
794
795 let mut buf = vec!(0; to_usize(num_bytes));
796 let res = file.file.as_ref().unwrap().borrow_mut().read_exact(&mut buf);
797
798 match res {
799 Ok(_) => {
800 let arr = buf.into_iter().map(|i| ObjectBlock::Int(Integer::from(i as u32)).to_obj()).collect();
801 Ok(Object::arr(arr, INT))
802 },
803 Err(_) => Err("Unable to read file".into())
804 }
805 }).unwrap();
806
807 let idx = ctx.define_function("write_str".into()).unwrap();
808
809 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), STR.to_ref()], BOOL, |_, _, v, _| {
810 let file = v[0].deref::<RynaFile>();
811 let content = &*v[1].deref::<String>();
812
813 if !file.is_open() {
814 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
815 }
816
817 let ok = file.file.as_ref().unwrap().borrow_mut().write_all(content.as_bytes()).is_ok();
818
819 Ok(ObjectBlock::Bool(ok).to_obj())
820 }).unwrap();
821
822 let idx = ctx.define_function("write_bytes".into()).unwrap();
823
824 ctx.define_native_function_overload(idx, 0, &[FILE.to_mut(), ARR_OF!(INT).to_ref()], BOOL, |_, _, v, _| {
825 let file = v[0].deref::<RynaFile>();
826 let content = &*v[1].deref::<RynaArray>();
827
828 if !file.is_open() {
829 return Err(format!("File at {} is closed", file.path.to_str().unwrap()));
830 }
831
832 let mut bytes = vec!();
833 bytes.reserve_exact(content.elements.len());
834
835 for n in &content.elements {
836 let byte = n.get::<Integer>();
837
838 if is_valid_byte(byte) {
839 bytes.push(to_u8(byte));
840
841 } else {
842 return Err(format!("{} is not a valid byte value", byte));
843 }
844 }
845
846 let ok = file.file.as_ref().unwrap().borrow_mut().write_all(&bytes).is_ok();
847
848 Ok(ObjectBlock::Bool(ok).to_obj())
849 }).unwrap();
850
851 let idx = ctx.define_function("to_string".into()).unwrap();
852
853 ctx.define_native_function_overload(idx, 0, &[INT], STR, |_, _, mut v, _| {
854 let obj = v.pop().unwrap().get::<Integer>().to_string();
855
856 Ok(ObjectBlock::Str(obj).to_obj())
857 }).unwrap();
858
859 ctx.define_native_function_overload(idx, 0, &[FLOAT], STR, |_, _, mut v, _| {
860 let obj = v.pop().unwrap().get::<f64>().to_string();
861
862 Ok(ObjectBlock::Str(obj).to_obj())
863 }).unwrap();
864
865 let idx = ctx.define_function("code_point_at".into()).unwrap();
867
868 ctx.define_native_function_overload(idx, 0, &[STR.to_ref().or(STR.to_mut()), INT], INT, |_, _, v, _| {
869 let string = &*v[0].deref::<String>();
870 let idx = v[1].get::<Integer>();
871
872 if !is_valid_index(idx) {
873 return Err(format!("{} is not a valid index", idx));
874
875 } else if string.len() <= to_usize(idx) {
876 return Err(format!("{} is higher than the length of the string ({})", idx, string.len()));
877 }
878
879 if let Some(character) = string[to_usize(idx)..].chars().next() {
880 Ok(ObjectBlock::Int(Integer::from(character as u64)).to_obj())
881
882 } else {
883 Err(format!("Invalid character start at position {}", idx))
884 }
885 }).unwrap();
886
887 let idx = ctx.define_function("code_point_to_str".into()).unwrap();
888
889 ctx.define_native_function_overload(idx, 0, &[INT], STR, |_, _, v, _| {
890 let cp = v[0].get::<Integer>();
891
892 if !is_valid_index(cp) {
893 return Err(format!("{} is not a valid code point", cp));
894 }
895
896 if let Some(character) = char::from_u32(to_u32(cp)) {
897 Ok(ObjectBlock::Str(character.to_string()).to_obj())
898
899 } else {
900 Err(format!("{} is not a valid code point", cp))
901 }
902 }).unwrap();
903
904 let idx = ctx.define_function("code_point_length".into()).unwrap();
905
906 ctx.define_native_function_overload(idx, 0, &[INT], INT, |_, _, v, _| {
907 let cp = v[0].get::<Integer>();
908
909 if !is_valid_index(cp) {
910 return Err(format!("{} is not a valid code point", cp));
911 }
912
913 if let Some(character) = char::from_u32(to_u32(cp)) {
914 Ok(ObjectBlock::Int(Integer::from(character.len_utf8() as u64)).to_obj())
915
916 } else {
917 Err(format!("{} is not a valid code point", cp))
918 }
919 }).unwrap();
920
921 let idx = ctx.define_function("utf8_array".into()).unwrap();
922
923 ctx.define_native_function_overload(idx, 0, &[STR.to_ref().or(STR.to_mut())], ARR_OF!(INT), |_, _, v, _| {
924 let string = &*v[0].deref::<String>();
925 let arr = string.bytes()
926 .map(|i| ObjectBlock::Int(Integer::from(i as u64)).to_obj())
927 .collect();
928
929 Ok(Object::arr(arr, INT))
930 }).unwrap();
931
932 let idx = ctx.define_function("utf8_to_str".into()).unwrap();
933
934 ctx.define_native_function_overload(idx, 0, &[ARR_OF!(INT).to_ref().or(ARR_OF!(INT).to_mut())], STR, |_, _, v, _| {
935 let arr = &*v[0].deref::<RynaArray>();
936 let mut bytes = vec!();
937 bytes.reserve_exact(arr.elements.len());
938
939 for i in &arr.elements {
940 let n = i.get::<Integer>();
941
942 if !is_valid_byte(n) {
943 return Err(format!("{} is not a valid byte", n));
944 }
945
946 bytes.push(to_u8(n));
947 }
948
949 if let Ok(string) = String::from_utf8(bytes) {
950 Ok(ObjectBlock::Str(string).to_obj())
951
952 } else {
953 Err("Invalid UTF-8 array".into())
954 }
955 }).unwrap();
956
957 let idx = ctx.define_function("truncate".into()).unwrap();
958
959 ctx.define_native_function_overload(idx, 0, &[INT], INT, |_, _, v, _| {
960 let cp = v[0].get::<Integer>();
961 Ok(Object::new(truncate(cp)))
962 }).unwrap();
963
964 let idx = ctx.define_function("input".into()).unwrap();
965
966 ctx.define_native_function_overload(idx, 0, &[], STR, |_, _, _, _| {
967 let mut buffer = String::new();
968
969 std::io::stdout().flush().unwrap();
970 std::io::stdin().read_line(&mut buffer).unwrap();
971
972 Ok(Object::new(buffer))
973 }).unwrap();
974
975 let idx = ctx.define_function("num_args".into()).unwrap();
976
977 ctx.define_native_function_overload(idx, 0, &[], INT, |_, _, _, ctx| {
978 Ok(Object::new(Integer::from(ctx.program_input.len() as u64)))
979 }).unwrap();
980
981 let idx = ctx.define_function("get_arg".into()).unwrap();
982
983 ctx.define_native_function_overload(idx, 0, &[INT], STR, |_, _, v, ctx| {
984 let idx = v[0].get::<Integer>();
985
986 if !is_valid_index(idx) {
987 return Err(format!("{} is not a valid index", idx));
988
989 } else if ctx.program_input.len() <= to_usize(idx) {
990 return Err(format!("{} is higher than the number of input arguments ({})", idx, ctx.program_input.len()));
991 }
992
993 Ok(Object::new(ctx.program_input[to_usize(idx)].clone()))
994 }).unwrap();
995
996 let idx = ctx.define_function("set".into()).unwrap();
997
998 ctx.define_native_function_overload(
999 idx,
1000 1,
1001 &[ARR_OF!(T_0).to_mut(), T_0, INT],
1002 Type::Empty,
1003 |_, _, v, _| {
1004 let array = v[0].deref::<RynaArray>();
1005 let idx = v[2].get::<Integer>();
1006
1007 if !is_valid_index(idx) {
1008 return Err(format!("{} is not a valid index", idx));
1009
1010 } else if array.elements.len() <= to_usize(idx) {
1011 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
1012 }
1013
1014 array.elements[to_usize(idx)] = v[1].clone();
1015
1016 Ok(Object::empty())
1017 }
1018 ).unwrap();
1019
1020 let idx = ctx.define_function("insert".into()).unwrap();
1021
1022 ctx.define_native_function_overload(
1023 idx,
1024 1,
1025 &[ARR_OF!(T_0).to_mut(), T_0, INT],
1026 Type::Empty,
1027 |_, _, v, _| {
1028 let array = v[0].deref::<RynaArray>();
1029 let idx = v[2].get::<Integer>();
1030
1031 if !is_valid_index(idx) {
1032 return Err(format!("{} is not a valid index", idx));
1033
1034 } else if array.elements.len() < to_usize(idx) {
1035 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
1036 }
1037
1038 array.elements.insert(to_usize(idx), v[1].clone());
1039
1040 Ok(Object::empty())
1041 }
1042 ).unwrap();
1043
1044 let idx = ctx.define_function("remove".into()).unwrap();
1045
1046 ctx.define_native_function_overload(
1047 idx,
1048 1,
1049 &[ARR_OF!(T_0).to_mut(), INT],
1050 Type::Empty,
1051 |_, _, v, _| {
1052 let array = v[0].deref::<RynaArray>();
1053 let idx = v[1].get::<Integer>();
1054
1055 if !is_valid_index(idx) {
1056 return Err(format!("{} is not a valid index", idx));
1057
1058 } else if array.elements.len() <= to_usize(idx) {
1059 return Err(format!("{} is higher than the length of the array ({})", idx, array.elements.len()));
1060 }
1061
1062 array.elements.remove(to_usize(idx));
1063
1064 Ok(Object::empty())
1065 }
1066 ).unwrap();
1067
1068 let idx = ctx.define_function("pop".into()).unwrap();
1069
1070 ctx.define_native_function_overload(
1071 idx,
1072 1,
1073 &[ARR_OF!(T_0).to_mut()],
1074 Type::Empty,
1075 |_, _, v, _| {
1076 let array = v[0].deref::<RynaArray>();
1077 array.elements.pop();
1078
1079 Ok(Object::empty())
1080 }
1081 ).unwrap();
1082
1083 let idx = ctx.define_function("time".into()).unwrap();
1084
1085 ctx.define_native_function_overload(
1086 idx,
1087 0,
1088 &[],
1089 INT,
1090 |_, _, _, _| {
1091 let time = SystemTime::now().duration_since(UNIX_EPOCH);
1092
1093 match time {
1094 Ok(d) => {
1095 let duration = d.as_nanos();
1096
1097 Ok(Object::new(Integer::from(duration)))
1098 },
1099 Err(_) => Err("Unable to get current time".into()),
1100 }
1101 }
1102 ).unwrap();
1103
1104 let idx = ctx.define_function("dec".into()).unwrap();
1105
1106 ctx.define_native_function_overload(idx, 0, &[INT.to_mut()], Type::Empty, EMPTY_FUNC).unwrap();
1107
1108 let idx = ctx.define_function("write_ptr_int".into()).unwrap();
1109
1110 ctx.define_native_function_overload(
1111 idx,
1112 0,
1113 &[PTR, INT, INT],
1114 Type::Empty,
1115 |_, _, v, _| {
1116 let ptr = v[0].get::<RynaPointer>();
1117 let offset = v[1].get::<Integer>();
1118 let value = v[2].get::<Integer>();
1119
1120 unsafe { std::ptr::write((ptr.ptr as *mut i64).offset(to_i64(offset) as isize), to_i64(value)) };
1121
1122 Ok(Object::empty())
1123 }
1124 ).unwrap();
1125
1126 let idx = ctx.define_function("write_ptr_float".into()).unwrap();
1127
1128 ctx.define_native_function_overload(
1129 idx,
1130 0,
1131 &[PTR, INT, FLOAT],
1132 Type::Empty,
1133 |_, _, v, _| {
1134 let ptr = v[0].get::<RynaPointer>();
1135 let offset = v[1].get::<Integer>();
1136 let value = v[2].get::<f64>();
1137
1138 unsafe { std::ptr::write((ptr.ptr as *mut f64).offset(to_i64(offset) as isize), *value) };
1139
1140 Ok(Object::empty())
1141 }
1142 ).unwrap();
1143
1144 let idx = ctx.define_function("load_library".into()).unwrap();
1145
1146 ctx.define_native_function_overload(
1147 idx,
1148 0,
1149 &[STR],
1150 LIB,
1151 |_, _, v, _| {
1152 let path = v[0].get::<String>();
1153 let lib = unsafe { Library::new(&path) };
1154
1155 match lib {
1156 Ok(l) => {
1157 Ok(Object::new(RynaLibrary::new(path, l)))
1158 },
1159 Err(_) => Err(format!("Unable to load library at {path}")),
1160 }
1161 }
1162 ).unwrap();
1163
1164 let idx = ctx.define_function("get_function".into()).unwrap();
1165
1166 ctx.define_native_function_overload(
1167 idx,
1168 0,
1169 &[LIB.to_ref(), STR],
1170 LIB_FUNC,
1171 |_, _, v, _| {
1172 let lib = v[0].deref::<RynaLibrary>();
1173 let name = v[1].get::<String>();
1174
1175 lib.get_function(name).map(Object::new)
1176 }
1177 ).unwrap();
1178
1179 let idx = ctx.define_function("call".into()).unwrap();
1180
1181 for i in 0..20 {
1182 let mut args = vec!(LIB_FUNC.to_ref());
1183 args.extend(std::iter::repeat(Type::Wildcard).take(i));
1184
1185 ctx.define_native_function_overload(
1186 idx,
1187 0,
1188 &args,
1189 Type::Wildcard,
1190 |_, _, v, _| {
1191 let func = v[0].deref::<RynaLibraryFunction>();
1192 func.call(&v[1..])
1193 }
1194 ).unwrap();
1195 }
1196
1197 ctx.define_function("destroy".into()).unwrap();
1198 ctx.define_function("destroy_or".into()).unwrap();
1199
1200 seq!(I in 0..10 {
1202 let idx = ctx.define_function(format!("$drop_{}_unsafe", I)).unwrap(); seq!(J in 2..10 {
1205 let ts = Type::And((0..J).map(|i| Type::TemplateParam(i, vec!())).collect());
1206
1207 ctx.define_native_function_overload(
1208 idx,
1209 J,
1210 &[ts.to_ref()],
1211 Type::Empty,
1212 |_, _, v, _| {
1213 let tuple = v[0].deref::<RynaTuple>();
1214 tuple.elements[I] = Object::no_value();
1215
1216 Ok(Object::empty())
1217 }
1218 ).unwrap();
1219 });
1220
1221 let idx = ctx.define_function(format!("get_{}", I)).unwrap();
1222
1223 seq!(J in 2..10 {
1224 let ts = Type::And((0..J).map(|i| Type::TemplateParam(i, vec!())).collect());
1225
1226 let res = ctx.define_native_function_overload(
1227 idx,
1228 J,
1229 &[ts.clone()],
1230 Type::TemplateParam(I, vec!()),
1231 EMPTY_FUNC
1232 ).unwrap();
1233
1234 ctx.cache.opcodes.functions.insert((idx, res), (CompiledRynaExpr::TupleElemMove(I), 0));
1235
1236 let res = ctx.define_native_function_overload(
1237 idx,
1238 J,
1239 &[Type::Ref(Box::new(ts.clone()))],
1240 Type::Ref(Box::new(Type::TemplateParam(I, vec!()))),
1241 EMPTY_FUNC
1242 ).unwrap();
1243
1244 ctx.cache.opcodes.functions.insert((idx, res), (CompiledRynaExpr::TupleElemRef(I), 0));
1245
1246 let res = ctx.define_native_function_overload(
1247 idx,
1248 J,
1249 &[Type::MutRef(Box::new(ts))],
1250 Type::MutRef(Box::new(Type::TemplateParam(I, vec!()))),
1251 EMPTY_FUNC
1252 ).unwrap();
1253
1254 ctx.cache.opcodes.functions.insert((idx, res), (CompiledRynaExpr::TupleElemMut(I), 0));
1255 });
1256 });
1257}
1258
1259pub fn define_macro_emit_fn(ctx: &mut RynaContext, name: String) {
1260 let idx = ctx.define_function(name).unwrap();
1261
1262 ctx.define_native_function_overload(idx, 0, &[STR], crate::types::Type::Empty, |_, _, mut args, ctx| {
1263 let obj = args.pop().unwrap();
1264 let string = obj.get::<String>();
1265
1266 *ctx.captured_output.borrow_mut() += string;
1267
1268 Ok(Object::empty())
1269 }).unwrap();
1270}