interpreter/types/
mod.rs

1mod alloc;
2mod fns;
3mod heap;
4mod heap_wrap;
5use std::{
6  collections::HashMap,
7  fmt::Debug,
8  ops::{Deref, DerefMut},
9  sync::{Arc, Mutex},
10  thread::JoinHandle,
11};
12pub use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
13
14pub use alloc::*;
15pub use fns::*;
16pub use heap::*;
17pub use heap_wrap::*;
18
19use crate::runtime::RuntimeValue;
20
21pub struct RetBufValue(pub BufValue);
22
23impl From<BufValue> for RetBufValue {
24  fn from(item: BufValue) -> Self {
25    Self(item)
26  }
27}
28
29pub struct Options {
30  pub pre: *const str,
31  pub r_val: Option<RetBufValue>,
32  r_runtime: Option<Box<dyn RuntimeValue>>,
33}
34
35unsafe impl Send for Options {}
36unsafe impl Sync for Options {}
37
38impl Debug for Options {
39  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40    f.write_fmt(format_args!("Options {{ <inner> }}"))
41  }
42}
43
44impl Options {
45  pub fn new() -> Self {
46    Self {
47      pre: "" as _,
48      r_val: None,
49      r_runtime: None,
50    }
51  }
52
53  pub fn set_return_val(&mut self, val: BufValue) {
54    self.r_val = Some(RetBufValue(val));
55  }
56
57  pub(crate) fn r_val(self) -> BufValue {
58    let val = self.r_val;
59
60    val.expect("Error").0
61  }
62
63  pub(crate) fn rem_r_runtime(&mut self) -> Option<Box<dyn RuntimeValue>> {
64    self.r_runtime.take()
65  }
66
67  pub fn set_r_runtime(&mut self, val: Box<dyn RuntimeValue>) {
68    self.r_runtime = Some(val);
69  }
70}
71
72#[derive(PartialEq, Debug)]
73pub struct StrPointer(pub *const str);
74
75impl ToString for StrPointer {
76  fn to_string(&self) -> String {
77    unsafe { (*self.0).to_string() }
78  }
79}
80
81macro_rules! extends {
82    (
83      $(
84        $good:ident $x:ident => $y:ty
85      ),*
86    ) => {
87      #[derive(Default, Clone, Debug)]
88      pub(crate) struct ExtendsInternal {
89        $(
90          pub(crate) $x: HashMap<&'static str, fn(*mut $y, Args, HeapWrapper, &str, &mut Options) -> ()>
91        ),*
92      }
93
94      #[derive(Default)]
95      pub struct Extends {
96        $(
97          pub $x: &'static [(&'static str, fn(*mut $y, Args, HeapWrapper, &str, &mut Options) -> ())]
98        ),*
99      }
100
101      #[derive(Default)]
102      pub struct PrototypeDocs {
103        $(
104          pub $x: HashMap<&'static str, &'static [&'static str; 3]>
105        ),*
106      }
107
108      pub(crate) fn get_handle_runtime_ptr<'a>(
109        heap: &mut Heap,
110        val: &BufValue,
111        caller: &'a str,
112      ) -> Option<*const ()> {
113        let (ext, ar) = heap.get_extends();
114
115        crate::paste! {
116          match val {
117            $(
118              BufValue::[<$good>](_) => {
119                let scope1 = &ext.$x;
120                let scope2 = &ar.$x;
121
122                // Optimized approach
123                let f = match scope1.get(caller) {
124                  Some(v) => v,
125                  None => match scope2.get(caller) {
126                      Some(v) => v,
127                      None => { return None }
128                  },
129                };
130
131                return Some(f as *const _ as *const ());
132              }
133            )*
134            _ => return None
135          }
136        }
137      }
138
139      pub(crate) fn handle_runtime<'a>(
140        heap: &mut Heap,
141        val: &mut BufValue,
142        caller: &'a str,
143        v: &'a [&'static str],
144        a: HeapWrapper,
145        c: &str,
146        o: &'a mut Options,
147      ) -> Option<()> {
148        let (ext, ar) = heap.get_extends();
149
150        crate::paste! {
151          match val {
152            $(
153              BufValue::[<$good>](data) => {
154                let scope1 = &ext.$x;
155                let scope2 = &ar.$x;
156
157                // Optimized approach
158                let f = match scope1.get(caller) {
159                  Some(v) => v,
160                  None => match scope2.get(caller) {
161                      Some(v) => v,
162                      None => { return None }
163                  },
164                };
165
166                f(data as _, v, a, c, o);
167              }
168            )*
169            _ => return None
170          }
171        }
172
173        Some(())
174      }
175
176      pub(crate) fn set_into_extends(extends: Extends, extends_internal: &mut ExtendsInternal) {
177        $(
178          for (k, v) in extends.$x.into_iter() {
179            if let Some(_) = extends_internal.$x.insert(k, *v) {
180              panic!("{} already exists. Please ensure that you do not have two prototypes with the same name FOR THE WHOLE APPLICATION", k);
181            }
182          }
183        )*
184      }
185    };
186}
187
188extends! {
189  Int int => i64,
190  U_Int uint => u64,
191  Float float => f64,
192  Str str_slice => String,
193  Bool boolean => bool,
194  Array array => Vec<BufValue>,
195  Object object => HashMap<String, Box<BufValue>>,
196  Faillable faillable => Result<Box<BufValue>, String>,
197  StrPointer str_ptr => StrPointer,
198  Pointer ptr => *const BufValue,
199  PointerMut mut_ptr => *mut BufValue,
200  AsyncTask async_task => AppliesEq<JoinHandle<BufValue>>,
201  Sender sender => AppliesEq<UnboundedSender<BufValue>>,
202  Listener listener => AppliesEq<UnboundedReceiver<BufValue>>,
203  ArcPointer arc_ptr => Arc<Box<BufValue>>,
204  ArcMutexPointer arc_mut_ptr => AppliesEq<Arc<Mutex<Box<BufValue>>>>
205}
206
207#[allow(non_camel_case_types)]
208#[derive(PartialEq, Debug)]
209pub enum BufValue {
210  Int(i64),
211  U_Int(u64),
212  Float(f64),
213  Str(String),
214  Bool(bool),
215  Array(Vec<Self>),
216  Object(HashMap<String, Box<Self>>),
217  Faillable(Result<Box<Self>, String>),
218  StrPointer(StrPointer),
219  Pointer(*const Self),
220  PointerMut(*mut Self),
221  ArcPointer(Arc<Box<Self>>),
222  ArcMutexPointer(AppliesEq<Arc<Mutex<Box<Self>>>>),
223  AsyncTask(AppliesEq<JoinHandle<Self>>),
224  Sender(AppliesEq<UnboundedSender<Self>>),
225  Listener(AppliesEq<UnboundedReceiver<Self>>),
226  RuntimeRaw(AppliesEq<RawRTValue>),
227}
228
229unsafe impl Send for BufValue {}
230unsafe impl Sync for BufValue {}
231
232macro_rules! implement_buf {
233  ($($i:ident => $x:ty),*) => {
234    $(
235      impl From<$x> for BufValue {
236        fn from(item: $x) -> Self {
237          Self::$i(item)
238        }
239      }
240    )*
241  };
242}
243
244implement_buf! {
245  Str => String,
246  Int => i64,
247  U_Int => u64,
248  Float => f64,
249  Bool => bool,
250  StrPointer => StrPointer,
251  AsyncTask => AppliesEq<JoinHandle<Self>>
252}
253
254#[derive(Debug)]
255pub struct AppliesEq<T>(pub T);
256
257unsafe impl<T> Send for AppliesEq<T> {}
258unsafe impl<T> Sync for AppliesEq<T> {}
259
260impl<T> PartialEq for AppliesEq<T> {
261  fn eq(&self, _: &Self) -> bool {
262    false
263  }
264}
265
266impl<T> Deref for AppliesEq<T> {
267  type Target = T;
268
269  fn deref(&self) -> &Self::Target {
270    &self.0
271  }
272}
273
274impl<T> DerefMut for AppliesEq<T> {
275  fn deref_mut(&mut self) -> &mut Self::Target {
276    &mut self.0
277  }
278}
279
280impl BufValue {
281  pub fn type_of(&self) -> String {
282    match &self {
283      BufValue::Array(_) => "array".to_string(),
284      BufValue::Bool(_) => "bool".to_string(),
285      BufValue::Float(_) => "float".to_string(),
286      BufValue::Int(_) => "int".to_string(),
287      BufValue::U_Int(_) => "u_int".to_string(),
288      BufValue::Object(_) => "object".to_string(),
289      BufValue::StrPointer(_) | BufValue::Str(_) => "string".to_string(),
290      BufValue::Faillable(res) => match res {
291        Ok(t) => format!("<success {}>", t.type_of()),
292        Err(t) => format!("<err {}>", &t),
293      },
294      BufValue::Pointer(ptr) => {
295        if ptr.is_null() {
296          return "<ptr *ref NULL>".into();
297        }
298
299        unsafe { &**ptr }.type_of()
300      }
301      BufValue::PointerMut(ptr) => {
302        if ptr.is_null() {
303          return "<ptr *mut NULL>".into();
304        }
305
306        unsafe { &**ptr }.type_of()
307      }
308      BufValue::Sender(_) => "<sender ?event>".into(),
309      BufValue::Listener(_) => "<listener ?event>".into(),
310      BufValue::AsyncTask(t) => {
311        if t.is_finished() {
312          "<async recv...\\0>".into()
313        } else {
314          "<async pending...>".into()
315        }
316      }
317      BufValue::RuntimeRaw(_) => "<runtime rt>".into(),
318      BufValue::ArcPointer(a) => a.type_of(),
319      BufValue::ArcMutexPointer(_) => format!("<mutex *>"),
320    }
321  }
322
323  pub fn display(&self) -> String {
324    match &self {
325      BufValue::Array(c) => c.iter().map(|x| x.display()).collect::<Vec<_>>().join(", "),
326      BufValue::Bool(a) => a.to_string(),
327      BufValue::Float(f) => f.to_string(),
328      BufValue::Int(i) => i.to_string(),
329      BufValue::U_Int(u) => u.to_string(),
330      BufValue::Object(c) => format!("{c:#?}"),
331      BufValue::Str(c) => c.to_string(),
332      BufValue::StrPointer(c) => c.to_string(),
333      e => e.type_of(),
334    }
335  }
336
337  pub fn get_vec_mut(&mut self) -> Option<&mut Vec<BufValue>> {
338    match self {
339      BufValue::Array(a) => Some(a),
340      _ => None,
341    }
342  }
343
344  pub fn gt(&self, other: &BufValue) -> bool {
345    match (self, other) {
346      (BufValue::Int(a), BufValue::Int(b)) => a > b,
347      (BufValue::Int(a), BufValue::U_Int(b)) => (*a as i128) > (*b as i128),
348      (BufValue::U_Int(a), BufValue::U_Int(b)) => a > b,
349      (BufValue::U_Int(a), BufValue::Int(b)) => (*a as i128) > (*b as i128),
350      (BufValue::Float(a), BufValue::Float(b)) => a > b,
351      _ => false,
352    }
353  }
354
355  pub fn lt(&self, other: &BufValue) -> bool {
356    match (self, other) {
357      (BufValue::Int(a), BufValue::Int(b)) => a < b,
358      (BufValue::Int(a), BufValue::U_Int(b)) => (*a as i128) < (*b as i128),
359      (BufValue::U_Int(a), BufValue::U_Int(b)) => a < b,
360      (BufValue::U_Int(a), BufValue::Int(b)) => (*a as i128) < (*b as i128),
361      (BufValue::Float(a), BufValue::Float(b)) => a < b,
362      _ => false,
363    }
364  }
365
366  pub fn eq(&self, other: &BufValue) -> bool {
367    match (self, other) {
368      (BufValue::Int(a), BufValue::U_Int(b)) => (*a as i128) == (*b as i128),
369      (BufValue::U_Int(a), BufValue::Int(b)) => (*a as i128) == (*b as i128),
370      _ => self == other,
371    }
372  }
373}