dyon/
module.rs

1use super::*;
2
3/// Stores functions for a Dyon module.
4#[derive(Clone)]
5pub struct Module {
6    pub(crate) functions: Vec<ast::Function>,
7    pub(crate) ext_prelude: Vec<FnExternal>,
8    pub(crate) register_namespace: Arc<Vec<Arc<String>>>,
9}
10
11impl Default for Module {
12    fn default() -> Module {
13        Module::new()
14    }
15}
16
17impl Module {
18    /// Creates a new empty module.
19    pub fn empty() -> Module {
20        Module {
21            functions: vec![],
22            ext_prelude: vec![],
23            register_namespace: Arc::new(vec![]),
24        }
25    }
26
27    /// Import external prelude from other module.
28    pub fn import_ext_prelude(&mut self, other: &Module) {
29        for f in &other.ext_prelude {
30            self.ext_prelude.push(f.clone());
31        }
32    }
33
34    /// Import external prelude and loaded functions from module.
35    pub fn import(&mut self, other: &Module) {
36        // Add external functions from imports.
37        for f in &other.ext_prelude {
38            let has_external = self
39                .ext_prelude
40                .iter()
41                .any(|a| a.name == f.name && a.namespace == f.namespace);
42            if !has_external {
43                self.ext_prelude.push(f.clone());
44            }
45        }
46        // Register loaded functions from imports.
47        for f in &other.functions {
48            self.functions.push(f.clone())
49        }
50    }
51
52    /// Creates a new module with standard library.
53    pub fn new() -> Module {
54        use dyon_std::*;
55        use Type::*;
56
57        let mut m = Module::empty();
58        m.ns("std");
59        m.add_binop(
60            crate::LESS.clone(),
61            less,
62            Dfn {
63                lts: vec![Lt::Default; 2],
64                tys: vec![Any, Any],
65                ret: Bool,
66                ext: vec![
67                    (
68                        vec![],
69                        vec![Secret(Box::new(F64)), F64],
70                        Secret(Box::new(Bool)),
71                    ),
72                    (vec![], vec![F64; 2], Bool),
73                    (vec![], vec![Str; 2], Bool),
74                ],
75                lazy: LAZY_NO,
76            },
77        );
78        m.add_binop(
79            crate::LESS_OR_EQUAL.clone(),
80            less_or_equal,
81            Dfn {
82                lts: vec![Lt::Default; 2],
83                tys: vec![Any, Any],
84                ret: Bool,
85                ext: vec![
86                    (
87                        vec![],
88                        vec![Secret(Box::new(F64)), F64],
89                        Secret(Box::new(Bool)),
90                    ),
91                    (vec![], vec![F64; 2], Bool),
92                    (vec![], vec![Str; 2], Bool),
93                ],
94                lazy: LAZY_NO,
95            },
96        );
97        m.add_binop(
98            crate::GREATER.clone(),
99            greater,
100            Dfn {
101                lts: vec![Lt::Default; 2],
102                tys: vec![Any, Any],
103                ret: Bool,
104                ext: vec![
105                    (
106                        vec![],
107                        vec![Secret(Box::new(F64)), F64],
108                        Secret(Box::new(Bool)),
109                    ),
110                    (vec![], vec![F64; 2], Bool),
111                    (vec![], vec![Str; 2], Bool),
112                ],
113                lazy: LAZY_NO,
114            },
115        );
116        m.add_binop(
117            crate::GREATER_OR_EQUAL.clone(),
118            greater_or_equal,
119            Dfn {
120                lts: vec![Lt::Default; 2],
121                tys: vec![Any, Any],
122                ret: Bool,
123                ext: vec![
124                    (
125                        vec![],
126                        vec![Secret(Box::new(F64)), F64],
127                        Secret(Box::new(Bool)),
128                    ),
129                    (vec![], vec![F64; 2], Bool),
130                    (vec![], vec![Str; 2], Bool),
131                ],
132                lazy: LAZY_NO,
133            },
134        );
135        m.add_binop(
136            crate::EQUAL.clone(),
137            equal,
138            Dfn {
139                lts: vec![Lt::Default; 2],
140                tys: vec![Any, Any],
141                ret: Bool,
142                ext: vec![
143                    (
144                        vec![],
145                        vec![Secret(Box::new(F64)), F64],
146                        Secret(Box::new(Bool)),
147                    ),
148                    (vec![], vec![F64; 2], Bool),
149                    (vec![], vec![Str; 2], Bool),
150                    (
151                        vec![],
152                        vec![Secret(Box::new(Bool)), Bool],
153                        Secret(Box::new(Bool)),
154                    ),
155                    (vec![], vec![Bool; 2], Bool),
156                    (vec![], vec![Vec4; 2], Bool),
157                    (vec![], vec![Type::object(), Type::object()], Bool),
158                    (vec![], vec![Type::array(), Type::array()], Bool),
159                    (vec![], vec![Type::option(), Type::option()], Bool),
160                ],
161                lazy: LAZY_NO,
162            },
163        );
164        m.add_binop(
165            crate::NOT_EQUAL.clone(),
166            not_equal,
167            Dfn {
168                lts: vec![Lt::Default; 2],
169                tys: vec![Any, Any],
170                ret: Bool,
171                ext: vec![
172                    (
173                        vec![],
174                        vec![Secret(Box::new(F64)), F64],
175                        Secret(Box::new(Bool)),
176                    ),
177                    (vec![], vec![F64; 2], Bool),
178                    (vec![], vec![Str; 2], Bool),
179                    (
180                        vec![],
181                        vec![Secret(Box::new(Bool)), Bool],
182                        Secret(Box::new(Bool)),
183                    ),
184                    (vec![], vec![Bool; 2], Bool),
185                    (vec![], vec![Vec4; 2], Bool),
186                    (vec![], vec![Type::object(), Type::object()], Bool),
187                    (vec![], vec![Type::array(), Type::array()], Bool),
188                    (vec![], vec![Type::option(), Type::option()], Bool),
189                ],
190                lazy: LAZY_NO,
191            },
192        );
193        m.add(
194            crate::AND_ALSO.clone(),
195            and_also,
196            Dfn {
197                lts: vec![Lt::Default; 2],
198                tys: vec![Bool, Bool],
199                ret: Any,
200                ext: vec![
201                    (
202                        vec![],
203                        vec![Secret(Box::new(Bool)), Bool],
204                        Secret(Box::new(Bool)),
205                    ),
206                    (vec![], vec![Bool; 2], Bool),
207                ],
208                lazy: LAZY_AND,
209            },
210        );
211        m.add(
212            crate::OR_ELSE.clone(),
213            or_else,
214            Dfn {
215                lts: vec![Lt::Default; 2],
216                tys: vec![Bool, Bool],
217                ret: Any,
218                ext: vec![
219                    (
220                        vec![],
221                        vec![Secret(Box::new(Bool)), Bool],
222                        Secret(Box::new(Bool)),
223                    ),
224                    (vec![], vec![Bool; 2], Bool),
225                ],
226                lazy: LAZY_OR,
227            },
228        );
229        m.add_binop(
230            crate::ADD.clone(),
231            add,
232            Dfn {
233                lts: vec![Lt::Default; 2],
234                tys: vec![Any; 2],
235                ret: Any,
236                ext: vec![
237                    Type::all_ext(vec![F64, F64], F64),
238                    Type::all_ext(vec![Vec4, Vec4], Vec4),
239                    Type::all_ext(vec![Vec4, F64], Vec4),
240                    Type::all_ext(vec![F64, Vec4], Vec4),
241                    Type::all_ext(vec![Mat4, Mat4], Mat4),
242                    Type::all_ext(vec![F64, Mat4], Mat4),
243                    Type::all_ext(vec![Mat4, F64], Mat4),
244                    Type::all_ext(vec![Bool, Bool], Bool),
245                    Type::all_ext(vec![Str, Str], Str),
246                    Type::all_ext(vec![Link, Link], Link),
247                ],
248                lazy: LAZY_NO,
249            },
250        );
251        m.add_binop(
252            crate::SUB.clone(),
253            sub,
254            Dfn {
255                lts: vec![Lt::Default; 2],
256                tys: vec![Any; 2],
257                ret: Any,
258                ext: vec![
259                    Type::all_ext(vec![F64, F64], F64),
260                    Type::all_ext(vec![Vec4, Vec4], Vec4),
261                    Type::all_ext(vec![Vec4, F64], Vec4),
262                    Type::all_ext(vec![F64, Vec4], Vec4),
263                    Type::all_ext(vec![Mat4, Mat4], Mat4),
264                    Type::all_ext(vec![F64, Mat4], Mat4),
265                    Type::all_ext(vec![Mat4, F64], Mat4),
266                    Type::all_ext(vec![Bool, Bool], Bool),
267                ],
268                lazy: LAZY_NO,
269            },
270        );
271        m.add_binop(
272            crate::MUL.clone(),
273            mul,
274            Dfn {
275                lts: vec![Lt::Default; 2],
276                tys: vec![Any; 2],
277                ret: Any,
278                ext: vec![
279                    (vec![], vec![F64, F64], F64),
280                    (vec![], vec![Vec4, Vec4], Vec4),
281                    (vec![], vec![Vec4, F64], Vec4),
282                    (vec![], vec![F64, Vec4], Vec4),
283                    (vec![], vec![Mat4, Mat4], Mat4),
284                    (vec![], vec![F64, Mat4], Mat4),
285                    (vec![], vec![Mat4, F64], Mat4),
286                    (vec![], vec![Mat4, Vec4], Vec4),
287                    Type::all_ext(vec![Bool, Bool], Bool),
288                ],
289                lazy: LAZY_NO,
290            },
291        );
292        m.add_binop(
293            crate::DIV.clone(),
294            div,
295            Dfn {
296                lts: vec![Lt::Default; 2],
297                tys: vec![Any; 2],
298                ret: Any,
299                ext: vec![
300                    (vec![], vec![F64, F64], F64),
301                    (vec![], vec![Vec4, Vec4], Vec4),
302                    (vec![], vec![Vec4, F64], Vec4),
303                    (vec![], vec![F64, Vec4], Vec4),
304                ],
305                lazy: LAZY_NO,
306            },
307        );
308        m.add_binop(
309            crate::REM.clone(),
310            rem,
311            Dfn {
312                lts: vec![Lt::Default; 2],
313                tys: vec![Any; 2],
314                ret: Any,
315                ext: vec![
316                    (vec![], vec![F64, F64], F64),
317                    (vec![], vec![Vec4, Vec4], Vec4),
318                    (vec![], vec![Vec4, F64], Vec4),
319                    (vec![], vec![F64, Vec4], Vec4),
320                ],
321                lazy: LAZY_NO,
322            },
323        );
324        m.add_binop(
325            crate::POW.clone(),
326            pow,
327            Dfn {
328                lts: vec![Lt::Default; 2],
329                tys: vec![Any; 2],
330                ret: Any,
331                ext: vec![
332                    (vec![], vec![F64, F64], F64),
333                    (vec![], vec![Vec4, Vec4], Vec4),
334                    (vec![], vec![Vec4, F64], Vec4),
335                    (vec![], vec![F64, Vec4], Vec4),
336                    Type::all_ext(vec![Bool, Bool], Bool),
337                ],
338                lazy: LAZY_NO,
339            },
340        );
341        m.add_unop(
342            crate::NOT.clone(),
343            not,
344            Dfn {
345                lts: vec![Lt::Default],
346                tys: vec![Any],
347                ret: Any,
348                ext: vec![
349                    (
350                        vec![],
351                        vec![Type::Secret(Box::new(Bool))],
352                        Type::Secret(Box::new(Bool)),
353                    ),
354                    (vec![], vec![Bool], Bool),
355                ],
356                lazy: LAZY_NO,
357            },
358        );
359        m.add_unop(
360            crate::NEG.clone(),
361            neg,
362            Dfn {
363                lts: vec![Lt::Default],
364                tys: vec![Any],
365                ret: Any,
366                ext: vec![
367                    (vec![], vec![F64], F64),
368                    (vec![], vec![Vec4], Vec4),
369                    (vec![], vec![Mat4], Mat4),
370                ],
371                lazy: LAZY_NO,
372            },
373        );
374        m.add_binop(
375            crate::DOT.clone(),
376            dot,
377            Dfn {
378                lts: vec![Lt::Default; 2],
379                tys: vec![Any; 2],
380                ret: F64,
381                ext: vec![
382                    (vec![], vec![Vec4, Vec4], F64),
383                    (vec![], vec![Vec4, F64], F64),
384                    (vec![], vec![F64, Vec4], F64),
385                ],
386                lazy: LAZY_NO,
387            },
388        );
389        m.add_str("cross", cross, Dfn::nl(vec![Vec4, Vec4], Vec4));
390        m.add_str("x", x, Dfn::nl(vec![Vec4], F64));
391        m.add_str("y", y, Dfn::nl(vec![Vec4], F64));
392        m.add_str("z", z, Dfn::nl(vec![Vec4], F64));
393        m.add_str("w", w, Dfn::nl(vec![Vec4], F64));
394        m.add_unop_str("norm", norm, Dfn::nl(vec![Vec4], F64));
395        m.add_str("det", det, Dfn::nl(vec![Mat4], F64));
396        m.add_str("inv", inv, Dfn::nl(vec![Mat4], Mat4));
397        m.add_str("mov", mov, Dfn::nl(vec![Vec4], Mat4));
398        m.add_str(
399            "rot__axis_angle",
400            rot__axis_angle,
401            Dfn::nl(vec![Vec4, F64], Mat4),
402        );
403        m.add_str(
404            "ortho__pos_right_up_forward",
405            ortho__pos_right_up_forward,
406            Dfn::nl(vec![Vec4; 4], Mat4),
407        );
408        m.add_str(
409            "proj__fov_near_far_ar",
410            proj__fov_near_far_ar,
411            Dfn::nl(vec![F64; 4], Mat4),
412        );
413        m.add_str(
414            "mvp__model_view_projection",
415            mvp__model_view_projection,
416            Dfn::nl(vec![Mat4; 3], Mat4),
417        );
418        m.add_str("scale", scale, Dfn::nl(vec![Vec4], Mat4));
419        m.add_str("rx", rx, Dfn::nl(vec![Mat4], Vec4));
420        m.add_str("ry", ry, Dfn::nl(vec![Mat4], Vec4));
421        m.add_str("rz", rz, Dfn::nl(vec![Mat4], Vec4));
422        m.add_str("rw", rw, Dfn::nl(vec![Mat4], Vec4));
423        m.add_str("cx", cx, Dfn::nl(vec![Mat4], Vec4));
424        m.add_str("cy", cy, Dfn::nl(vec![Mat4], Vec4));
425        m.add_str("cz", cz, Dfn::nl(vec![Mat4], Vec4));
426        m.add_str("cw", cw, Dfn::nl(vec![Mat4], Vec4));
427        m.add_str("cv", cv, Dfn::nl(vec![Mat4, F64], Vec4));
428        m.add_str("clone", clone, Dfn::nl(vec![Any], Any));
429        m.add_str("rv", rv, Dfn::nl(vec![Mat4, Type::F64], Vec4));
430        m.add_str("s", s, Dfn::nl(vec![Vec4, F64], F64));
431        #[cfg(feature = "stdio")]
432        m.add_str("println", println, Dfn::nl(vec![Any], Void));
433        #[cfg(feature = "stdio")]
434        m.add_str("print", print, Dfn::nl(vec![Any], Void));
435        #[cfg(feature = "stdio")]
436        m.add_str("eprintln", eprintln, Dfn::nl(vec![Any], Void));
437        #[cfg(feature = "stdio")]
438        m.add_str("eprint", eprint, Dfn::nl(vec![Any], Void));
439        m.add_str("sqrt", sqrt, Dfn::nl(vec![F64], F64));
440        m.add_str("sin", sin, Dfn::nl(vec![F64], F64));
441        m.add_str("asin", asin, Dfn::nl(vec![F64], F64));
442        m.add_str("cos", cos, Dfn::nl(vec![F64], F64));
443        m.add_str("acos", acos, Dfn::nl(vec![F64], F64));
444        m.add_str("tan", tan, Dfn::nl(vec![F64], F64));
445        m.add_str("atan", atan, Dfn::nl(vec![F64], F64));
446        m.add_str("atan2", atan2, Dfn::nl(vec![F64; 2], F64));
447        m.add_str("exp", exp, Dfn::nl(vec![F64], F64));
448        m.add_str("ln", ln, Dfn::nl(vec![F64], F64));
449        m.add_str("log2", log2, Dfn::nl(vec![F64], F64));
450        m.add_str("log10", log10, Dfn::nl(vec![F64], F64));
451        m.add_str("round", round, Dfn::nl(vec![F64], F64));
452        m.add_str("abs", abs, Dfn::nl(vec![F64], F64));
453        m.add_str("floor", floor, Dfn::nl(vec![F64], F64));
454        m.add_str("ceil", ceil, Dfn::nl(vec![F64], F64));
455        #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
456        m.add_str("sleep", sleep, Dfn::nl(vec![F64], Void));
457        #[cfg(feature = "rand")]
458        m.add_str("random", random, Dfn::nl(vec![], F64));
459        m.add_str("tau", tau, Dfn::nl(vec![], F64));
460        #[cfg(feature = "stdio")]
461        m.add_str("read_line", read_line, Dfn::nl(vec![], Str));
462        #[cfg(feature = "stdio")]
463        m.add_str("read_number", read_number, Dfn::nl(vec![Str], F64));
464        m.add_str(
465            "parse_number",
466            parse_number,
467            Dfn::nl(vec![Str], Option(Box::new(Type::F64))),
468        );
469        m.add_str("trim", trim, Dfn::nl(vec![Str], Str));
470        m.add_str("trim_left", trim_left, Dfn::nl(vec![Str], Str));
471        m.add_str("trim_right", trim_right, Dfn::nl(vec![Str], Str));
472        m.add_str("str", _str, Dfn::nl(vec![Any], Str));
473        m.add_str("fmt__tab_string", fmt__tab_string, Dfn::nl(vec![F64, Str], Str));
474        m.add_str("json_string", json_string, Dfn::nl(vec![Str], Str));
475        m.add_str("str__color", str__color, Dfn::nl(vec![Vec4], Str));
476        m.add_str(
477            "srgb_to_linear__color",
478            srgb_to_linear__color,
479            Dfn::nl(vec![Vec4], Vec4),
480        );
481        m.add_str(
482            "linear_to_srgb__color",
483            linear_to_srgb__color,
484            Dfn::nl(vec![Vec4], Vec4),
485        );
486        m.add_str("typeof", _typeof, Dfn::nl(vec![Any], Str));
487        m.add_str("debug", debug, Dfn::nl(vec![], Void));
488        m.add_str("backtrace", backtrace, Dfn::nl(vec![], Void));
489        m.add_str("none", none, Dfn::nl(vec![], Type::option()));
490        m.add_str("some", some, Dfn::nl(vec![Any], Type::option()));
491        m.add_str("ok", ok, Dfn::nl(vec![Any], Type::result()));
492        m.add_str("err", err, Dfn::nl(vec![Any], Type::result()));
493        m.add_str("dir__angle", dir__angle, Dfn::nl(vec![F64], Vec4));
494        m.add_str(
495            "load__meta_file",
496            load__meta_file,
497            Dfn::nl(
498                vec![Str; 2],
499                Type::Result(Box::new(Type::Array(Box::new(Type::array())))),
500            ),
501        );
502        m.add_str(
503            "load__meta_url",
504            load__meta_url,
505            Dfn::nl(
506                vec![Str; 2],
507                Type::Result(Box::new(Type::Array(Box::new(Type::array())))),
508            ),
509        );
510        m.add_str(
511            "syntax__in_string",
512            syntax__in_string,
513            Dfn::nl(vec![Type::Str; 2], Type::Result(Box::new(Any))),
514        );
515        m.add_str(
516            "download__url_file",
517            download__url_file,
518            Dfn::nl(vec![Type::Str; 2], Type::Result(Box::new(Str))),
519        );
520        m.add_str(
521            "save__string_file",
522            save__string_file,
523            Dfn::nl(vec![Type::Str; 2], Type::Result(Box::new(Str))),
524        );
525        m.add_str(
526            "load_string__file",
527            load_string__file,
528            Dfn::nl(vec![Str], Type::Result(Box::new(Str))),
529        );
530        m.add_str(
531            "load_string__url",
532            load_string__url,
533            Dfn::nl(vec![Str], Type::Result(Box::new(Str))),
534        );
535        #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
536        m.add_str(
537            "join__thread",
538            join__thread,
539            Dfn::nl(vec![Type::thread()], Type::Result(Box::new(Any))),
540        );
541        m.add_str(
542            "load_data__file",
543            load_data__file,
544            Dfn::nl(vec![Str], Type::Result(Box::new(Any))),
545        );
546        m.add_str(
547            "load_data__string",
548            load_data__string,
549            Dfn::nl(vec![Str], Type::Result(Box::new(Any))),
550        );
551        m.add_str(
552            "args_os",
553            args_os,
554            Dfn::nl(vec![], Type::Array(Box::new(Str))),
555        );
556        m.add_str("now", now, Dfn::nl(vec![], F64));
557        m.add_str("is_nan", is_nan, Dfn::nl(vec![F64], Bool));
558        #[cfg(feature = "dynload")]
559        m.add_str("load", load, Dfn::nl(vec![Str], Type::result()));
560        #[cfg(feature = "dynload")]
561        m.add_str(
562            "load__source_imports",
563            load__source_imports,
564            Dfn::nl(vec![Str, Type::array()], Type::result()),
565        );
566        m.add_str(
567            "module__in_string_imports",
568            module__in_string_imports,
569            Dfn::nl(vec![Str, Str, Type::array()], Type::result()),
570        );
571        m.add_str(
572            "check__in_string_imports",
573            check__in_string_imports,
574            Dfn::nl(
575                vec![Str, Str, Type::array()],
576                Type::Result(Box::new(Type::Array(Box::new(Type::Object)))),
577            ),
578        );
579        m.add_str("call", _call, Dfn::nl(vec![Any, Str, Type::array()], Void));
580        m.add_str(
581            "call_ret",
582            call_ret,
583            Dfn::nl(vec![Any, Str, Type::array()], Any),
584        );
585        m.add_str("functions", functions, Dfn::nl(vec![], Any));
586        m.add_str(
587            "functions__module",
588            functions__module,
589            Dfn::nl(vec![Any], Any),
590        );
591        m.add_str("is_err", is_err, Dfn::nl(vec![Type::result()], Bool));
592        m.add_str("is_ok", is_ok, Dfn::nl(vec![Type::result()], Bool));
593        m.add_str("min", min, Dfn::nl(vec![Type::Array(Box::new(F64))], F64));
594        m.add_str("max", max, Dfn::nl(vec![Type::Array(Box::new(F64))], F64));
595        m.add_str("unwrap", unwrap, Dfn::nl(vec![Any], Any));
596        m.add_str(
597            "why",
598            why,
599            Dfn::nl(vec![Type::Secret(Box::new(Bool))], Type::array()),
600        );
601        m.add_str(
602            "where",
603            _where,
604            Dfn::nl(vec![Type::Secret(Box::new(F64))], Type::array()),
605        );
606        m.add_str(
607            "explain_why",
608            explain_why,
609            Dfn::nl(vec![Bool, Any], Type::Secret(Box::new(Bool))),
610        );
611        m.add_str(
612            "explain_where",
613            explain_where,
614            Dfn::nl(vec![F64, Any], Type::Secret(Box::new(F64))),
615        );
616        m.add_str("head", head, Dfn::nl(vec![Link], Any));
617        m.add_str("tip", tip, Dfn::nl(vec![Link], Type::Option(Box::new(Any))));
618        m.add_str("tail", tail, Dfn::nl(vec![Link], Link));
619        m.add_str("neck", neck, Dfn::nl(vec![Link], Link));
620        m.add_str("is_empty", is_empty, Dfn::nl(vec![Link], Bool));
621        m.add_unop_str("len", len, Dfn::nl(vec![Type::array()], F64));
622        m.add_str(
623            "push_ref(mut,_)",
624            push_ref,
625            Dfn {
626                lts: vec![Lt::Default, Lt::Arg(0)],
627                tys: vec![Type::array(), Any],
628                ret: Void,
629                ext: vec![],
630                lazy: LAZY_NO,
631            },
632        );
633        m.add_str(
634            "insert_ref(mut,_,_)",
635            insert_ref,
636            Dfn {
637                lts: vec![Lt::Default, Lt::Default, Lt::Arg(0)],
638                tys: vec![Type::array(), F64, Any],
639                ret: Void,
640                ext: vec![],
641                lazy: LAZY_NO,
642            },
643        );
644        m.add_str("push(mut,_)", push, Dfn::nl(vec![Type::array(), Any], Void));
645        m.add_str(
646            "insert(mut,_,_)",
647            insert,
648            Dfn {
649                lts: vec![Lt::Default; 3],
650                tys: vec![Type::array(), F64, Any],
651                ret: Void,
652                ext: vec![],
653                lazy: LAZY_NO,
654            },
655        );
656        m.add_str(
657            "pop(mut)",
658            pop,
659            Dfn {
660                lts: vec![Lt::Return],
661                tys: vec![Type::array()],
662                ret: Any,
663                ext: vec![],
664                lazy: LAZY_NO,
665            },
666        );
667        m.add_str(
668            "remove(mut,_)",
669            remove,
670            Dfn {
671                lts: vec![Lt::Return, Lt::Default],
672                tys: vec![Type::array(), F64],
673                ret: Any,
674                ext: vec![],
675                lazy: LAZY_NO,
676            },
677        );
678        m.add_str("reverse(mut)", reverse, Dfn::nl(vec![Type::array()], Void));
679        m.add_str("clear(mut)", clear, Dfn::nl(vec![Type::array()], Void));
680        m.add_str(
681            "swap(mut,_,_)",
682            swap,
683            Dfn::nl(vec![Type::array(), F64, F64], Void),
684        );
685        m.add_str(
686            "unwrap_or",
687            unwrap_or,
688            Dfn {
689                lts: vec![Lt::Default; 2],
690                tys: vec![Any; 2],
691                ret: Any,
692                ext: vec![],
693                lazy: LAZY_UNWRAP_OR,
694            },
695        );
696        m.add_str("unwrap_err", unwrap_err, Dfn::nl(vec![Any], Any));
697        m.add_str(
698            "meta__syntax_in_string",
699            meta__syntax_in_string,
700            Dfn::nl(
701                vec![Any, Str, Str],
702                Type::Result(Box::new(Type::Array(Box::new(Type::array())))),
703            ),
704        );
705        m.add_str(
706            "save__data_file",
707            save__data_file,
708            Dfn::nl(vec![Any, Str], Type::Result(Box::new(Str))),
709        );
710        m.add_str(
711            "json_from_meta_data",
712            json_from_meta_data,
713            Dfn::nl(vec![Type::Array(Box::new(Type::array()))], Str),
714        );
715        m.add_str(
716            "errstr__string_start_len_msg",
717            errstr__string_start_len_msg,
718            Dfn::nl(vec![Str, F64, F64, Str], Str),
719        );
720        m.add_str("has", has, Dfn::nl(vec![Object, Str], Bool));
721        m.add_str(
722            "keys",
723            keys,
724            Dfn::nl(vec![Object], Type::Array(Box::new(Str))),
725        );
726        m.add_str(
727            "chars",
728            chars,
729            Dfn::nl(vec![Str], Type::Array(Box::new(Str))),
730        );
731        #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
732        m.add_str("wait_next", wait_next, Dfn::nl(vec![Type::in_ty()], Any));
733        #[cfg(all(not(target_family = "wasm"), feature = "threading"))]
734        m.add_str("next", next, Dfn::nl(vec![Type::in_ty()], Type::option()));
735
736        m.no_ns();
737        m
738    }
739
740    /// Sets namespace for following added functions.
741    pub fn ns(&mut self, ns: &str) {
742        self.register_namespace = Arc::new(ns.split("::").map(|s| Arc::new(s.into())).collect());
743    }
744
745    /// Sets no namespace.
746    pub fn no_ns(&mut self) {
747        self.register_namespace = Arc::new(vec![]);
748    }
749
750    pub(crate) fn register(&mut self, function: ast::Function) {
751        self.functions.push(function);
752    }
753
754    /// Find function relative another function index.
755    pub fn find_function(&self, name: &Arc<String>, relative: usize) -> FnIndex {
756        for (i, f) in self.functions.iter().enumerate().rev() {
757            if &f.name == name {
758                return FnIndex::Loaded(i as isize - relative as isize);
759            }
760        }
761        for f in self.ext_prelude.iter().rev() {
762            if &f.name == name {
763                return match f.f {
764                    FnExt::Return(ff) => {
765                        if f.p.lazy == LAZY_NO {
766                            FnIndex::Return(FnReturnRef(ff))
767                        } else {
768                            FnIndex::Lazy(FnReturnRef(ff), f.p.lazy)
769                        }
770                    }
771                    FnExt::BinOp(ff) => FnIndex::BinOp(FnBinOpRef(ff)),
772                    FnExt::UnOp(ff) => FnIndex::UnOp(FnUnOpRef(ff)),
773                    FnExt::Void(ff) => FnIndex::Void(FnVoidRef(ff)),
774                };
775            }
776        }
777        FnIndex::None
778    }
779
780    /// Generates an error message.
781    ///
782    /// Uses the call stack to look up the source of the function.
783    pub(crate) fn error(&self, range: Range, msg: &str, rt: &Runtime) -> String {
784        let fnindex = if let Some(x) = rt.call_stack.last() {
785            x.index
786        } else {
787            return msg.into();
788        };
789        self.error_fnindex(range, msg, fnindex)
790    }
791
792    /// Generates an error with a function index.
793    pub(crate) fn error_fnindex(&self, range: Range, msg: &str, fnindex: usize) -> String {
794        let source = match self.functions.get(fnindex) {
795            Some(x) => &x.source,
796            None => return format!("{}\nfnindex `{}` outside bounds of `0..{}`",
797                    msg, fnindex, self.functions.len()),
798        };
799        self.error_source(range, msg, source)
800    }
801
802    /// Generates an error message with a source.
803    pub(crate) fn error_source(&self, range: Range, msg: &str, source: &Arc<String>) -> String {
804        use piston_meta::ParseErrorHandler;
805
806        let mut w: Vec<u8> = vec![];
807        ParseErrorHandler::new(source)
808            .write_msg(&mut w, range, msg)
809            .unwrap();
810        String::from_utf8(w).unwrap()
811    }
812
813    /// Adds a new external prelude function.
814    pub fn add<T>(&mut self, name: Arc<String>, f: fn(&mut Runtime) -> T, prelude_function: Dfn)
815    where
816        fn(&mut Runtime) -> T: Into<FnExt>,
817    {
818        self.ext_prelude.push(FnExternal {
819            namespace: self.register_namespace.clone(),
820            name,
821            f: f.into(),
822            p: prelude_function,
823        });
824    }
825
826    /// Adds a new external prelude function.
827    pub fn add_str<T>(&mut self, name: &str, f: fn(&mut Runtime) -> T, prelude_function: Dfn)
828    where
829        fn(&mut Runtime) -> T: Into<FnExt>,
830    {
831        self.ext_prelude.push(FnExternal {
832            namespace: self.register_namespace.clone(),
833            name: Arc::new(name.into()),
834            f: f.into(),
835            p: prelude_function,
836        });
837    }
838
839    /// Adds a new external prelude binary operator.
840    pub fn add_binop(
841        &mut self,
842        name: Arc<String>,
843        f: fn(&Variable, &Variable) -> Result<Variable, String>,
844        prelude_function: Dfn,
845    ) {
846        self.ext_prelude.push(FnExternal {
847            namespace: self.register_namespace.clone(),
848            name,
849            f: f.into(),
850            p: prelude_function,
851        });
852    }
853
854    /// Adds a new external prelude unary operator.
855    pub fn add_unop(
856        &mut self,
857        name: Arc<String>,
858        f: fn(&Variable) -> Result<Variable, String>,
859        prelude_function: Dfn,
860    ) {
861        self.ext_prelude.push(FnExternal {
862            namespace: self.register_namespace.clone(),
863            name,
864            f: f.into(),
865            p: prelude_function,
866        });
867    }
868
869    /// Adds a new external prelude unary operator.
870    pub fn add_unop_str(
871        &mut self,
872        name: &str,
873        f: fn(&Variable) -> Result<Variable, String>,
874        prelude_function: Dfn,
875    ) {
876        self.add_unop(Arc::new(name.into()), f, prelude_function)
877    }
878}