interpreter/types/
fns.rs

1use crate::Package;
2use lealang_chalk_rs::Chalk;
3use std::{collections::HashMap, sync::Arc};
4
5use super::{set_into_extends, ExtendsInternal, HeapWrapper, Options};
6
7//pub trait DynPackageCallback = FnMut(&Args, &mut Heap, &mut bool);
8pub type Args = *const [&'static str];
9pub type PackageCallback = fn(Args, HeapWrapper, &str, &mut Options) -> ();
10
11pub type MethodRes = &'static [(&'static str, PackageCallback)];
12
13pub struct LanguagePackages<'a> {
14  pub inner: HashMap<&'static str, (&'a str, PackageCallback)>,
15  pub(crate) extends: Arc<ExtendsInternal>,
16}
17
18impl<'a> LanguagePackages<'a> {
19  pub fn new() -> Self {
20    Self {
21      inner: HashMap::new(),
22      extends: Arc::new(ExtendsInternal::default()),
23    }
24  }
25
26  pub fn import_dyn(&mut self, func: Box<dyn Package>) -> &mut Self {
27    let name = String::from_utf8_lossy(func.name());
28    let name: &'static mut str = name.to_string().leak::<'static>();
29    for (key, val) in func.methods() {
30      self.inner.insert(key, (name, *val));
31    }
32
33    // SAFETY: These functions cannot be called when the Arc is in use
34    let ext = unsafe { Arc::get_mut_unchecked(&mut self.extends) };
35
36    set_into_extends(func.prototype(), ext);
37
38    self
39  }
40
41  pub fn import_static(&mut self, func: &'static dyn Package) -> &mut Self {
42    let name = String::from_utf8_lossy(func.name());
43    let name: &'static mut str = name.to_string().leak::<'static>();
44    for (key, val) in func.methods() {
45      self.inner.insert(key, (name, *val));
46    }
47
48    // SAFETY: These functions cannot be called when the Arc is in use
49    let ext = unsafe { Arc::get_mut_unchecked(&mut self.extends) };
50
51    set_into_extends(func.prototype(), ext);
52
53    self
54  }
55
56  pub fn import<T: Package + 'static>(&mut self, func: T) -> &mut Self {
57    self.import_dyn(Box::new(func))
58  }
59
60  pub fn list(&self, chalk: &mut Chalk) {
61    println!(
62      "{} {}",
63      chalk.reset_weight().blue().string(&"Total Commands:"),
64      self.inner.len()
65    );
66    chalk.reset_weight().green().println(&"Commands:");
67
68    self
69      .inner
70      .iter()
71      .enumerate()
72      .for_each(|(no, (syntax, (name, _)))| {
73        chalk.red().print(&format!("{}- ", no + 1));
74        chalk.yellow().bold().print(&syntax);
75        print!(" from ");
76        chalk.reset_weight().blue().println(&name);
77      });
78  }
79}