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 #[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 #[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 #[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
159impl 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 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#[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 (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 (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#[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}