adana_script_core/primitive/
core_primitive.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3
4#[cfg(not(target_arch = "wasm32"))]
5use std::any::Any;
6
7use std::{
8    cmp::Ordering,
9    collections::BTreeMap,
10    fmt::Display,
11    path::{Path, PathBuf},
12    sync::{Arc, RwLock},
13};
14
15use crate::{Value, constants::NULL};
16
17const MAX_U32_AS_I128: i128 = u32::MAX as i128;
18
19pub const TYPE_U8: &str = "u8";
20pub const TYPE_I8: &str = "i8";
21pub const TYPE_INT: &str = "int";
22pub const TYPE_BOOL: &str = "bool";
23pub const TYPE_NULL: &str = "null";
24pub const TYPE_DOUBLE: &str = "double";
25pub const TYPE_STRING: &str = "string";
26pub const TYPE_ARRAY: &str = "array";
27pub const TYPE_ERROR: &str = "error";
28pub const TYPE_NATIVE_LIB: &str = "nativeLibrary";
29pub const TYPE_FUNCTION: &str = "function";
30pub const TYPE_UNIT: &str = "unit";
31pub const TYPE_STRUCT: &str = "struct";
32pub const TYPE_NO_RETURN: &str = "!";
33pub const TYPE_LIB_DATA: &str = "libdata";
34
35#[derive(Debug)]
36pub struct NativeLibrary {
37    #[cfg(target_arch = "wasm32")]
38    _lib: (),
39    #[cfg(not(target_arch = "wasm32"))]
40    lib: libloading::Library,
41    path: PathBuf,
42}
43
44pub type NativeFunctionCallResult = anyhow::Result<Primitive>;
45pub type Compiler = dyn FnMut(Value, BTreeMap<String, RefPrimitive>) -> NativeFunctionCallResult
46    + Send;
47
48#[cfg(not(target_arch = "wasm32"))]
49#[allow(improper_ctypes_definitions)]
50pub type NativeFunction<'lib> = libloading::Symbol<
51    'lib,
52    fn(Vec<Primitive>, Box<Compiler>) -> NativeFunctionCallResult,
53>;
54
55#[cfg(target_arch = "wasm32")]
56pub type NativeFunction = ();
57
58impl NativeLibrary {
59    /// # Safety
60    /// trust me bro
61    #[cfg(not(target_arch = "wasm32"))]
62    pub unsafe fn new(path: &Path) -> anyhow::Result<NativeLibrary> {
63        unsafe {
64            let lib = libloading::Library::new(path)
65                .map_err(|e| anyhow::format_err!("could not load lib, {e}"))?;
66            Ok(NativeLibrary { lib, path: path.to_path_buf() })
67        }
68    }
69
70    #[cfg(target_arch = "wasm32")]
71    pub fn new(_path: &Path) -> anyhow::Result<NativeLibrary> {
72        Err(anyhow::format_err!("cannot use lib loading in wasm context!"))
73    }
74
75    pub fn get_path(&self) -> &Path {
76        self.path.as_path()
77    }
78
79    /// # Safety
80    /// trust me bro
81    #[cfg(not(target_arch = "wasm32"))]
82    pub unsafe fn get_function(
83        &self,
84        key: &str,
85    ) -> anyhow::Result<NativeFunction> {
86        unsafe {
87            let r = self.lib.get(key.as_bytes())?;
88            Ok(r)
89        }
90    }
91
92    #[cfg(target_arch = "wasm32")]
93    pub fn get_function(&self, _key: &str) -> anyhow::Result<NativeFunction> {
94        Err(anyhow::format_err!("cannot use lib loading in wasm context!"))
95    }
96
97    /// # Safety
98    /// trust me bro
99    #[cfg(not(target_arch = "wasm32"))]
100    pub unsafe fn call_function(
101        &self,
102        key: &str,
103        params: Vec<Primitive>,
104        compiler: Box<Compiler>,
105    ) -> anyhow::Result<Primitive> {
106        unsafe {
107            let fun = self.get_function(key)?;
108            fun(params, compiler)
109        }
110    }
111
112    #[cfg(target_arch = "wasm32")]
113    pub fn call_function(
114        &self,
115        _key: &str,
116        _params: Vec<Primitive>,
117        _compiler: Box<Compiler>,
118    ) -> anyhow::Result<Primitive> {
119        Err(anyhow::format_err!("cannot use lib loading in wasm context!"))
120    }
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[repr(C)]
125pub enum Primitive {
126    U8(u8),
127    I8(i8),
128    Int(i128),
129    Bool(bool),
130    Ref(RefPrimitive),
131    Null,
132    Double(f64),
133    String(String),
134    Array(Vec<Primitive>),
135    Struct(BTreeMap<String, Primitive>),
136    Error(String),
137    Function {
138        parameters: Vec<Value>,
139        exprs: Vec<Value>,
140    },
141    Unit,
142    NoReturn,
143    EarlyReturn(Box<Primitive>),
144    #[serde(skip_serializing, skip_deserializing)]
145    NativeLibrary(Arc<NativeLibrary>),
146    #[serde(skip_serializing, skip_deserializing)]
147    NativeFunction(String, Arc<NativeLibrary>),
148    #[serde(skip_serializing, skip_deserializing)]
149    LibData(LibData),
150}
151#[derive(Debug, Clone)]
152pub struct LibData {
153    #[cfg(not(target_arch = "wasm32"))]
154    pub data: Arc<Box<dyn Send + Any + Sync>>,
155}
156
157pub type RefPrimitive = Arc<RwLock<Primitive>>;
158
159// region: traits
160impl Primitive {
161    pub fn ref_prim(self) -> RefPrimitive {
162        Arc::new(RwLock::new(self))
163    }
164    pub fn to_value(self) -> anyhow::Result<Value> {
165        // code was more complex than that before libhttp. I forgot why,
166        // and probably this simplification shouldn't cause any problem
167        Ok(Value::Primitive(self))
168    }
169}
170pub trait StringManipulation {
171    fn match_regex(&self, regex: &Primitive) -> Self;
172    fn is_match(&self, regex: &Primitive) -> Self;
173    fn replace(&self, regex: &Primitive, new_value: &Primitive) -> Self;
174    fn replace_all(&self, regex: &Primitive, new_value: &Primitive) -> Self;
175    fn to_upper(&self) -> Self;
176    fn to_lower(&self) -> Self;
177    fn capitalize(&self) -> Self;
178}
179
180pub trait TypeOf {
181    fn type_of(&self) -> Self;
182    fn type_of_str(&self) -> &'static str;
183}
184pub trait BitShift {
185    fn left_shift(&self, n: &Self) -> Self;
186    fn right_shift(&self, n: &Self) -> Self;
187}
188pub trait ToBool {
189    fn to_bool(&self) -> Self;
190}
191pub trait ToNumber {
192    fn to_int(&self) -> Self;
193    fn to_double(&self) -> Self;
194}
195pub trait Pow {
196    fn pow(&self, n: &Self) -> Self;
197}
198
199pub trait And {
200    fn and(&self, n: &Self) -> Self;
201    fn bitwise_and(&self, n: &Self) -> Self;
202}
203pub trait Or {
204    fn or(&self, n: &Self) -> Self;
205    fn bitwise_or(&self, n: &Self) -> Self;
206    fn bitwise_xor(&self, n: &Self) -> Self;
207}
208pub trait Sqrt {
209    fn sqrt(&self) -> Self;
210}
211pub trait Abs {
212    fn abs(&self) -> Self;
213}
214pub trait Logarithm {
215    fn log(&self) -> Self;
216    fn ln(&self) -> Self;
217}
218
219pub trait DisplayHex {
220    fn to_hex(&self) -> Self;
221}
222
223pub trait DisplayBinary {
224    fn to_binary(&self) -> Self;
225}
226
227pub trait Sin {
228    fn sin(&self) -> Self;
229}
230pub trait Array {
231    fn index_at(&self, rhs: &Self) -> Self;
232    fn len(&self) -> Primitive;
233    fn is_empty(&self) -> Primitive;
234    fn swap_mem(&mut self, rhs: &mut Self, index: &Primitive) -> Self;
235    fn remove(&mut self, key: &Self) -> anyhow::Result<()>;
236}
237
238pub trait Cos {
239    fn cos(&self) -> Self;
240}
241pub trait Tan {
242    fn tan(&self) -> Self;
243}
244
245pub trait Add {
246    fn add(&self, rhs: &Self) -> Self;
247}
248
249pub trait Neg {
250    fn neg(&self) -> Self;
251}
252
253pub trait Not {
254    fn bitwise_not(&self) -> Self;
255    fn not(&self) -> Self;
256}
257
258pub trait Sub {
259    fn sub(&self, rhs: &Self) -> Self;
260}
261
262pub trait Mul {
263    fn mul(&self, rhs: &Self) -> Self;
264}
265
266pub trait Div {
267    fn div(&self, rhs: &Self) -> Self;
268}
269
270pub trait Rem {
271    fn rem(&self, rhs: &Self) -> Self;
272}
273pub trait Round {
274    fn floor(&self) -> Self;
275    fn round(&self, decimals: &Self) -> Self;
276    fn ceil(&self) -> Self;
277}
278// endregion traits
279
280// region: impl primitive
281#[allow(dead_code)]
282impl Primitive {
283    pub fn is_greater_than(&self, other: &Primitive) -> Primitive {
284        match self.partial_cmp(other) {
285            Some(Ordering::Greater) => Primitive::Bool(true),
286            Some(Ordering::Less) => Primitive::Bool(false),
287            Some(Ordering::Equal) => Primitive::Bool(false),
288            None => Primitive::Error(format!(
289                "call to is_greater_than() for two different types {self} => {other}"
290            )),
291        }
292    }
293    pub fn is_greater_or_equal(&self, other: &Primitive) -> Primitive {
294        match self.partial_cmp(other) {
295            Some(Ordering::Greater) | Some(Ordering::Equal) => {
296                Primitive::Bool(true)
297            }
298            Some(Ordering::Less) => Primitive::Bool(false),
299            None => Primitive::Error(format!(
300                "call to is_greater_or_equal() for two different types {self} => {other}"
301            )),
302        }
303    }
304    pub fn is_less_than(&self, other: &Primitive) -> Primitive {
305        match self.partial_cmp(other) {
306            Some(Ordering::Less) => Primitive::Bool(true),
307            Some(Ordering::Greater) => Primitive::Bool(false),
308            Some(Ordering::Equal) => Primitive::Bool(false),
309            None => Primitive::Error(format!(
310                "call to is_less_than() for two different types {self} => {other}"
311            )),
312        }
313    }
314    pub fn is_less_or_equal(&self, other: &Primitive) -> Primitive {
315        match self.partial_cmp(other) {
316            Some(Ordering::Less) | Some(Ordering::Equal) => {
317                Primitive::Bool(true)
318            }
319            Some(Ordering::Greater) => Primitive::Bool(false),
320            None => Primitive::Error(format!(
321                "call to is_less_or_equal() for two different types {self} => {other}"
322            )),
323        }
324    }
325    pub fn is_equal(&self, other: &Primitive) -> Primitive {
326        match self.partial_cmp(other) {
327            Some(Ordering::Equal) => Primitive::Bool(true),
328            Some(Ordering::Less) | Some(Ordering::Greater) => {
329                Primitive::Bool(false)
330            }
331            None => match (self, other) {
332                (Primitive::Null, _) | (_, Primitive::Null) => {
333                    Primitive::Bool(false)
334                }
335                (Primitive::Struct(_), Primitive::Struct(_)) => {
336                    Primitive::Bool(false)
337                }
338                _ => Primitive::Error(format!(
339                    "call to is_equal() for two different types {self} => {other}"
340                )),
341            },
342        }
343    }
344    pub fn as_ref_ok(&self) -> Result<&Primitive> {
345        match self {
346            Primitive::Error(msg) => Err(anyhow::Error::msg(msg.to_string())),
347
348            _ => Ok(self),
349        }
350    }
351}
352
353impl Display for Primitive {
354    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
355        match self {
356            Primitive::Ref(s) => {
357                let lock = s.read().expect("FMT ERROR: could not acquire lock");
358                write!(f, "{lock}")
359            }
360            Primitive::U8(u) => write!(f, "{u}"),
361            Primitive::I8(u) => write!(f, "{u}"),
362            Primitive::Int(i) => write!(f, "{i}"),
363            Primitive::Double(d) => write!(f, "{d}"),
364            Primitive::Bool(b) => write!(f, "{b}"),
365            Primitive::Error(e) => write!(f, "Err: {e}"),
366            Primitive::String(s) => {
367                write!(f, "{s}")
368            }
369            Primitive::Unit => write!(f, "()"),
370            Primitive::Array(arr) => {
371                let joined_arr = arr
372                    .iter()
373                    .map(|p| match p {
374                        Primitive::String(s) => format!(r#""{s}""#),
375                        _ => p.to_string(),
376                    })
377                    .collect::<Vec<_>>();
378                write!(f, "[{}]", joined_arr[..].join(", "))
379            }
380            Primitive::Struct(struc) => {
381                let joined_arr = struc
382                    .iter()
383                    .map(|(k, p)| {
384                        format!(
385                            "\t{k}: {}",
386                            if let Primitive::String(s) = p {
387                                format!(r#""{s}""#)
388                            } else {
389                                p.to_string()
390                            }
391                        )
392                    })
393                    .collect::<Vec<_>>();
394                write!(f, "struct {{\n{}\n}}", joined_arr[..].join(", \n"))
395            }
396            Primitive::Function { parameters, exprs: _ } => {
397                let mut parameters_formatted = String::new();
398                let len = parameters.len();
399                for (idx, p) in parameters.iter().enumerate() {
400                    match p {
401                        Value::VariableUnused => parameters_formatted.push('_'),
402                        _ => {
403                            parameters_formatted.push('p');
404                            parameters_formatted.push(
405                                char::from_digit(idx as u32, 10).unwrap_or('0'),
406                            );
407                        }
408                    }
409                    if idx < len {
410                        parameters_formatted.push(',');
411                    }
412                }
413                write!(f, "({parameters_formatted}) => {{..}}")
414            }
415            Primitive::NoReturn => write!(f, "!"),
416            Primitive::Null => write!(f, "{NULL}"),
417            Primitive::EarlyReturn(p) => write!(f, "{p}"),
418            Primitive::NativeLibrary { .. } => write!(f, "__native_lib__"),
419            Primitive::NativeFunction(key, _) => {
420                write!(f, "__native_fn__{key}")
421            }
422            Primitive::LibData(_) => write!(f, "__lib_data"),
423        }
424    }
425}
426
427impl Sin for Primitive {
428    fn sin(&self) -> Self {
429        match self {
430            Primitive::Ref(s) => {
431                let lock =
432                    s.read().expect("SIN ERORR: could not acquire lock!");
433                lock.sin()
434            }
435            Primitive::U8(i) => Primitive::Double((*i as f64).sin()),
436            Primitive::I8(i) => Primitive::Double((*i as f64).sin()),
437            Primitive::Int(i) => Primitive::Double((*i as f64).sin()),
438            Primitive::Double(d) => Primitive::Double(d.sin()),
439
440            Primitive::Error(e) => panic!("call to sin() on an error. {e}"),
441            _ => Primitive::Error(format!("illegal call to sin() => {self}")),
442        }
443    }
444}
445
446impl Cos for Primitive {
447    fn cos(&self) -> Self {
448        match self {
449            Primitive::Ref(s) => {
450                let lock =
451                    s.read().expect("COS ERORR: could not acquire lock!");
452                lock.cos()
453            }
454            Primitive::Int(i) => Primitive::Double((*i as f64).cos()),
455            Primitive::U8(i) => Primitive::Double((*i as f64).cos()),
456            Primitive::I8(i) => Primitive::Double((*i as f64).cos()),
457            Primitive::Double(d) => Primitive::Double(d.cos()),
458            Primitive::Error(e) => panic!("call to cos() on an error. {e}"),
459            _ => Primitive::Error(format!("illegal call to cos() => {self}")),
460        }
461    }
462}
463
464impl Tan for Primitive {
465    fn tan(&self) -> Self {
466        match self {
467            Primitive::Ref(s) => {
468                let lock =
469                    s.read().expect("TAN ERORR: could not acquire lock!");
470                lock.tan()
471            }
472
473            Primitive::U8(i) => Primitive::Double((*i as f64).tan()),
474            Primitive::I8(i) => Primitive::Double((*i as f64).tan()),
475            Primitive::Int(i) => Primitive::Double((*i as f64).tan()),
476            Primitive::Double(d) => Primitive::Double(d.tan()),
477            Primitive::Error(e) => panic!("call to tan() on an error. {e}"),
478            _ => Primitive::Error(format!("illegal call to tan() => {self}")),
479        }
480    }
481}
482
483impl Logarithm for Primitive {
484    fn log(&self) -> Self {
485        match self {
486            Primitive::Ref(s) => {
487                let lock =
488                    s.read().expect("LOG ERORR: could not acquire lock!");
489                lock.log()
490            }
491
492            Primitive::U8(i) => Primitive::Double((*i as f64).log10()),
493            Primitive::I8(i) => Primitive::Double((*i as f64).log10()),
494            Primitive::Int(i) => Primitive::Double((*i as f64).log10()),
495            Primitive::Double(d) => Primitive::Double(d.log10()),
496            Primitive::Error(e) => panic!("call to log() on an error. {e}"),
497            _ => Primitive::Error(format!("illegal call to log() => {self}")),
498        }
499    }
500    fn ln(&self) -> Self {
501        match self {
502            Primitive::Ref(s) => {
503                let lock = s.read().expect("LN ERORR: could not acquire lock!");
504                lock.ln()
505            }
506
507            Primitive::U8(i) => Primitive::Double((*i as f64).ln()),
508            Primitive::I8(i) => Primitive::Double((*i as f64).ln()),
509            Primitive::Int(i) => Primitive::Double((*i as f64).ln()),
510            Primitive::Double(d) => Primitive::Double(d.ln()),
511            Primitive::Error(e) => panic!("call to ln() on an error. {e}"),
512            _ => Primitive::Error(format!("illegal call to ln() => {self}")),
513        }
514    }
515}
516
517impl Sqrt for Primitive {
518    fn sqrt(&self) -> Self {
519        match self {
520            Primitive::Ref(s) => {
521                let lock =
522                    s.read().expect("SQRT ERORR: could not acquire lock!");
523                lock.sqrt()
524            }
525            Primitive::U8(i) => Primitive::Double((*i as f64).sqrt()),
526            Primitive::I8(i) => Primitive::Double((*i as f64).sqrt()),
527            Primitive::Int(i) => Primitive::Double((*i as f64).sqrt()),
528            Primitive::Double(d) => Primitive::Double(d.sqrt()),
529            Primitive::Error(e) => panic!("call to sqrt() on an error. {e}"),
530            _ => Primitive::Error(format!("illegal call to sqrt() => {self}")),
531        }
532    }
533}
534impl Abs for Primitive {
535    fn abs(&self) -> Self {
536        match self {
537            Primitive::Ref(s) => {
538                let lock =
539                    s.read().expect("ABS ERORR: could not acquire lock!");
540                lock.abs()
541            }
542            Primitive::U8(i) => Primitive::U8(*i),
543            Primitive::I8(i) => Primitive::I8(i.abs()),
544            Primitive::Int(i) => Primitive::Int(i.abs()),
545            Primitive::Double(d) => Primitive::Double(d.abs()),
546            Primitive::Error(e) => panic!("call to abs() on an error. {e}"),
547            _ => Primitive::Error(format!("illegal call to abs() => {self}")),
548        }
549    }
550}
551
552impl Pow for Primitive {
553    fn pow(&self, rhs: &Self) -> Self {
554        match (self, rhs) {
555            (Primitive::Ref(l), Primitive::Ref(r)) => {
556                let l = l.read().expect("POW L ERORR: could not acquire lock!");
557
558                let r = r.read().expect("POW R ERORR: could not acquire lock!");
559                l.pow(&r)
560            }
561            (Primitive::Ref(l), r) => {
562                let l = l.read().expect("POW L ERORR: could not acquire lock!");
563
564                l.pow(r)
565            }
566            (l, Primitive::Ref(r)) => {
567                let r = r.read().expect("POW R ERORR: could not acquire lock!");
568
569                l.pow(&r)
570            }
571            (Primitive::U8(l), Primitive::U8(r)) => {
572                Primitive::Int((*l as i128).pow(*r as u32))
573            }
574            (Primitive::U8(l), Primitive::I8(r)) if r > &0 => {
575                Primitive::Int((*l as i128).pow(*r as u32))
576            }
577            (Primitive::U8(l), Primitive::I8(r)) => {
578                Primitive::Double((*l as f64).powf(*r as f64))
579            }
580            #[allow(clippy::manual_range_contains)]
581            (Primitive::U8(l), Primitive::Int(r))
582                if r >= &0 && r <= &MAX_U32_AS_I128 =>
583            {
584                Primitive::Int((*l as i128).pow(*r as u32))
585            }
586
587            (Primitive::I8(l), Primitive::I8(r)) if r > &0 => {
588                Primitive::Int((*l as i128).pow(*r as u32))
589            }
590            (Primitive::I8(l), Primitive::I8(r)) => {
591                Primitive::Double((*l as f64).powf(*r as f64))
592            }
593
594            (Primitive::I8(l), Primitive::U8(r)) => {
595                Primitive::Int((*l as i128).pow(*r as u32))
596            }
597            #[allow(clippy::manual_range_contains)]
598            (Primitive::I8(l), Primitive::Int(r))
599                if r >= &0 && r <= &MAX_U32_AS_I128 =>
600            {
601                Primitive::Int((*l as i128).pow(*r as u32))
602            }
603
604            (Primitive::U8(l), Primitive::Int(r)) => {
605                Primitive::Double((*l as f64).powf(*r as f64))
606            }
607            (Primitive::I8(l), Primitive::Int(r)) => {
608                Primitive::Double((*l as f64).powf(*r as f64))
609            }
610            (Primitive::U8(l), Primitive::Double(r)) => {
611                Primitive::Double((*l as f64).powf(*r))
612            }
613            (Primitive::I8(l), Primitive::Double(r)) => {
614                Primitive::Double((*l as f64).powf(*r))
615            }
616
617            #[allow(clippy::manual_range_contains)]
618            (Primitive::Int(l), Primitive::Int(r))
619                if r >= &0 && r <= &MAX_U32_AS_I128 =>
620            {
621                Primitive::Int(l.pow(*r as u32))
622            }
623
624            (Primitive::Int(l), Primitive::U8(r)) => {
625                Primitive::Int(l.pow(*r as u32))
626            }
627            (Primitive::Int(l), Primitive::I8(r)) if r >= &0 => {
628                Primitive::Int(l.pow(*r as u32))
629            }
630            (Primitive::Int(l), Primitive::I8(r)) => {
631                Primitive::Double((*l as f64).powf(*r as f64))
632            }
633            (Primitive::Int(l), Primitive::Int(r)) => {
634                Primitive::Double((*l as f64).powf(*r as f64))
635            }
636            (Primitive::Int(l), Primitive::Double(r)) => {
637                Primitive::Double((*l as f64).powf(*r))
638            }
639            (Primitive::Double(l), Primitive::Int(r)) => {
640                Primitive::Double(l.powf(*r as f64))
641            }
642            (Primitive::Double(l), Primitive::U8(r)) => {
643                Primitive::Double(l.powf(*r as f64))
644            }
645            (Primitive::Double(l), Primitive::I8(r)) => {
646                Primitive::Double(l.powf(*r as f64))
647            }
648            (Primitive::Double(l), Primitive::Double(r)) => {
649                Primitive::Double(l.powf(*r))
650            }
651            (l, r) => Primitive::Error(format!(
652                "illegal call to pow() => left: {l} right: {r}"
653            )),
654        }
655    }
656}
657
658impl Add for Primitive {
659    fn add(&self, rhs: &Self) -> Self {
660        match (self.clone(), rhs.clone()) {
661            (Primitive::Ref(l), Primitive::Ref(r)) => {
662                let l = l.read().expect("ADD L ERORR: could not acquire lock!");
663
664                let r = r.read().expect("ADD R ERORR: could not acquire lock!");
665                l.add(&r)
666            }
667            (Primitive::Ref(l), r) => {
668                let l = l.read().expect("ADD L ERORR: could not acquire lock!");
669
670                l.add(&r)
671            }
672            (l, Primitive::Ref(r)) => {
673                let r = r.read().expect("ADD R ERORR: could not acquire lock!");
674
675                l.add(&r)
676            }
677            (Primitive::U8(l), Primitive::U8(r)) => {
678                Primitive::Int(l as i128 + r as i128)
679            }
680            (Primitive::U8(l), Primitive::I8(r)) => {
681                Primitive::Int(l as i128 + r as i128)
682            }
683            (Primitive::U8(l), Primitive::Int(r)) => {
684                Primitive::Int(l as i128 + r)
685            }
686            (Primitive::U8(l), Primitive::String(s)) => {
687                Primitive::String(format!("{l}{s}"))
688            }
689            (Primitive::U8(l), Primitive::Double(r)) => {
690                Primitive::Double(l as f64 + r)
691            }
692
693            (Primitive::I8(l), Primitive::I8(r)) => {
694                Primitive::Int(l as i128 + r as i128)
695            }
696            (Primitive::I8(l), Primitive::U8(r)) => {
697                Primitive::Int(l as i128 + r as i128)
698            }
699            (Primitive::I8(l), Primitive::Int(r)) => {
700                Primitive::Int(l as i128 + r)
701            }
702            (Primitive::I8(l), Primitive::String(s)) => {
703                Primitive::String(format!("{l}{s}"))
704            }
705            (Primitive::I8(l), Primitive::Double(r)) => {
706                Primitive::Double(l as f64 + r)
707            }
708
709            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l + r),
710            (Primitive::Int(l), Primitive::U8(r)) => {
711                Primitive::Int(l + r as i128)
712            }
713            (Primitive::Int(l), Primitive::I8(r)) => {
714                Primitive::Int(l + r as i128)
715            }
716            (Primitive::Int(l), Primitive::Double(r)) => {
717                Primitive::Double(l as f64 + r)
718            }
719            (Primitive::Int(l), Primitive::String(s)) => {
720                Primitive::String(format!("{l}{s}"))
721            }
722
723            (Primitive::Double(l), Primitive::Int(r)) => {
724                Primitive::Double(l + r as f64)
725            }
726            (Primitive::Double(l), Primitive::U8(r)) => {
727                Primitive::Double(l + r as f64)
728            }
729            (Primitive::Double(l), Primitive::I8(r)) => {
730                Primitive::Double(l + r as f64)
731            }
732            (Primitive::Double(l), Primitive::Double(r)) => {
733                Primitive::Double(l + r)
734            }
735
736            (Primitive::Array(mut l), Primitive::Array(mut r)) => {
737                l.append(&mut r);
738                Primitive::Array(l)
739            }
740
741            (Primitive::Array(mut l), r) => {
742                let r: Primitive = r;
743                l.push(r);
744                Primitive::Array(l)
745            }
746            (l, Primitive::Array(mut r)) => {
747                r.insert(0, l);
748                Primitive::Array(r)
749            }
750            (l, Primitive::String(s)) => Primitive::String(format!("{l}{s}")),
751
752            (Primitive::String(s), r) => Primitive::String(format!("{s}{r}")),
753            (l, r) => Primitive::Error(format!(
754                "illegal call to add() => left: {l} right: {r}"
755            )),
756        }
757    }
758}
759
760impl Sub for Primitive {
761    fn sub(&self, rhs: &Self) -> Self {
762        match (self.clone(), rhs.clone()) {
763            (Primitive::Ref(l), Primitive::Ref(r)) => {
764                let l = l.read().expect("SUB L ERORR: could not acquire lock!");
765
766                let r = r.read().expect("SUB R ERORR: could not acquire lock!");
767                l.sub(&r)
768            }
769            (Primitive::Ref(l), r) => {
770                let l = l.read().expect("SUB L ERORR: could not acquire lock!");
771
772                l.sub(&r)
773            }
774            (l, Primitive::Ref(r)) => {
775                let r = r.read().expect("SUB R ERORR: could not acquire lock!");
776
777                l.sub(&r)
778            }
779
780            (Primitive::U8(l), Primitive::U8(r)) => {
781                if let Some(v) = l.checked_sub(r) {
782                    Primitive::U8(v)
783                } else {
784                    Primitive::Int(l as i128 - r as i128)
785                }
786            }
787            (Primitive::U8(l), Primitive::I8(r)) => {
788                Primitive::Int(l as i128 - r as i128)
789            }
790            (Primitive::U8(l), Primitive::Int(r)) => {
791                Primitive::Int(l as i128 - r)
792            }
793            (Primitive::U8(l), Primitive::Double(r)) => {
794                Primitive::Double(l as f64 - r)
795            }
796
797            (Primitive::I8(l), Primitive::U8(r)) => {
798                Primitive::Int(l as i128 - r as i128)
799            }
800            (Primitive::I8(l), Primitive::I8(r)) => {
801                if let Some(v) = l.checked_sub(r) {
802                    Primitive::I8(v)
803                } else {
804                    Primitive::Int(l as i128 - r as i128)
805                }
806            }
807            (Primitive::I8(l), Primitive::Int(r)) => {
808                Primitive::Int(l as i128 - r)
809            }
810            (Primitive::I8(l), Primitive::Double(r)) => {
811                Primitive::Double(l as f64 - r)
812            }
813
814            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l - r),
815            (Primitive::Int(l), Primitive::Double(r)) => {
816                Primitive::Double(l as f64 - r)
817            }
818            (Primitive::Int(l), Primitive::U8(r)) => {
819                Primitive::Int(l - r as i128)
820            }
821            (Primitive::Int(l), Primitive::I8(r)) => {
822                Primitive::Int(l - r as i128)
823            }
824
825            (Primitive::Double(l), Primitive::Int(r)) => {
826                Primitive::Double(l - r as f64)
827            }
828            (Primitive::Double(l), Primitive::Double(r)) => {
829                Primitive::Double(l - r)
830            }
831            (Primitive::Double(l), Primitive::U8(r)) => {
832                Primitive::Double(l - r as f64)
833            }
834            (Primitive::Double(l), Primitive::I8(r)) => {
835                Primitive::Double(l - r as f64)
836            }
837
838            (l, r) => Primitive::Error(format!(
839                "illegal call to sub() => left: {l} right: {r}"
840            )),
841        }
842    }
843}
844impl Rem for Primitive {
845    fn rem(&self, rhs: &Self) -> Self {
846        match (self.clone(), rhs.clone()) {
847            (Primitive::Ref(l), Primitive::Ref(r)) => {
848                let l = l.read().expect("REM L ERORR: could not acquire lock!");
849
850                let r = r.read().expect("REM R ERORR: could not acquire lock!");
851                l.rem(&r)
852            }
853            (Primitive::Ref(l), r) => {
854                let l = l.read().expect("REM L ERORR: could not acquire lock!");
855
856                l.rem(&r)
857            }
858            (l, Primitive::Ref(r)) => {
859                let r = r.read().expect("REM R ERORR: could not acquire lock!");
860
861                l.rem(&r)
862            }
863
864            (Primitive::U8(l), Primitive::U8(r)) if r != 0 => {
865                Primitive::U8(l % r)
866            }
867            (Primitive::U8(l), Primitive::I8(r)) if r != 0 => {
868                Primitive::Int(l as i128 % r as i128)
869            }
870            (Primitive::U8(l), Primitive::Int(r)) if r != 0 => {
871                Primitive::Int(l as i128 % r)
872            }
873            (Primitive::U8(l), Primitive::Double(r)) => {
874                Primitive::Double(l as f64 % r)
875            }
876            (Primitive::U8(_), _) => Primitive::Double(f64::NAN),
877
878            (Primitive::I8(l), Primitive::I8(r)) if r != 0 => {
879                Primitive::I8(l % r)
880            }
881            (Primitive::I8(l), Primitive::U8(r)) if r != 0 => {
882                Primitive::Int(l as i128 % r as i128)
883            }
884            (Primitive::I8(l), Primitive::Int(r)) if r != 0 => {
885                Primitive::Int(l as i128 % r)
886            }
887            (Primitive::I8(l), Primitive::Double(r)) => {
888                Primitive::Double(l as f64 % r)
889            }
890            (Primitive::I8(_), _) => Primitive::Double(f64::NAN),
891
892            (Primitive::Int(l), Primitive::Int(r)) if r != 0 => {
893                Primitive::Int(l % r)
894            }
895            (Primitive::Int(l), Primitive::U8(r)) if r != 0 => {
896                Primitive::Int(l % r as i128)
897            }
898            (Primitive::Int(l), Primitive::I8(r)) if r != 0 => {
899                Primitive::Int(l % r as i128)
900            }
901            (Primitive::Int(l), Primitive::Double(r)) => {
902                Primitive::Double(l as f64 % r)
903            }
904            (Primitive::Int(_), _) => Primitive::Double(f64::NAN),
905
906            (Primitive::Double(l), Primitive::U8(r)) => {
907                Primitive::Double(l % r as f64)
908            }
909            (Primitive::Double(l), Primitive::I8(r)) => {
910                Primitive::Double(l % r as f64)
911            }
912            (Primitive::Double(l), Primitive::Int(r)) => {
913                Primitive::Double(l % r as f64)
914            }
915            (Primitive::Double(l), Primitive::Double(r)) => {
916                Primitive::Double(l % r)
917            }
918
919            (l, r) => Primitive::Error(format!(
920                "illegal call to rem() => left: {l} right: {r}"
921            )),
922        }
923    }
924}
925
926impl Mul for Primitive {
927    fn mul(&self, rhs: &Self) -> Self {
928        fn multiply_array(arr: Vec<Primitive>, n: i128) -> Vec<Primitive> {
929            let arr_size = arr.len();
930            arr.into_iter().cycle().take(n as usize * arr_size).collect()
931        }
932        match (self.clone(), rhs.clone()) {
933            (Primitive::Ref(l), Primitive::Ref(r)) => {
934                let l = l.read().expect("MUL L ERORR: could not acquire lock!");
935
936                let r = r.read().expect("MUL R ERORR: could not acquire lock!");
937                l.mul(&r)
938            }
939            (Primitive::Ref(l), r) => {
940                let l = l.read().expect("MUL L ERORR: could not acquire lock!");
941
942                l.mul(&r)
943            }
944            (l, Primitive::Ref(r)) => {
945                let r = r.read().expect("MUL R ERORR: could not acquire lock!");
946
947                l.mul(&r)
948            }
949
950            (Primitive::U8(l), Primitive::U8(r)) => {
951                Primitive::Int(l as i128 * r as i128)
952            }
953            (Primitive::U8(l), Primitive::I8(r)) => {
954                Primitive::Int(l as i128 * r as i128)
955            }
956            (Primitive::U8(l), Primitive::Int(r)) => {
957                Primitive::Int(l as i128 * r)
958            }
959            (Primitive::U8(l), Primitive::Double(r)) => {
960                Primitive::Double(l as f64 * r)
961            }
962            (Primitive::U8(l), Primitive::Array(r)) => {
963                Primitive::Array(multiply_array(r, l as i128))
964            }
965
966            (Primitive::I8(l), Primitive::U8(r)) => {
967                Primitive::Int(l as i128 * r as i128)
968            }
969            (Primitive::I8(l), Primitive::I8(r)) => {
970                Primitive::Int(l as i128 * r as i128)
971            }
972            (Primitive::I8(l), Primitive::Int(r)) => {
973                Primitive::Int(l as i128 * r)
974            }
975            (Primitive::I8(l), Primitive::Double(r)) => {
976                Primitive::Double(l as f64 * r)
977            }
978            (Primitive::I8(l), Primitive::Array(r)) if l >= 0 => {
979                Primitive::Array(multiply_array(r, l as i128))
980            }
981
982            (Primitive::Int(l), Primitive::Int(r)) => {
983                Primitive::Int(l.wrapping_mul(r))
984            }
985            (Primitive::Int(l), Primitive::U8(r)) => {
986                Primitive::Int(l * r as i128)
987            }
988            (Primitive::Int(l), Primitive::I8(r)) => {
989                Primitive::Int(l * r as i128)
990            }
991            (Primitive::Int(l), Primitive::Double(r)) => {
992                Primitive::Double(l as f64 * r)
993            }
994            (Primitive::Int(l), Primitive::Array(r)) if l >= 0 => {
995                Primitive::Array(multiply_array(r, l))
996            }
997
998            (Primitive::Double(l), Primitive::Int(r)) => {
999                Primitive::Double(l * r as f64)
1000            }
1001            (Primitive::Double(l), Primitive::U8(r)) => {
1002                Primitive::Double(l * r as f64)
1003            }
1004            (Primitive::Double(l), Primitive::I8(r)) => {
1005                Primitive::Double(l * r as f64)
1006            }
1007            (Primitive::Double(l), Primitive::Double(r)) => {
1008                Primitive::Double(l * r)
1009            }
1010
1011            (Primitive::String(l), Primitive::Int(r)) if r >= 0 => {
1012                Primitive::String(l.repeat(r as usize))
1013            }
1014            (Primitive::String(l), Primitive::U8(r)) => {
1015                Primitive::String(l.repeat(r as usize))
1016            }
1017            (Primitive::String(l), Primitive::I8(r)) if r >= 0 => {
1018                Primitive::String(l.repeat(r as usize))
1019            }
1020
1021            (Primitive::Array(l), Primitive::Int(n)) if n >= 0 => {
1022                Primitive::Array(multiply_array(l, n))
1023            }
1024            (Primitive::Array(l), Primitive::U8(n)) => {
1025                Primitive::Array(multiply_array(l, n as i128))
1026            }
1027            (Primitive::Array(l), Primitive::I8(n)) if n >= 0 => {
1028                Primitive::Array(multiply_array(l, n as i128))
1029            }
1030
1031            (l, r) => Primitive::Error(format!(
1032                "illegal call to mul() => left: {l} right: {r}"
1033            )),
1034        }
1035    }
1036}
1037impl Div for Primitive {
1038    fn div(&self, rhs: &Self) -> Self {
1039        match (self.clone(), rhs.clone()) {
1040            (Primitive::Ref(l), Primitive::Ref(r)) => {
1041                let l = l.read().expect("DIV L ERORR: could not acquire lock!");
1042
1043                let r = r.read().expect("DIV R ERORR: could not acquire lock!");
1044                l.div(&r)
1045            }
1046            (Primitive::Ref(l), r) => {
1047                let l = l.read().expect("DIV L ERORR: could not acquire lock!");
1048
1049                l.div(&r)
1050            }
1051            (l, Primitive::Ref(r)) => {
1052                let r = r.read().expect("DIV R ERORR: could not acquire lock!");
1053
1054                l.div(&r)
1055            }
1056
1057            (Primitive::U8(l), Primitive::U8(r)) if r != 0 => {
1058                Primitive::Int(l as i128 / r as i128)
1059            }
1060            (Primitive::U8(l), Primitive::I8(r)) if r != 0 => {
1061                Primitive::Int(l as i128 / r as i128)
1062            }
1063            (Primitive::U8(l), Primitive::Int(r)) if r != 0 => {
1064                Primitive::Int(l as i128 / r)
1065            }
1066            (Primitive::U8(l), Primitive::Double(r)) => {
1067                Primitive::Double(l as f64 / r)
1068            }
1069            (Primitive::U8(l), Primitive::Int(_)) if l >= 1 => {
1070                Primitive::Double(f64::INFINITY)
1071            }
1072            (Primitive::U8(l), Primitive::U8(_)) if l >= 1 => {
1073                Primitive::Double(f64::INFINITY)
1074            }
1075            (Primitive::U8(l), Primitive::I8(_)) if l >= 1 => {
1076                Primitive::Double(f64::INFINITY)
1077            }
1078            (Primitive::U8(_), _) => Primitive::Double(f64::NAN),
1079
1080            (Primitive::I8(l), Primitive::U8(r)) if r != 0 => {
1081                Primitive::Int(l as i128 / r as i128)
1082            }
1083            (Primitive::I8(l), Primitive::I8(r)) if r != 0 => {
1084                Primitive::Int(l as i128 / r as i128)
1085            }
1086            (Primitive::I8(l), Primitive::Int(r)) if r != 0 => {
1087                Primitive::Int(l as i128 / r)
1088            }
1089            (Primitive::I8(l), Primitive::Double(r)) => {
1090                Primitive::Double(l as f64 / r)
1091            }
1092            (Primitive::I8(l), Primitive::Int(_)) if l >= 1 => {
1093                Primitive::Double(f64::INFINITY)
1094            }
1095            (Primitive::I8(l), Primitive::U8(_)) if l >= 1 => {
1096                Primitive::Double(f64::INFINITY)
1097            }
1098            (Primitive::I8(l), Primitive::I8(_)) if l >= 1 => {
1099                Primitive::Double(f64::INFINITY)
1100            }
1101            (Primitive::I8(_), _) => Primitive::Double(f64::NAN),
1102
1103            (Primitive::Int(l), Primitive::Int(r)) if r != 0 => {
1104                Primitive::Int(l / r)
1105            }
1106            (Primitive::Int(l), Primitive::U8(r)) if r != 0 => {
1107                Primitive::Int(l / r as i128)
1108            }
1109            (Primitive::Int(l), Primitive::I8(r)) if r != 0 => {
1110                Primitive::Int(l / r as i128)
1111            }
1112            (Primitive::Int(l), Primitive::Double(r)) => {
1113                Primitive::Double(l as f64 / r)
1114            }
1115            (Primitive::Int(l), Primitive::Int(_)) if l >= 1 => {
1116                Primitive::Double(f64::INFINITY)
1117            }
1118            (Primitive::Int(l), Primitive::U8(_)) if l >= 1 => {
1119                Primitive::Double(f64::INFINITY)
1120            }
1121            (Primitive::Int(l), Primitive::I8(_)) if l >= 1 => {
1122                Primitive::Double(f64::INFINITY)
1123            }
1124            (Primitive::Int(_), _) => Primitive::Double(f64::NAN),
1125
1126            (Primitive::Double(l), Primitive::Int(r)) => {
1127                Primitive::Double(l / r as f64)
1128            }
1129            (Primitive::Double(l), Primitive::U8(r)) => {
1130                Primitive::Double(l / r as f64)
1131            }
1132            (Primitive::Double(l), Primitive::I8(r)) => {
1133                Primitive::Double(l / r as f64)
1134            }
1135            (Primitive::Double(l), Primitive::Double(r)) => {
1136                Primitive::Double(l / r)
1137            }
1138
1139            (l, r) => Primitive::Error(format!(
1140                "illegal call to div() => left: {l} right: {r}"
1141            )),
1142        }
1143    }
1144}
1145
1146impl Neg for Primitive {
1147    fn neg(&self) -> Self {
1148        match self {
1149            Primitive::Ref(s) => {
1150                let lock =
1151                    s.read().expect("NEG ERORR: could not acquire lock!");
1152                lock.neg()
1153            }
1154            Primitive::U8(n) if *n > i8::MAX as u8 => {
1155                Primitive::Int(-(*n as i128))
1156            }
1157            Primitive::U8(n) => Primitive::I8(-(*n as i8)),
1158            Primitive::I8(n) => Primitive::I8(-*n),
1159
1160            Primitive::Int(n) => Primitive::Int(-n),
1161            Primitive::Double(n) => Primitive::Double(-n),
1162            _ => Primitive::Error(format!("invalid call to neg() {self}")),
1163        }
1164    }
1165}
1166
1167impl Not for Primitive {
1168    fn not(&self) -> Self {
1169        match self {
1170            Primitive::Ref(s) => {
1171                let lock =
1172                    s.read().expect("NOT ERORR: could not acquire lock!");
1173                lock.not()
1174            }
1175            Primitive::Bool(b) => Primitive::Bool(!b),
1176            _ => Primitive::Error(format!("invalid call to not() {self}")),
1177        }
1178    }
1179    fn bitwise_not(&self) -> Self {
1180        match self {
1181            Primitive::Ref(s) => {
1182                let lock =
1183                    s.read().expect("NOT ERORR: could not acquire lock!");
1184                lock.not()
1185            }
1186            Primitive::U8(b) if *b < i8::MAX as u8 => {
1187                Primitive::I8(!(*b as i8))
1188            }
1189            Primitive::U8(b) => Primitive::Int(!(*b as i128)),
1190            Primitive::I8(b) => Primitive::I8(!b),
1191            Primitive::Int(b) => Primitive::Int(!b),
1192            _ => Primitive::Error(format!(
1193                "invalid call to bitwise_not() {self}"
1194            )),
1195        }
1196    }
1197}
1198
1199impl ToBool for Primitive {
1200    fn to_bool(&self) -> Self {
1201        match self {
1202            Primitive::Ref(s) => {
1203                let lock =
1204                    s.read().expect("TO_BOOL ERORR: could not acquire lock!");
1205                lock.to_bool()
1206            }
1207            v @ Primitive::Bool(_) => v.clone(),
1208            Primitive::Double(n) => Primitive::Bool(n > &0.0),
1209            Primitive::U8(n) => Primitive::Bool(n > &0),
1210            Primitive::I8(n) => Primitive::Bool(n > &0),
1211            Primitive::Int(n) => Primitive::Bool(n > &0),
1212            Primitive::Null => Primitive::Bool(false),
1213            Primitive::Array(a) => Primitive::Bool(!a.is_empty()),
1214            Primitive::String(s) => match s.parse::<bool>() {
1215                Ok(b) => Primitive::Bool(b),
1216                Err(e) => Primitive::Error(format!(
1217                    "invalid cast to bool: {self}, {e}"
1218                )),
1219            },
1220            _ => Primitive::Error(format!("invalide cast too bool: {self}")),
1221        }
1222    }
1223}
1224
1225impl ToNumber for Primitive {
1226    fn to_int(&self) -> Self {
1227        match self {
1228            Primitive::Ref(s) => {
1229                let lock =
1230                    s.read().expect("TO_INT ERORR: could not acquire lock!");
1231                lock.to_int()
1232            }
1233            v @ Primitive::Int(_) => v.clone(),
1234            v @ Primitive::U8(_) => v.clone(),
1235            v @ Primitive::I8(_) => v.clone(),
1236            Primitive::Bool(false) => Primitive::Int(0),
1237            Primitive::Bool(true) => Primitive::Int(1),
1238            Primitive::Double(d) => Primitive::Int(*d as i128),
1239            Primitive::String(s) => match s.parse::<i128>() {
1240                Ok(number) => Primitive::Int(number),
1241                Err(e) => Primitive::Error(format!(
1242                    "invalid cast to int: {self}, {e}"
1243                )),
1244            },
1245            _ => Primitive::Error(format!("invalid cast to int: {self}")),
1246        }
1247    }
1248
1249    fn to_double(&self) -> Self {
1250        match self {
1251            Primitive::Ref(s) => {
1252                let lock =
1253                    s.read().expect("TO_DOUBLE ERORR: could not acquire lock!");
1254                lock.to_double()
1255            }
1256            Primitive::U8(d) => Primitive::Double(*d as f64),
1257            Primitive::I8(d) => Primitive::Double(*d as f64),
1258            Primitive::Int(d) => Primitive::Double(*d as f64),
1259            v @ Primitive::Double(_) => v.clone(),
1260            Primitive::String(s) => match s.parse::<f64>() {
1261                Ok(number) => Primitive::Double(number),
1262                Err(e) => Primitive::Error(format!(
1263                    "invalid cast to double: {self}, {e}"
1264                )),
1265            },
1266            _ => Primitive::Error(format!("invalid cast to double: {self}")),
1267        }
1268    }
1269}
1270
1271impl BitShift for Primitive {
1272    fn right_shift(&self, rhs: &Self) -> Self {
1273        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1274            let l =
1275                l.read().expect("B_R_SHIFT L ERROR: could not acquire lock!");
1276            let r =
1277                r.read().expect("B_R_SHIFT R ERROR: could not acquire lock!");
1278            return l.right_shift(&r);
1279        } else if let &Primitive::Ref(l) = &self {
1280            let l = l
1281                .read()
1282                .expect("B_R_SHIFT SELF ERROR: could not acquire lock!");
1283            return l.right_shift(rhs);
1284        } else if let &Primitive::Ref(r) = &rhs {
1285            let r =
1286                r.read().expect("B_R_SHIFT RHS ERROR: could not acquire lock!");
1287            return self.right_shift(&r);
1288        }
1289
1290        match (self, rhs) {
1291            (Primitive::U8(l), Primitive::U8(r)) => {
1292                Primitive::Int(*l as i128 >> *r as i128)
1293            }
1294            (Primitive::U8(l), Primitive::Bool(r)) => {
1295                Primitive::U8(l >> if r == &true { 1 } else { 0 })
1296            }
1297            (Primitive::U8(l), Primitive::Int(r)) => {
1298                Primitive::Int(*l as i128 >> r)
1299            }
1300            (Primitive::U8(l), Primitive::I8(r)) => {
1301                Primitive::Int(*l as i128 >> *r as i128)
1302            }
1303            (Primitive::I8(l), Primitive::I8(r)) => {
1304                Primitive::Int(*l as i128 >> *r as i128)
1305            }
1306            (Primitive::I8(l), Primitive::Int(r)) => {
1307                Primitive::Int(*l as i128 >> r)
1308            }
1309            (Primitive::I8(l), Primitive::U8(r)) => {
1310                Primitive::Int(*l as i128 >> *r as i128)
1311            }
1312            (Primitive::I8(l), Primitive::Bool(r)) => {
1313                Primitive::I8(l >> if r == &true { 1 } else { 0 })
1314            }
1315            (Primitive::Int(l), Primitive::U8(r)) => {
1316                Primitive::Int(l >> *r as i128)
1317            }
1318            (Primitive::Int(l), Primitive::I8(r)) => {
1319                Primitive::Int(l >> *r as i128)
1320            }
1321            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l >> *r),
1322            (Primitive::Int(l), Primitive::Bool(r)) => {
1323                Primitive::Int(l >> if r == &true { 1 } else { 0 })
1324            }
1325            _ => Primitive::Error(format!(
1326                "illegal call to 'r_shift' => left: {self} right: {rhs}"
1327            )),
1328        }
1329    }
1330
1331    fn left_shift(&self, rhs: &Self) -> Self {
1332        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1333            let l =
1334                l.read().expect("B_L_SHIFT L ERROR: could not acquire lock!");
1335            let r =
1336                r.read().expect("B_L_SHIFT R ERROR: could not acquire lock!");
1337            return l.left_shift(&r);
1338        } else if let &Primitive::Ref(l) = &self {
1339            let l = l
1340                .read()
1341                .expect("B_L_SHIFT SELF ERROR: could not acquire lock!");
1342            return l.left_shift(rhs);
1343        } else if let &Primitive::Ref(r) = &rhs {
1344            let r =
1345                r.read().expect("B_L_SHIFT RHS ERROR: could not acquire lock!");
1346            return self.left_shift(&r);
1347        }
1348
1349        match (self, rhs) {
1350            (Primitive::U8(l), Primitive::U8(r)) => {
1351                Primitive::Int((*l as i128) << *r as i128)
1352            }
1353            (Primitive::U8(l), Primitive::Bool(r)) => {
1354                Primitive::U8(l << if r == &true { 1 } else { 0 })
1355            }
1356            (Primitive::U8(l), Primitive::Int(r)) => {
1357                Primitive::Int((*l as i128) << r)
1358            }
1359            (Primitive::U8(l), Primitive::I8(r)) => {
1360                Primitive::Int((*l as i128) << r)
1361            }
1362            (Primitive::I8(l), Primitive::I8(r)) => {
1363                Primitive::Int((*l as i128) << (*r as i128))
1364            }
1365            (Primitive::I8(l), Primitive::Int(r)) => {
1366                Primitive::Int((*l as i128) << r)
1367            }
1368            (Primitive::I8(l), Primitive::U8(r)) => {
1369                Primitive::Int((*l as i128) << *r as i128)
1370            }
1371            (Primitive::I8(l), Primitive::Bool(r)) => {
1372                Primitive::I8(l << if r == &true { 1 } else { 0 })
1373            }
1374            (Primitive::Int(l), Primitive::U8(r)) => {
1375                Primitive::Int(l << *r as i128)
1376            }
1377            (Primitive::Int(l), Primitive::I8(r)) => {
1378                Primitive::Int(l << *r as i128)
1379            }
1380            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l << *r),
1381            (Primitive::Int(l), Primitive::Bool(r)) => {
1382                Primitive::Int(l << if r == &true { 1 } else { 0 })
1383            }
1384            _ => Primitive::Error(format!(
1385                "illegal call to 'l_shift' => left: {self} right: {rhs}"
1386            )),
1387        }
1388    }
1389}
1390
1391impl Or for Primitive {
1392    fn or(&self, rhs: &Self) -> Self {
1393        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1394            let l = l.read().expect("OR L ERROR: could not acquire lock!");
1395            let r = r.read().expect("OR R ERROR: could not acquire lock!");
1396            return l.or(&r);
1397        } else if let &Primitive::Ref(l) = &self {
1398            let l = l.read().expect("OR SELF ERROR: could not acquire lock!");
1399            return l.or(rhs);
1400        } else if let &Primitive::Ref(r) = &rhs {
1401            let r = r.read().expect("OR RHS ERROR: could not acquire lock!");
1402            return self.or(&r);
1403        }
1404        if let &Primitive::Bool(true) = &self {
1405            return Primitive::Bool(true);
1406        }
1407        if !matches!((self, &rhs), (Primitive::Bool(_), Primitive::Bool(_))) {
1408            Primitive::Error(format!(
1409                "illegal call to 'or' => left: {self} right: {rhs}"
1410            ));
1411        }
1412        rhs.clone()
1413    }
1414
1415    fn bitwise_or(&self, rhs: &Self) -> Self {
1416        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1417            let l = l.read().expect("B_OR L ERROR: could not acquire lock!");
1418            let r = r.read().expect("B_OR R ERROR: could not acquire lock!");
1419            return l.bitwise_or(&r);
1420        } else if let &Primitive::Ref(l) = &self {
1421            let l = l.read().expect("B_OR SELF ERROR: could not acquire lock!");
1422            return l.bitwise_or(rhs);
1423        } else if let &Primitive::Ref(r) = &rhs {
1424            let r = r.read().expect("B_OR RHS ERROR: could not acquire lock!");
1425            return self.bitwise_or(&r);
1426        }
1427
1428        match (self, rhs) {
1429            (Primitive::U8(l), Primitive::U8(r)) => Primitive::U8(l | r),
1430            (Primitive::U8(l), Primitive::Bool(r)) => {
1431                Primitive::U8(l | if r == &true { 1 } else { 0 })
1432            }
1433            (Primitive::U8(l), Primitive::Int(r)) => {
1434                Primitive::Int(*l as i128 | r)
1435            }
1436            (Primitive::U8(l), Primitive::I8(r)) => {
1437                Primitive::Int(*l as i128 | *r as i128)
1438            }
1439            (Primitive::I8(l), Primitive::I8(r)) => Primitive::I8(l | r),
1440            (Primitive::I8(l), Primitive::Int(r)) => {
1441                Primitive::Int(*l as i128 | r)
1442            }
1443            (Primitive::I8(l), Primitive::U8(r)) => {
1444                Primitive::Int(*l as i128 | *r as i128)
1445            }
1446            (Primitive::I8(l), Primitive::Bool(r)) => {
1447                Primitive::I8(l | if r == &true { 1 } else { 0 })
1448            }
1449            (Primitive::Int(l), Primitive::U8(r)) => {
1450                Primitive::Int(l | *r as i128)
1451            }
1452            (Primitive::Int(l), Primitive::I8(r)) => {
1453                Primitive::Int(l | *r as i128)
1454            }
1455            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l | *r),
1456            (Primitive::Int(l), Primitive::Bool(r)) => {
1457                Primitive::Int(l | if r == &true { 1 } else { 0 })
1458            }
1459            _ => Primitive::Error(format!(
1460                "illegal call to 'bitwise_or' => left: {self} right: {rhs}"
1461            )),
1462        }
1463    }
1464
1465    fn bitwise_xor(&self, rhs: &Self) -> Self {
1466        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1467            let l = l.read().expect("B_XOR L ERROR: could not acquire lock!");
1468            let r = r.read().expect("B_XOR R ERROR: could not acquire lock!");
1469            return l.bitwise_xor(&r);
1470        } else if let &Primitive::Ref(l) = &self {
1471            let l =
1472                l.read().expect("B_XOR SELF ERROR: could not acquire lock!");
1473            return l.bitwise_xor(rhs);
1474        } else if let &Primitive::Ref(r) = &rhs {
1475            let r = r.read().expect("B_XOR RHS ERROR: could not acquire lock!");
1476            return self.bitwise_xor(&r);
1477        }
1478
1479        match (self, rhs) {
1480            (Primitive::U8(l), Primitive::U8(r)) => Primitive::U8(l ^ r),
1481            (Primitive::U8(l), Primitive::Bool(r)) => {
1482                Primitive::U8(l ^ if r == &true { 1 } else { 0 })
1483            }
1484            (Primitive::U8(l), Primitive::Int(r)) => {
1485                Primitive::Int(*l as i128 ^ r)
1486            }
1487            (Primitive::U8(l), Primitive::I8(r)) => {
1488                Primitive::Int(*l as i128 ^ *r as i128)
1489            }
1490            (Primitive::I8(l), Primitive::I8(r)) => Primitive::I8(l ^ r),
1491            (Primitive::I8(l), Primitive::Int(r)) => {
1492                Primitive::Int(*l as i128 ^ r)
1493            }
1494            (Primitive::I8(l), Primitive::U8(r)) => {
1495                Primitive::Int(*l as i128 ^ *r as i128)
1496            }
1497            (Primitive::I8(l), Primitive::Bool(r)) => {
1498                Primitive::I8(l ^ if r == &true { 1 } else { 0 })
1499            }
1500            (Primitive::Int(l), Primitive::U8(r)) => {
1501                Primitive::Int(l ^ *r as i128)
1502            }
1503            (Primitive::Int(l), Primitive::I8(r)) => {
1504                Primitive::Int(l ^ *r as i128)
1505            }
1506            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l ^ *r),
1507            (Primitive::Int(l), Primitive::Bool(r)) => {
1508                Primitive::Int(l ^ if r == &true { 1 } else { 0 })
1509            }
1510            _ => Primitive::Error(format!(
1511                "illegal call to 'bitwise_xor' => left: {self} right: {rhs}"
1512            )),
1513        }
1514    }
1515}
1516impl And for Primitive {
1517    fn and(&self, rhs: &Self) -> Self {
1518        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1519            let l = l.read().expect("AND L ERROR: could not acquire lock!");
1520            let r = r.read().expect("AND R ERROR: could not acquire lock!");
1521            return l.and(&r);
1522        } else if let &Primitive::Ref(l) = &self {
1523            let l = l.read().expect("AND SELF ERROR: could not acquire lock!");
1524            return l.and(rhs);
1525        } else if let &Primitive::Ref(r) = &rhs {
1526            let r = r.read().expect("AND RHS ERROR: could not acquire lock!");
1527            return self.and(&r);
1528        }
1529        if let &Primitive::Bool(false) = &self {
1530            return Primitive::Bool(false);
1531        }
1532
1533        if !matches!((self, &rhs), (Primitive::Bool(_), Primitive::Bool(_))) {
1534            return Primitive::Error(format!(
1535                "illegal call to 'and' => left: {self} right: {rhs}"
1536            ));
1537        }
1538
1539        rhs.clone()
1540    }
1541    fn bitwise_and(&self, rhs: &Self) -> Self {
1542        if let (&Primitive::Ref(l), &Primitive::Ref(r)) = (&self, &rhs) {
1543            let l = l.read().expect("B_AND L ERROR: could not acquire lock!");
1544            let r = r.read().expect("B_AND R ERROR: could not acquire lock!");
1545            return l.bitwise_and(&r);
1546        } else if let &Primitive::Ref(l) = &self {
1547            let l =
1548                l.read().expect("B_AND SELF ERROR: could not acquire lock!");
1549            return l.bitwise_and(rhs);
1550        } else if let &Primitive::Ref(r) = &rhs {
1551            let r = r.read().expect("B_AND RHS ERROR: could not acquire lock!");
1552            return self.bitwise_and(&r);
1553        }
1554
1555        match (self, rhs) {
1556            (Primitive::U8(l), Primitive::U8(r)) => Primitive::U8(l & r),
1557            (Primitive::U8(l), Primitive::Bool(r)) => {
1558                Primitive::U8(l & if r == &true { 1 } else { 0 })
1559            }
1560            (Primitive::U8(l), Primitive::Int(r)) => {
1561                Primitive::Int(*l as i128 & r)
1562            }
1563            (Primitive::U8(l), Primitive::I8(r)) => {
1564                Primitive::Int(*l as i128 & *r as i128)
1565            }
1566            (Primitive::I8(l), Primitive::I8(r)) => Primitive::I8(l & r),
1567            (Primitive::I8(l), Primitive::Int(r)) => {
1568                Primitive::Int(*l as i128 & r)
1569            }
1570            (Primitive::I8(l), Primitive::U8(r)) => {
1571                Primitive::Int(*l as i128 & *r as i128)
1572            }
1573            (Primitive::I8(l), Primitive::Bool(r)) => {
1574                Primitive::I8(l & if r == &true { 1 } else { 0 })
1575            }
1576            (Primitive::Int(l), Primitive::U8(r)) => {
1577                Primitive::Int(l & *r as i128)
1578            }
1579            (Primitive::Int(l), Primitive::I8(r)) => {
1580                Primitive::Int(l & *r as i128)
1581            }
1582            (Primitive::Int(l), Primitive::Int(r)) => Primitive::Int(l & *r),
1583            (Primitive::Int(l), Primitive::Bool(r)) => {
1584                Primitive::Int(l & if r == &true { 1 } else { 0 })
1585            }
1586            _ => Primitive::Error(format!(
1587                "illegal call to 'bitwise_and' => left: {self} right: {rhs}"
1588            )),
1589        }
1590    }
1591}
1592
1593impl PartialOrd for Primitive {
1594    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1595        match (self, other) {
1596            (Primitive::Ref(l), Primitive::Ref(r)) => {
1597                if Arc::ptr_eq(l, r) {
1598                    return Some(Ordering::Equal);
1599                }
1600                let l = l
1601                    .read()
1602                    .expect("PARTIAL_CMP L ERORR: could not acquire lock!");
1603
1604                let r = r
1605                    .read()
1606                    .expect("PARTIAL_CMP R ERORR: could not acquire lock!");
1607                l.partial_cmp(&r)
1608            }
1609            (Primitive::Ref(l), r) => {
1610                let l = l
1611                    .read()
1612                    .expect("PARTIAL_CMP L ERORR: could not acquire lock!");
1613
1614                l.partial_cmp(r)
1615            }
1616            (l, Primitive::Ref(r)) => {
1617                let r = r
1618                    .read()
1619                    .expect("PARTIAL_CMP R ERORR: could not acquire lock!");
1620
1621                l.partial_cmp(&r)
1622            }
1623
1624            (Primitive::U8(l), Primitive::U8(r)) => l.partial_cmp(r),
1625            (Primitive::U8(l), Primitive::I8(r)) => (*l as i8).partial_cmp(r),
1626            (Primitive::U8(l), Primitive::Int(r)) => {
1627                (*l as i128).partial_cmp(r)
1628            }
1629            (Primitive::U8(l), Primitive::Double(r)) => {
1630                (*l as f64).partial_cmp(r)
1631            }
1632
1633            (Primitive::I8(l), Primitive::U8(r)) => l.partial_cmp(&(*r as i8)),
1634            (Primitive::I8(l), Primitive::I8(r)) => (*l).partial_cmp(r),
1635            (Primitive::I8(l), Primitive::Int(r)) => {
1636                (*l as i128).partial_cmp(r)
1637            }
1638            (Primitive::I8(l), Primitive::Double(r)) => {
1639                (*l as f64).partial_cmp(r)
1640            }
1641
1642            (Primitive::Int(l), Primitive::Int(r)) => l.partial_cmp(r),
1643            (Primitive::Int(l), Primitive::U8(r)) => {
1644                l.partial_cmp(&(*r as i128))
1645            }
1646            (Primitive::Int(l), Primitive::I8(r)) => {
1647                l.partial_cmp(&(*r as i128))
1648            }
1649            (Primitive::Int(l), Primitive::Double(r)) => {
1650                (*l as f64).partial_cmp(r)
1651            }
1652
1653            (Primitive::Double(l), Primitive::Int(r)) => {
1654                l.partial_cmp(&(*r as f64))
1655            }
1656            (Primitive::Double(l), Primitive::U8(r)) => {
1657                l.partial_cmp(&(*r as f64))
1658            }
1659            (Primitive::Double(l), Primitive::I8(r)) => {
1660                l.partial_cmp(&(*r as f64))
1661            }
1662            (Primitive::Double(l), Primitive::Double(r)) => l.partial_cmp(r),
1663
1664            (Primitive::Bool(a), Primitive::Bool(b)) => a.partial_cmp(b),
1665            (l @ Primitive::Bool(_), r) => l.partial_cmp(&(r.to_bool())),
1666
1667            (Primitive::String(l), Primitive::String(r)) => l.partial_cmp(r),
1668            (Primitive::Unit, Primitive::Unit) => Some(Ordering::Equal),
1669            (Primitive::Array(l), Primitive::Array(r)) => l.partial_cmp(r),
1670            (
1671                Primitive::Function { parameters: pl, exprs: el },
1672                Primitive::Function { parameters: pr, exprs: er },
1673            ) => {
1674                if pl.eq(pr)
1675                    && el.iter().zip(er.iter()).filter(|&(a, b)| a != b).count()
1676                        == 0
1677                {
1678                    Some(Ordering::Equal)
1679                } else {
1680                    None
1681                }
1682            }
1683            (Primitive::Error(l), Primitive::Error(r)) => l.partial_cmp(r),
1684            (Primitive::Null, Primitive::Null) => Some(Ordering::Equal),
1685            (Primitive::EarlyReturn(l), Primitive::EarlyReturn(r)) => {
1686                l.partial_cmp(r)
1687            }
1688            (Primitive::EarlyReturn(l), a) => l.as_ref().partial_cmp(a),
1689            (l, Primitive::EarlyReturn(r)) => l.partial_cmp(r),
1690            (Primitive::Struct(l), Primitive::Struct(r)) => {
1691                if l.eq(r) {
1692                    Some(Ordering::Equal)
1693                } else {
1694                    None
1695                }
1696            }
1697            (Primitive::NativeLibrary { .. }, _)
1698            | (_, Primitive::NativeLibrary { .. }) => None,
1699            (Primitive::NativeFunction(_, _), _)
1700            | (_, Primitive::NativeFunction(_, _)) => None,
1701            (Primitive::Struct(_), _) => None,
1702            (Primitive::Int(_), _) => None,
1703            (Primitive::U8(_), _) => None,
1704            (Primitive::I8(_), _) => None,
1705            (Primitive::Double(_), _) => None,
1706            (Primitive::String(_), _) => None,
1707            (Primitive::NoReturn, _) => None,
1708            (Primitive::Null, _) => None,
1709            (Primitive::Array(_), _) => None,
1710            (Primitive::Error(_), _) => None,
1711            (Primitive::Unit, _) => None,
1712            (Primitive::Function { parameters: _, exprs: _ }, _) => None,
1713            (Primitive::LibData(_), _) => None,
1714        }
1715    }
1716}
1717
1718impl Round for Primitive {
1719    fn floor(&self) -> Self {
1720        match self {
1721            Primitive::Ref(l) => {
1722                let l = l.read().expect("FLOOR ERROR: could not acquire lock!");
1723                l.floor()
1724            }
1725
1726            Primitive::Int(i) => Primitive::Int(*i),
1727            Primitive::I8(i) => Primitive::I8(*i),
1728            Primitive::U8(i) => Primitive::U8(*i),
1729            Primitive::Double(d) => Primitive::Double(d.floor()),
1730
1731            r => Primitive::Error(format!("illegal call to floor!! {r}")),
1732        }
1733    }
1734
1735    fn ceil(&self) -> Self {
1736        match self {
1737            Primitive::Ref(l) => {
1738                let l = l.read().expect("CEIL ERROR: could not acquire lock!");
1739                l.floor()
1740            }
1741
1742            Primitive::Int(i) => Primitive::Int(*i),
1743            Primitive::I8(i) => Primitive::I8(*i),
1744            Primitive::U8(i) => Primitive::U8(*i),
1745            Primitive::Double(d) => Primitive::Double(d.ceil()),
1746
1747            r => Primitive::Error(format!("illegal call to ceil!! {r}")),
1748        }
1749    }
1750
1751    fn round(&self, decimals: &Self) -> Self {
1752        match (self, decimals) {
1753            (Primitive::Ref(s), decimals) => {
1754                let l = s.read().expect("ROUND ERROR: could not acquire lock!");
1755                l.round(decimals)
1756            }
1757            (l, Primitive::Ref(decimals)) => {
1758                let decimals = decimals
1759                    .read()
1760                    .expect("ROUND ERROR: could not acquire lock!");
1761                l.round(&decimals)
1762            }
1763            (v @ Primitive::Double(_), Primitive::U8(u)) => {
1764                v.round(&Primitive::Int(*u as i128))
1765            }
1766            (v @ Primitive::Double(_), Primitive::I8(u)) => {
1767                v.round(&Primitive::Int(*u as i128))
1768            }
1769            (Primitive::Double(x), Primitive::Int(u)) => {
1770                if u < &1 || u > &(u32::MAX as i128) {
1771                    return Primitive::Error(format!(
1772                        "illegal call to round!!  {u}"
1773                    ));
1774                }
1775                let decimals = *u as u32;
1776                let y = 10i32.pow(decimals) as f64;
1777                Primitive::Double((x * y).round() / y)
1778            }
1779            (p, r) => {
1780                Primitive::Error(format!("illegal call to round!!  {p} {r}"))
1781            }
1782        }
1783    }
1784}
1785impl StringManipulation for Primitive {
1786    fn match_regex(&self, regex: &Primitive) -> Self {
1787        match self {
1788            Primitive::Ref(l) => {
1789                let l = l.read().expect("MATCH ERROR: could not acquire lock!");
1790                l.match_regex(regex)
1791            }
1792            v @ Primitive::String(s) => match regex {
1793                Primitive::Ref(r) => {
1794                    let r =
1795                        r.read().expect("MATCH ERROR: could not acquire lock!");
1796                    v.match_regex(&r)
1797                }
1798                Primitive::String(r) => match regex::Regex::new(r) {
1799                    Ok(re) => {
1800                        let mut captures = vec![];
1801                        for cap in re.captures_iter(s) {
1802                            let len = cap.len();
1803                            let p = if len == 0 {
1804                                Primitive::Null
1805                            } else if len == 1 {
1806                                cap.get(0)
1807                                    .map(|c| {
1808                                        Primitive::String(
1809                                            c.as_str().to_string(),
1810                                        )
1811                                    })
1812                                    .unwrap_or(Primitive::Null)
1813                            } else {
1814                                Primitive::Array(
1815                                    cap.iter()
1816                                        .flatten()
1817                                        .map(|c| {
1818                                            Primitive::String(
1819                                                c.as_str().to_string(),
1820                                            )
1821                                        })
1822                                        .collect::<Vec<_>>(),
1823                                )
1824                            };
1825                            captures.push(p);
1826                        }
1827                        Primitive::Array(captures)
1828                    }
1829                    Err(e) => Primitive::Error(format!("regex error: {e}")),
1830                },
1831                r => Primitive::Error(format!("bad regex!  {r}")),
1832            },
1833            p => Primitive::Error(format!("illegal call to match!!  {p}")),
1834        }
1835    }
1836
1837    fn is_match(&self, regex: &Primitive) -> Self {
1838        match self {
1839            Primitive::Ref(l) => {
1840                let l =
1841                    l.read().expect("TYPE_OF ERROR: could not acquire lock!");
1842                l.is_match(regex)
1843            }
1844            v @ Primitive::String(s) => match regex {
1845                Primitive::Ref(r) => {
1846                    let r =
1847                        r.read().expect("MATCH ERROR: could not acquire lock!");
1848                    v.is_match(&r)
1849                }
1850                Primitive::String(r) => match regex::Regex::new(r) {
1851                    Ok(re) => Primitive::Bool(re.is_match(s)),
1852                    Err(e) => Primitive::Error(format!("regex error: {e}")),
1853                },
1854                r => Primitive::Error(format!("bad regex!  {r}")),
1855            },
1856            p => Primitive::Error(format!("illegal call to is_match!!  {p}")),
1857        }
1858    }
1859    fn replace(&self, regex: &Primitive, new_value: &Primitive) -> Self {
1860        match self {
1861            Primitive::Ref(l) => {
1862                let l =
1863                    l.read().expect("REPLACE ERROR: could not acquire lock!");
1864                l.match_regex(regex)
1865            }
1866            v @ Primitive::String(s) => match (regex, new_value) {
1867                (Primitive::Ref(regex), new_value) => {
1868                    let r = regex
1869                        .read()
1870                        .expect("REPLACE ERROR: could not acquire lock!");
1871                    v.replace(&r, new_value)
1872                }
1873                (regex, Primitive::Ref(new_value)) => {
1874                    let r = new_value
1875                        .read()
1876                        .expect("REPLACE ERROR: could not acquire lock!");
1877                    v.replace(regex, &r)
1878                }
1879                (Primitive::String(r), Primitive::String(new_value)) => {
1880                    match regex::Regex::new(r) {
1881                        Ok(re) => Primitive::String(
1882                            re.replace(s, new_value).to_string(),
1883                        ),
1884                        Err(e) => {
1885                            Primitive::Error(format!("replace error: {e}"))
1886                        }
1887                    }
1888                }
1889                (r, l) => {
1890                    Primitive::Error(format!("bad call to replace!  {r} {l}"))
1891                }
1892            },
1893            p => Primitive::Error(format!("illegal call to replace!!  {p}")),
1894        }
1895    }
1896    fn replace_all(&self, regex: &Primitive, new_value: &Primitive) -> Self {
1897        match self {
1898            Primitive::Ref(l) => {
1899                let l = l
1900                    .read()
1901                    .expect("REPLACE_ALL ERROR: could not acquire lock!");
1902                l.match_regex(regex)
1903            }
1904            v @ Primitive::String(s) => match (regex, new_value) {
1905                (Primitive::Ref(regex), new_value) => {
1906                    let r = regex
1907                        .read()
1908                        .expect("REPLACE_ALL ERROR: could not acquire lock!");
1909                    v.replace(&r, new_value)
1910                }
1911                (regex, Primitive::Ref(new_value)) => {
1912                    let r = new_value
1913                        .read()
1914                        .expect("REPLACE_ALL ERROR: could not acquire lock!");
1915                    v.replace(regex, &r)
1916                }
1917                (Primitive::String(r), Primitive::String(new_value)) => {
1918                    match regex::Regex::new(r) {
1919                        Ok(re) => Primitive::String(
1920                            re.replace_all(s, new_value).to_string(),
1921                        ),
1922                        Err(e) => {
1923                            Primitive::Error(format!("replace_all error: {e}"))
1924                        }
1925                    }
1926                }
1927                (r, l) => Primitive::Error(format!(
1928                    "bad call to replace_all!  {r} {l}"
1929                )),
1930            },
1931            p => {
1932                Primitive::Error(format!("illegal call to replace_all!!  {p}"))
1933            }
1934        }
1935    }
1936    fn to_upper(&self) -> Self {
1937        match self {
1938            Primitive::Ref(l) => {
1939                let l =
1940                    l.read().expect("TO_UPPER ERROR: could not acquire lock!");
1941                l.to_upper()
1942            }
1943            Primitive::String(s) => Primitive::String(s.to_uppercase()),
1944            p => Primitive::Error(format!("illegal call to to_upper!!  {p}")),
1945        }
1946    }
1947
1948    fn to_lower(&self) -> Self {
1949        match self {
1950            Primitive::Ref(l) => {
1951                let l =
1952                    l.read().expect("TO_LOWER ERROR: could not acquire lock!");
1953                l.to_upper()
1954            }
1955            Primitive::String(s) => Primitive::String(s.to_lowercase()),
1956            p => Primitive::Error(format!("illegal call to to_lower!!  {p}")),
1957        }
1958    }
1959
1960    fn capitalize(&self) -> Self {
1961        match self {
1962            Primitive::Ref(l) => {
1963                let l = l
1964                    .read()
1965                    .expect("CAPITALIZE ERROR: could not acquire lock!");
1966                l.to_upper()
1967            }
1968            Primitive::String(s) => {
1969                let mut c = s.chars();
1970                let new_s = match c.next() {
1971                    None => String::new(),
1972                    Some(f) => f.to_uppercase().chain(c).collect(),
1973                };
1974                Primitive::String(new_s)
1975            }
1976            p => Primitive::Error(format!("illegal call to capitalize!!  {p}")),
1977        }
1978    }
1979}
1980
1981impl TypeOf for Primitive {
1982    fn type_of_str(&self) -> &'static str {
1983        match self {
1984            Primitive::Ref(l) => {
1985                let l =
1986                    l.read().expect("TYPE_OF ERROR: could not acquire lock!");
1987                l.type_of_str()
1988            }
1989            Primitive::U8(_) => TYPE_U8,
1990            Primitive::I8(_) => TYPE_I8,
1991            Primitive::Int(_) => TYPE_INT,
1992            Primitive::Bool(_) => TYPE_BOOL,
1993            Primitive::Null => TYPE_NULL,
1994            Primitive::Double(_) => TYPE_DOUBLE,
1995            Primitive::String(_) => TYPE_STRING,
1996            Primitive::Array(_) => TYPE_ARRAY,
1997            Primitive::Error(_) => TYPE_ERROR,
1998            Primitive::NativeLibrary(_) => TYPE_NATIVE_LIB,
1999            Primitive::Function { .. } | Primitive::NativeFunction(_, _) => {
2000                TYPE_FUNCTION
2001            }
2002            Primitive::Struct(_) => TYPE_STRUCT,
2003            Primitive::Unit => TYPE_UNIT,
2004            Primitive::NoReturn => TYPE_NO_RETURN,
2005            Primitive::EarlyReturn(v) => v.type_of_str(),
2006            Primitive::LibData(_) => TYPE_LIB_DATA,
2007        }
2008    }
2009
2010    fn type_of(&self) -> Self {
2011        Primitive::String(self.type_of_str().to_string())
2012    }
2013}
2014
2015impl Array for Primitive {
2016    fn index_at(&self, rhs: &Primitive) -> Primitive {
2017        match (self, rhs) {
2018            (Primitive::Ref(l), Primitive::Ref(r)) => {
2019                let l = l
2020                    .read()
2021                    .expect("INDEX_AT L ERORR: could not acquire lock!");
2022
2023                let r = r
2024                    .read()
2025                    .expect("INDEX_AT R ERORR: could not acquire lock!");
2026                l.index_at(&r)
2027            }
2028            (Primitive::Ref(l), r) => {
2029                let l = l
2030                    .read()
2031                    .expect("INDEX_AT L ERORR: could not acquire lock!");
2032
2033                l.index_at(r)
2034            }
2035            (l, Primitive::Ref(r)) => {
2036                let r = r
2037                    .read()
2038                    .expect("INDEX_AT R ERORR: could not acquire lock!");
2039
2040                l.index_at(&r)
2041            }
2042            (Primitive::Array(arr), Primitive::Int(idx)) if idx >= &0 => {
2043                let idx = *idx as usize;
2044                if idx < arr.len() {
2045                    arr[idx].clone()
2046                } else {
2047                    Primitive::Error("index out of range".to_string())
2048                }
2049            }
2050            (Primitive::Array(arr), Primitive::U8(idx)) => {
2051                let idx = *idx as usize;
2052                if idx < arr.len() {
2053                    arr[idx].clone()
2054                } else {
2055                    Primitive::Error("index out of range".to_string())
2056                }
2057            }
2058            (Primitive::Array(arr), Primitive::I8(idx)) if idx >= &0 => {
2059                let idx = *idx as usize;
2060                if idx < arr.len() {
2061                    arr[idx].clone()
2062                } else {
2063                    Primitive::Error("index out of range".to_string())
2064                }
2065            }
2066            (Primitive::String(s), Primitive::Int(idx)) if idx >= &0 => {
2067                let idx = *idx as usize;
2068                if idx < s.len() {
2069                    let s: String = s.chars().skip(idx).take(1).collect();
2070                    Primitive::String(s)
2071                } else {
2072                    Primitive::Error("index out of range".to_string())
2073                }
2074            }
2075            (Primitive::String(s), Primitive::U8(idx)) => {
2076                let idx = *idx as usize;
2077                if idx < s.len() {
2078                    let s: String = s.chars().skip(idx).take(1).collect();
2079                    Primitive::String(s)
2080                } else {
2081                    Primitive::Error("index out of range".to_string())
2082                }
2083            }
2084            (Primitive::String(s), Primitive::I8(idx)) if idx >= &0 => {
2085                let idx = *idx as usize;
2086                if idx < s.len() {
2087                    let s: String = s.chars().skip(idx).take(1).collect();
2088                    Primitive::String(s)
2089                } else {
2090                    Primitive::Error("index out of range".to_string())
2091                }
2092            }
2093            (Primitive::Struct(struc), Primitive::String(key)) => {
2094                if let Some(p) = struc.get(key) {
2095                    p.clone()
2096                } else {
2097                    Primitive::Null
2098                }
2099            }
2100            (key, value) => Primitive::Error(format!(
2101                "illegal access to array!!!  {key} => {value}"
2102            )),
2103        }
2104    }
2105
2106    fn len(&self) -> Primitive {
2107        match self {
2108            Primitive::Ref(l) => {
2109                let l = l.read().expect("LEN ERROR: could not acquire lock!");
2110                l.len()
2111            }
2112            Primitive::String(s) => Primitive::Int(s.len() as i128),
2113            Primitive::Array(a) => Primitive::Int(a.len() as i128),
2114            Primitive::Struct(s) => Primitive::Int(s.len() as i128),
2115            _ => Primitive::Error(format!(
2116                "call to len() on a non array value => {self}"
2117            )),
2118        }
2119    }
2120
2121    fn swap_mem(
2122        &mut self,
2123        rhs: &mut Primitive,
2124        index: &Primitive,
2125    ) -> Primitive {
2126        match (self, index) {
2127            // FIXME this might be more complex than that
2128            // RHS could be equal to self
2129            // using Arc::ptr_eq(&arc1, &arc2) might be safer
2130            (Primitive::Ref(l), Primitive::Ref(r)) => {
2131                let mut l = l
2132                    .write()
2133                    .expect("SWAP_MEM L ERORR: could not acquire lock!");
2134
2135                let r = r
2136                    .read()
2137                    .expect("SWAP_MEM R ERORR: could not acquire lock!");
2138                l.swap_mem(rhs, &r)
2139            }
2140            (Primitive::Ref(l), _) => {
2141                let mut l = l
2142                    .write()
2143                    .expect("SWAP_MEM L ERORR: could not acquire lock!");
2144
2145                l.swap_mem(rhs, index)
2146            }
2147            (l, Primitive::Ref(index)) => {
2148                let index = index
2149                    .read()
2150                    .expect("SWAP_MEM R ERORR: could not acquire lock!");
2151
2152                l.swap_mem(rhs, &index)
2153            }
2154            (Primitive::Array(arr), Primitive::Int(idx)) if idx >= &0 => {
2155                let idx = *idx as usize;
2156                if !matches!(rhs, Primitive::Error(_) | Primitive::Unit)
2157                    && idx < arr.len()
2158                {
2159                    std::mem::swap(&mut arr[idx], rhs);
2160                    arr[idx].clone()
2161                } else {
2162                    Primitive::Error("index out of range".to_string())
2163                }
2164            }
2165
2166            (Primitive::Array(arr), Primitive::U8(idx)) => {
2167                let idx = *idx as usize;
2168                if !matches!(rhs, Primitive::Error(_) | Primitive::Unit)
2169                    && idx < arr.len()
2170                {
2171                    std::mem::swap(&mut arr[idx], rhs);
2172                    arr[idx].clone()
2173                } else {
2174                    Primitive::Error("index out of range".to_string())
2175                }
2176            }
2177            (Primitive::Array(arr), Primitive::I8(idx)) if idx >= &0 => {
2178                let idx = *idx as usize;
2179                if !matches!(rhs, Primitive::Error(_) | Primitive::Unit)
2180                    && idx < arr.len()
2181                {
2182                    std::mem::swap(&mut arr[idx], rhs);
2183                    arr[idx].clone()
2184                } else {
2185                    Primitive::Error("index out of range".to_string())
2186                }
2187            }
2188            (Primitive::Struct(s), Primitive::String(k)) => {
2189                if s.contains_key(k) {
2190                    std::mem::swap(s.get_mut(k).unwrap(), rhs);
2191                } else {
2192                    s.insert(k.clone(), rhs.clone());
2193                }
2194                s[k].clone()
2195            }
2196            (Primitive::String(s), Primitive::Int(idx)) if idx >= &0 => {
2197                let idx = *idx as usize;
2198                if !matches!(rhs, Primitive::Error(_) | Primitive::Unit)
2199                    && idx < s.len()
2200                {
2201                    s.remove(idx);
2202                    s.insert_str(idx, &rhs.to_string());
2203                    rhs.clone()
2204                } else {
2205                    Primitive::Error("index out of range".to_string())
2206                }
2207            }
2208            (Primitive::String(s), Primitive::I8(idx)) if idx >= &0 => {
2209                let idx = *idx as usize;
2210                if !matches!(rhs, Primitive::Error(_) | Primitive::Unit)
2211                    && idx < s.len()
2212                {
2213                    s.remove(idx);
2214                    s.insert_str(idx, &rhs.to_string());
2215                    rhs.clone()
2216                } else {
2217                    Primitive::Error("index out of range".to_string())
2218                }
2219            }
2220            (Primitive::String(s), Primitive::U8(idx)) => {
2221                let idx = *idx as usize;
2222                if !matches!(rhs, Primitive::Error(_) | Primitive::Unit)
2223                    && idx < s.len()
2224                {
2225                    s.remove(idx);
2226                    s.insert_str(idx, &rhs.to_string());
2227                    rhs.clone()
2228                } else {
2229                    Primitive::Error("index out of range".to_string())
2230                }
2231            }
2232            _ => Primitive::Error("invalid call to swap_mem()".to_string()),
2233        }
2234    }
2235
2236    fn remove(&mut self, key: &Primitive) -> anyhow::Result<()> {
2237        match (self, key) {
2238            // FIXME this might be more complex than that
2239            // RHS could be equal to self
2240            // using Arc::ptr_eq(&arc1, &arc2) might be safer
2241            (Primitive::Ref(l), Primitive::Ref(r)) => {
2242                let mut l =
2243                    l.write().expect("REMOVE L ERORR: could not acquire lock!");
2244
2245                let r =
2246                    r.read().expect("REMOVE R ERORR: could not acquire lock!");
2247                l.remove(&r)
2248            }
2249            (Primitive::Ref(l), _) => {
2250                let mut l =
2251                    l.write().expect("REMOVE L ERORR: could not acquire lock!");
2252
2253                l.remove(key)
2254            }
2255            (l, Primitive::Ref(index)) => {
2256                let index = index
2257                    .read()
2258                    .expect("REMOVE R ERORR: could not acquire lock!");
2259
2260                l.remove(&index)
2261            }
2262            (Primitive::Array(arr), Primitive::Int(idx)) if idx >= &0 => {
2263                let idx = *idx as usize;
2264                if idx < arr.len() {
2265                    arr.remove(idx);
2266                    Ok(())
2267                } else {
2268                    Err(anyhow::Error::msg("index out of range"))
2269                }
2270            }
2271            (Primitive::Array(arr), Primitive::U8(idx)) => {
2272                let idx = *idx as usize;
2273                if idx < arr.len() {
2274                    arr.remove(idx);
2275                    Ok(())
2276                } else {
2277                    Err(anyhow::Error::msg("index out of range"))
2278                }
2279            }
2280            (Primitive::Array(arr), Primitive::I8(idx)) if idx >= &0 => {
2281                let idx = *idx as usize;
2282                if idx < arr.len() {
2283                    arr.remove(idx);
2284                    Ok(())
2285                } else {
2286                    Err(anyhow::Error::msg("index out of range"))
2287                }
2288            }
2289
2290            (Primitive::String(s), Primitive::U8(idx)) => {
2291                let idx = *idx as usize;
2292                if idx < s.len() {
2293                    s.remove(idx);
2294                    Ok(())
2295                } else {
2296                    Err(anyhow::Error::msg("index out of range"))
2297                }
2298            }
2299            (Primitive::String(s), Primitive::I8(idx)) if idx >= &0 => {
2300                let idx = *idx as usize;
2301                if idx < s.len() {
2302                    s.remove(idx);
2303                    Ok(())
2304                } else {
2305                    Err(anyhow::Error::msg("index out of range"))
2306                }
2307            }
2308            (Primitive::String(s), Primitive::Int(idx)) if idx >= &0 => {
2309                let idx = *idx as usize;
2310                if idx < s.len() {
2311                    s.remove(idx);
2312                    Ok(())
2313                } else {
2314                    Err(anyhow::Error::msg("index out of range"))
2315                }
2316            }
2317            (Primitive::Struct(struc), Primitive::String(key)) => {
2318                match struc.remove(key) {
2319                    Some(_p) => Ok(()),
2320                    _ => Err(anyhow::Error::msg("key doesn't exist")),
2321                }
2322            }
2323            _ => Err(anyhow::Error::msg("illegal access to array!!!")),
2324        }
2325    }
2326
2327    fn is_empty(&self) -> Primitive {
2328        match self.len() {
2329            Primitive::Int(n) => Primitive::Bool(n == 0),
2330            e => Primitive::Error(format!("err: {e}")),
2331        }
2332    }
2333}
2334impl PartialEq for Primitive {
2335    fn eq(&self, other: &Self) -> bool {
2336        match (self, other) {
2337            (Self::Ref(l0), Self::Ref(r0)) => {
2338                if Arc::ptr_eq(l0, r0) {
2339                    return true;
2340                }
2341
2342                let l0 =
2343                    l0.read().expect("EQ L ERORR: could not acquire lock!");
2344
2345                let r = r0.read().expect("EQ R ERORR: could not acquire lock!");
2346                l0.eq(&r)
2347            }
2348            (Primitive::Ref(l), _) => {
2349                let l = l.read().expect("EQ L ERORR: could not acquire lock!");
2350                l.eq(other)
2351            }
2352            (_, Primitive::Ref(r)) => {
2353                let r = r.read().expect("EQ R ERORR: could not acquire lock!");
2354                self.eq(&r)
2355            }
2356            (Self::U8(l0), Self::U8(r0)) => l0 == r0,
2357            (Self::I8(l0), Self::I8(r0)) => l0 == r0,
2358            (Self::Int(l0), Self::Int(r0)) => l0 == r0,
2359            (Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
2360            (Self::Double(l0), Self::Double(r0)) => l0 == r0,
2361            (Self::String(l0), Self::String(r0)) => l0 == r0,
2362            (Self::Array(l0), Self::Array(r0)) => l0 == r0,
2363            (Self::Struct(l0), Self::Struct(r0)) => l0 == r0,
2364            (Self::Error(l0), Self::Error(r0)) => l0 == r0,
2365            (
2366                Self::Function { parameters: l_parameters, exprs: l_exprs },
2367                Self::Function { parameters: r_parameters, exprs: r_exprs },
2368            ) => l_parameters == r_parameters && l_exprs == r_exprs,
2369            (Self::EarlyReturn(l0), Self::EarlyReturn(r0)) => l0 == r0,
2370            _ => {
2371                core::mem::discriminant(self) == core::mem::discriminant(other)
2372            }
2373        }
2374    }
2375}
2376impl DisplayHex for Primitive {
2377    fn to_hex(&self) -> Self {
2378        match self {
2379            Primitive::U8(u) => Primitive::String(format!("{u:#x}")),
2380            Primitive::I8(u) => Primitive::String(format!("{u:#x}")),
2381            Primitive::Int(u) => Primitive::String(format!("{u:#x}")),
2382
2383            Primitive::Ref(l0) => {
2384                let l0 =
2385                    l0.read().expect("EQ L ERORR: could not acquire lock!");
2386                l0.to_hex()
2387            }
2388            Primitive::Double(d) => {
2389                let bytes = d.to_ne_bytes();
2390                let u = i64::from_ne_bytes(bytes);
2391                Primitive::String(format!("{u:#x}"))
2392            }
2393
2394            e => Primitive::Error(format!("could not convert to_hex: {e}")),
2395        }
2396    }
2397}
2398impl DisplayBinary for Primitive {
2399    fn to_binary(&self) -> Self {
2400        match self {
2401            Primitive::U8(u) => Primitive::String(format!("{u:#b}")),
2402            Primitive::I8(u) => Primitive::String(format!("{u:#b}")),
2403            Primitive::Int(u) => Primitive::String(format!("{u:#b}")),
2404
2405            Primitive::Ref(l0) => {
2406                let l0 =
2407                    l0.read().expect("EQ L ERORR: could not acquire lock!");
2408                l0.to_hex()
2409            }
2410            Primitive::Double(d) => {
2411                let bytes = d.to_ne_bytes();
2412                let u = i64::from_ne_bytes(bytes);
2413                Primitive::String(format!("{u:#b}"))
2414            }
2415
2416            e => Primitive::Error(format!("could not convert to_binary: {e}")),
2417        }
2418    }
2419}
2420// endregion
2421
2422#[cfg(test)]
2423mod test {
2424    use super::Add;
2425
2426    use super::Primitive;
2427
2428    #[test]
2429    fn test_add_valid() {
2430        let l = Primitive::Int(1);
2431        let r = Primitive::Int(2);
2432        assert_eq!(l.add(&r), Primitive::Int(3));
2433
2434        let l = Primitive::Int(1);
2435        let r = Primitive::Double(2.);
2436        assert_eq!(l.add(&r), Primitive::Double(3.));
2437
2438        let l = Primitive::Double(1.);
2439        let r = Primitive::Int(2);
2440        assert_eq!(l.add(&r), Primitive::Double(3.));
2441
2442        let l = Primitive::Double(1.);
2443        let r = Primitive::Double(2.);
2444        assert_eq!(l.add(&r), Primitive::Double(3.));
2445    }
2446}