ryna/
functions.rs

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
24/*
25                                                  ╒══════════════════╕
26    ============================================= │  IMPLEMENTATION  │ =============================================
27                                                  ╘══════════════════╛
28*/
29
30// Takes type parameters, return type and arguments
31pub 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
57/*
58                                                  ╒══════════════════════╕
59    ============================================= │  STANDARD FUNCTIONS  │ =============================================
60                                                  ╘══════════════════════╛
61*/
62
63macro_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
115// Constant identifiers
116pub 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( // this is safe, but non-accesible by normal means
385        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( // this is safe, but non-accesible by normal means
397        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(); // this is unsafe and non-accesible by normal means
573
574    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(); // this is unsafe and non-accesible by normal means
594
595    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(); // this is unsafe and non-accesible by normal means
618
619    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, &param_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, &param_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    // String functions
866    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    // Max tuple size is 10 for now
1201    seq!(I in 0..10 {
1202        let idx = ctx.define_function(format!("$drop_{}_unsafe", I)).unwrap(); // this is unsafe and non-accesible by normal means
1203
1204        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}