nessa/
functions.rs

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