1use std::borrow::{Borrow, Cow};
2use std::fmt;
3use std::fmt::{Debug, Display, Formatter};
4use std::ops::{Add, Sub};
5
6use cpclib_common::itertools::Itertools;
7use cpclib_common::smol_str::SmolStr;
8use ordered_float::OrderedFloat;
9
10use crate::ListingElement;
11use crate::tokens::Token;
12
13#[derive(Debug, PartialEq, Eq, Clone, Hash)]
15#[allow(missing_docs)]
16pub enum Expr {
17 RelativeDelta(i8),
19
20 Value(i32),
22 Float(OrderedFloat<f64>),
24 Char(char),
26 Bool(bool),
28 String(SmolStr),
30 Label(SmolStr),
32 List(Vec<Expr>),
34
35 PrefixedLabel(LabelPrefix, SmolStr),
37
38 Paren(Box<Expr>),
39
40 UnaryFunction(UnaryFunction, Box<Expr>),
41 UnaryOperation(UnaryOperation, Box<Expr>),
42 UnaryTokenOperation(UnaryTokenOperation, Box<Token>),
43 BinaryFunction(BinaryFunction, Box<Expr>, Box<Expr>),
44 BinaryOperation(BinaryOperation, Box<Expr>, Box<Expr>),
45
46 AnyFunction(SmolStr, Vec<Expr>),
48
49 Rnd
51}
52
53impl From<Expr> for Cow<'_, Expr> {
54 fn from(val: Expr) -> Self {
55 Cow::Owned(val)
56 }
57}
58
59impl<'e> From<&'e Expr> for Cow<'e, Expr> {
60 fn from(val: &'e Expr) -> Self {
61 Cow::Borrowed(val)
62 }
63}
64
65pub trait ExprElement: Sized {
67 type ResultExpr: ExprElement;
68 type Token: ListingElement;
69
70 fn is_label_value(&self, label: &str) -> bool {
71 self.is_label() && self.label() == label
72 }
73
74 fn is_negated(&self) -> bool;
75
76 fn is_relative(&self) -> bool;
77 fn relative_delta(&self) -> i8;
78
79 fn is_value(&self) -> bool;
80 fn value(&self) -> i32;
81
82 fn is_char(&self) -> bool;
83 fn char(&self) -> char;
84
85 fn is_bool(&self) -> bool;
86 fn bool(&self) -> bool;
87
88 fn is_string(&self) -> bool;
89 fn string(&self) -> &str;
90
91 fn is_float(&self) -> bool;
92 fn float(&self) -> OrderedFloat<f64>;
93
94 fn is_list(&self) -> bool;
95 fn list(&self) -> &[Self];
96
97 fn is_label(&self) -> bool;
98 fn label(&self) -> &str;
99
100 fn is_token_operation(&self) -> bool;
101 fn token_operation(&self) -> &UnaryTokenOperation;
102 fn token(&self) -> &Self::Token;
103
104 fn is_prefix_label(&self) -> bool;
105 fn prefix(&self) -> &LabelPrefix;
106
107 fn is_binary_operation(&self) -> bool;
108 fn binary_operation(&self) -> BinaryOperation;
109
110 fn is_unary_operation(&self) -> bool;
111 fn unary_operation(&self) -> UnaryOperation;
112
113 fn is_unary_function(&self) -> bool;
114 fn unary_function(&self) -> UnaryFunction;
115
116 fn is_binary_function(&self) -> bool;
117 fn binary_function(&self) -> BinaryFunction;
118
119 fn is_paren(&self) -> bool;
120
121 fn is_rnd(&self) -> bool;
122
123 fn is_any_function(&self) -> bool;
124 fn function_name(&self) -> &str;
125 fn function_args(&self) -> &[Self];
126
127 fn arg1(&self) -> &Self;
128 fn arg2(&self) -> &Self;
129
130 fn neg(&self) -> Self::ResultExpr;
131 fn not(&self) -> Self::ResultExpr;
132 fn add<E: Into<Self::ResultExpr>>(&self, v: E) -> Self::ResultExpr;
133
134 fn is_context_independant(&self) -> bool;
135 fn fix_relative_value(&mut self);
136
137 fn to_expr(&self) -> Cow<Expr>;
138}
139
140#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
141pub enum LabelPrefix {
143 Bank,
145 Page,
147 Pageset
149}
150
151impl Display for LabelPrefix {
152 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
153 let repr: &'static str = match self {
154 Self::Bank => "{bank}",
155 Self::Page => "{page}",
156 Self::Pageset => "{pageset}"
157 };
158 write!(format, "{repr}")
159 }
160}
161
162#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
177pub enum ExprFormat {
178 Hex(Option<u8>),
179 Bin(Option<u8>),
180 Int
181}
182
183impl Display for ExprFormat {
184 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
185 let repr: &'static str = match self {
186 Self::Hex(None) => "{hex}",
187 Self::Bin(None) => "{bin}",
188
189 Self::Int => "{int}",
190
191 Self::Hex(Some(2)) => "{hex2}",
192 Self::Hex(Some(4)) => "{hex4}",
193 Self::Hex(Some(8)) => "{hex8}",
194
195 Self::Bin(Some(8)) => "{bin8}",
196 Self::Bin(Some(16)) => "{bin16}",
197 Self::Bin(Some(32)) => "{bin32}",
198
199 _ => unreachable!()
200 };
201 write!(format, "{repr}")
202 }
203}
204
205impl ExprFormat {
206 pub fn string_representation(&self, val: i32) -> String {
208 match self {
209 Self::Hex(None) => format!("0x{val:x}"),
210 Self::Bin(None) => format!("0b{val:b}"),
211
212 Self::Int => format!("{val}"),
213
214 Self::Hex(Some(2)) => format!("0x{val:0>2x}"),
215 Self::Hex(Some(4)) => format!("0x{val:0>4x}"),
216 Self::Hex(Some(8)) => format!("0x{val:0>8x}"),
217
218 Self::Bin(Some(8)) => format!("0b{val:0>8b}"),
219 Self::Bin(Some(16)) => format!("0b{val:0>16b}"),
220 Self::Bin(Some(32)) => format!("0b{val:0>32b}"),
221
222 _ => unreachable!()
223 }
224 }
225}
226
227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229pub enum FormattedExpr {
230 Raw(Expr),
232 Formatted(ExprFormat, Expr)
234}
235
236impl FormattedExpr {
237 }
243
244impl Display for FormattedExpr {
245 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
246 match self {
247 Self::Raw(expr) => write!(formatter, "{expr}"),
248 Self::Formatted(format, expr) => write!(formatter, "{format}{expr}")
249 }
250 }
251}
252
253impl From<Expr> for FormattedExpr {
254 fn from(e: Expr) -> Self {
255 Self::Raw(e)
256 }
257}
258
259#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
261pub enum UnaryFunction {
262 High,
264 Low,
266 Memory,
268 Char,
269 Floor,
270 Ceil,
271 Frac,
272 Int,
273 Sin,
274 Cos,
275 ASin,
276 ACos,
277 Abs,
278 Ln,
279 Log10,
280 Exp,
281 Sqrt
282}
283
284impl Display for UnaryFunction {
285 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
286 let repr = match self {
288 UnaryFunction::High => "high",
289 UnaryFunction::Low => "low",
290 UnaryFunction::Memory => "memory",
291 UnaryFunction::Floor => "floor",
292 UnaryFunction::Ceil => "ceil",
293 UnaryFunction::Frac => "frac",
294 UnaryFunction::Int => "int",
295 UnaryFunction::Char => "char",
296 UnaryFunction::Sin => "sin",
297 UnaryFunction::Cos => "cos",
298 UnaryFunction::ASin => "asin",
299 UnaryFunction::ACos => "acos",
300 UnaryFunction::Abs => "abs",
301 UnaryFunction::Ln => "ln",
302 UnaryFunction::Log10 => "log10",
303 UnaryFunction::Exp => "exp",
304 UnaryFunction::Sqrt => "sqrt"
305 };
306 write!(format, "{repr}")
307 }
308}
309
310#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
311pub enum UnaryOperation {
312 Neg,
313 Not,
314 BinaryNot
315}
316
317impl Display for UnaryOperation {
318 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
319 let repr = match self {
320 UnaryOperation::Neg => "-",
321 UnaryOperation::Not => "!",
322 UnaryOperation::BinaryNot => "~"
323 };
324 write!(format, "{repr}")
325 }
326}
327
328impl Display for BinaryFunction {
329 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
330 let repr = match self {
331 BinaryFunction::Min => "min",
332 BinaryFunction::Max => "max",
333 BinaryFunction::Pow => "pow"
334 };
335 write!(format, "{repr}")
336 }
337}
338
339#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
340pub enum UnaryTokenOperation {
341 Duration,
342 Opcode
343}
344
345impl Display for UnaryTokenOperation {
346 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
347 let repr = match self {
348 UnaryTokenOperation::Duration => "DURATION",
349 UnaryTokenOperation::Opcode => "OPCODE"
350 };
351 write!(format, "{repr}")
352 }
353}
354
355#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
356pub enum BinaryOperation {
357 RightShift,
358 LeftShift,
359
360 Add,
361 Sub,
362 Mul,
363 Div,
364 Mod,
365
366 BinaryAnd,
367 BinaryOr,
368 BinaryXor,
369
370 BooleanAnd,
371 BooleanOr,
372
373 Equal,
374 Different,
375 LowerOrEqual,
376 GreaterOrEqual,
377 StrictlyGreater,
378 StrictlyLower
379}
380
381impl Display for BinaryOperation {
382 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
383 use BinaryOperation::*;
384 let repr = match self {
385 RightShift => ">>",
386 LeftShift => "<<",
387
388 Add => "+",
389 Sub => "-",
390 Mul => "*",
391 Div => "/",
392 Mod => "%",
393
394 BinaryAnd => "&",
395 BinaryOr => "|",
396 BinaryXor => "^",
397
398 BooleanAnd => "&&",
399 BooleanOr => "||",
400
401 Equal => "==",
402 Different => "!=",
403 LowerOrEqual => "<=",
404 GreaterOrEqual => ">=",
405 StrictlyGreater => ">",
406 StrictlyLower => "<"
407 };
408 write!(format, "{repr}")
409 }
410}
411
412#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
414pub enum BinaryFunction {
415 Min,
416 Max,
417 Pow
418}
419
420impl From<&str> for Expr {
421 fn from(src: &str) -> Self {
422 Expr::Label(src.into())
423 }
424}
425
426macro_rules! convert_number_to_expr {
428 ( $($i:ty)* ) => {
429 $(
430 #[allow(trivial_numeric_casts)]
431 impl From<$i> for Expr {
432 fn from(src: $i) -> Self {
433 Expr::Value(src as _)
434 }
435 }
436 )*
437 };
438 }
439
440convert_number_to_expr!(i32 i16 i8 u8 u16 u32 usize);
441
442#[allow(missing_docs)]
443impl ExprElement for Expr {
444 type ResultExpr = Expr;
445 type Token = Token;
446
447 fn to_expr(&self) -> Cow<Expr> {
448 Cow::Borrowed(self)
449 }
450
451 fn is_negated(&self) -> bool {
452 match self {
453 Expr::UnaryOperation(UnaryOperation::Neg, _) => true,
454 _ => false
455 }
456 }
457
458 fn is_relative(&self) -> bool {
459 match self {
460 Expr::RelativeDelta(_) => true,
461 _ => false
462 }
463 }
464
465 fn relative_delta(&self) -> i8 {
466 match self {
467 Expr::RelativeDelta(val) => *val,
468 _ => unreachable!()
469 }
470 }
471
472 fn neg(&self) -> Self {
473 Expr::UnaryOperation(UnaryOperation::Neg, Box::new(self.clone()))
474 }
475
476 fn add<E: Into<Expr>>(&self, v: E) -> Self {
477 Expr::BinaryOperation(
478 BinaryOperation::Add,
479 Box::new(self.clone()),
480 v.into().into()
481 )
482 }
483
484 fn is_context_independant(&self) -> bool {
486 use self::Expr::*;
487 match *self {
488 Label(_) => false,
489 _ => true
490 }
491 }
492
493 fn fix_relative_value(&mut self) {
495 panic!("i am planning to remove this code, it should not be called");
496 if let Expr::Value(val) = self {
497 let mut new_expr = Expr::RelativeDelta(*val as i8);
498 std::mem::swap(self, &mut new_expr);
499 }
500 }
501
502 fn not(&self) -> Self::ResultExpr {
503 todo!()
504 }
505
506 fn is_value(&self) -> bool {
507 match self {
508 Self::Value(_) => true,
509 _ => false
510 }
511 }
512
513 fn value(&self) -> i32 {
514 match self {
515 Self::Value(v) => *v,
516 _ => unreachable!()
517 }
518 }
519
520 fn is_char(&self) -> bool {
521 match self {
522 Self::Char(_) => true,
523 _ => false
524 }
525 }
526
527 fn char(&self) -> char {
528 match self {
529 Self::Char(v) => *v,
530 _ => unreachable!()
531 }
532 }
533
534 fn is_bool(&self) -> bool {
535 match self {
536 Self::Bool(_) => true,
537 _ => false
538 }
539 }
540
541 fn bool(&self) -> bool {
542 match self {
543 Self::Bool(v) => *v,
544 _ => unreachable!()
545 }
546 }
547
548 fn is_string(&self) -> bool {
549 match self {
550 Self::String(_) => true,
551 _ => false
552 }
553 }
554
555 fn string(&self) -> &str {
556 match self {
557 Self::String(v) => v.as_str(),
558 _ => unreachable!()
559 }
560 }
561
562 fn is_float(&self) -> bool {
563 match self {
564 Self::Float(_) => true,
565 _ => false
566 }
567 }
568
569 fn float(&self) -> OrderedFloat<f64> {
570 match self {
571 Self::Float(v) => *v,
572 _ => unreachable!()
573 }
574 }
575
576 fn is_list(&self) -> bool {
577 match self {
578 Self::List(_) => true,
579 _ => false
580 }
581 }
582
583 fn list(&self) -> &[Self] {
584 match self {
585 Self::List(v) => v.as_slice(),
586 _ => unreachable!()
587 }
588 }
589
590 fn is_label(&self) -> bool {
591 match self {
592 Self::Label(_) => true,
593 _ => false
594 }
595 }
596
597 fn label(&self) -> &str {
598 match self {
599 Self::Label(v) => v.as_str(),
600 Self::PrefixedLabel(_, v) => v.as_str(),
601 _ => unreachable!()
602 }
603 }
604
605 fn is_token_operation(&self) -> bool {
606 match self {
607 Self::UnaryTokenOperation(..) => true,
608 _ => false
609 }
610 }
611
612 fn token_operation(&self) -> &UnaryTokenOperation {
613 match self {
614 Self::UnaryTokenOperation(op, _) => op,
615 _ => unreachable!()
616 }
617 }
618
619 fn token(&self) -> &Self::Token {
620 match self {
621 Self::UnaryTokenOperation(_, box token) => token,
622 _ => unreachable!()
623 }
624 }
625
626 fn is_prefix_label(&self) -> bool {
627 match self {
628 Self::PrefixedLabel(..) => true,
629 _ => false
630 }
631 }
632
633 fn prefix(&self) -> &LabelPrefix {
634 match self {
635 Self::PrefixedLabel(prefix, _) => prefix,
636 _ => unreachable!()
637 }
638 }
639
640 fn is_binary_operation(&self) -> bool {
641 match self {
642 Self::BinaryOperation(..) => true,
643 _ => false
644 }
645 }
646
647 fn binary_operation(&self) -> BinaryOperation {
648 match self {
649 Self::BinaryOperation(op, ..) => *op,
650 _ => unreachable!()
651 }
652 }
653
654 fn is_unary_operation(&self) -> bool {
655 match self {
656 Self::UnaryOperation(..) => true,
657 _ => false
658 }
659 }
660
661 fn unary_operation(&self) -> UnaryOperation {
662 match self {
663 Self::UnaryOperation(op, _) => *op,
664 _ => unreachable!()
665 }
666 }
667
668 fn is_unary_function(&self) -> bool {
669 match self {
670 Self::UnaryFunction(..) => true,
671 _ => false
672 }
673 }
674
675 fn unary_function(&self) -> UnaryFunction {
676 match self {
677 Self::UnaryFunction(f, _) => *f,
678 _ => unreachable!()
679 }
680 }
681
682 fn is_binary_function(&self) -> bool {
683 match self {
684 Self::BinaryFunction(..) => true,
685 _ => false
686 }
687 }
688
689 fn binary_function(&self) -> BinaryFunction {
690 match self {
691 Self::BinaryFunction(f, ..) => *f,
692 _ => unreachable!()
693 }
694 }
695
696 fn is_paren(&self) -> bool {
697 match self {
698 Self::Paren(..) => true,
699 _ => false
700 }
701 }
702
703 fn is_rnd(&self) -> bool {
704 match self {
705 Self::Rnd => true,
706 _ => false
707 }
708 }
709
710 fn is_any_function(&self) -> bool {
711 match self {
712 Self::AnyFunction(..) => true,
713 _ => false
714 }
715 }
716
717 fn function_name(&self) -> &str {
718 match self {
719 Self::AnyFunction(n, _) => n.as_str(),
720 Self::UnaryFunction(_f, _) => todo!(),
721 Self::BinaryFunction(_f, ..) => todo!(),
722 _ => unreachable!()
723 }
724 }
725
726 fn function_args(&self) -> &[Self] {
727 match self {
728 Self::AnyFunction(_, args) => args.as_slice(),
729 _ => unreachable!()
730 }
731 }
732
733 fn arg1(&self) -> &Self {
734 match self {
735 Self::BinaryOperation(_, box arg1, _) => arg1,
736 Self::UnaryOperation(_, box arg) => arg,
737 Self::UnaryFunction(_, box arg) => arg,
738 Self::BinaryFunction(_, box arg1, _) => arg1,
739 Self::Paren(box p) => p,
740
741 _ => unreachable!()
742 }
743 }
744
745 fn arg2(&self) -> &Self {
746 match self {
747 Self::BinaryOperation(_, _, box arg2) => arg2,
748 Self::BinaryFunction(_, _, box arg2) => arg2,
749
750 _ => unreachable!()
751 }
752 }
753}
754
755impl Expr {
756 pub fn to_simplified_string(&self) -> String {
757 let exp = self.to_string();
758 let exp = exp.trim();
759
760 let exp = if exp.starts_with('(') && exp.ends_with(')') {
761 let exp = exp.strip_prefix('(').unwrap_or(exp);
762
763 exp.strip_suffix(')').unwrap_or(exp)
764 }
765 else {
766 exp
767 };
768
769 exp.to_owned()
770 }
771}
772impl Display for Expr {
773 fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
774 use self::Expr::*;
775 match self {
776 Rnd => write!(format, "RND()"),
777 RelativeDelta(delta) => write!(format, "$ + {delta} + 2"),
779
780 Value(val) => write!(format, "0x{val:x}"),
781 Float(val) => write!(format, "{val}"),
782 Char(c) => write!(format, "'{c}'"),
783 Bool(b) => write!(format, "{}", if *b { "true" } else { "false" }),
784 String(string) => write!(format, "\"{string}\""),
785 List(l) => write!(format, "[{}]", l.iter().map(|e| e.to_string()).join(",")),
786 Label(label) => write!(format, "{label}"),
787 PrefixedLabel(prefix, label) => write!(format, "{prefix}{label}"),
788
789 UnaryFunction(func, arg) => write!(format, "{func}({arg})"),
790
791 BinaryFunction(func, arg1, arg2) => write!(format, "{func}({arg1}, {arg2})"),
792
793 Paren(expr) => write!(format, "({expr})"),
794
795 AnyFunction(name, args) => {
796 write!(
797 format,
798 "{}({})",
799 name,
800 args.iter().map(|e| e.to_string()).join(",")
801 )
802 },
803
804 UnaryOperation(op, exp) => write!(format, "{op}{exp}"),
805 UnaryTokenOperation(op, tok) => write!(format, "{op}({tok})"),
806 BinaryOperation(op, exp1, exp2) => write!(format, "({exp1} {op} {exp2})")
807 }
808 }
809}
810
811impl Expr {
847 pub fn do_apply_macro_labels_modification(s: &mut std::string::String, seed: usize) {
890 assert!(!s.is_empty());
891 if s.starts_with('@') {
892 let mut new = format!("__macro__{seed}__{s}");
893 std::mem::swap(&mut new, s);
894 }
895 }
896
897 pub fn neg(self) -> Self {
898 Expr::UnaryOperation(UnaryOperation::Neg, Box::new(self))
899 }
900}
901
902#[derive(Debug, Clone, PartialEq, Eq)]
903pub struct ExpressionTypeError(String);
904
905impl Display for ExpressionTypeError {
906 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
907 write!(f, "{}", &self.0)
908 }
909}
910
911#[derive(Eq, Ord, Debug, Clone)]
914pub enum ExprResult {
915 Float(OrderedFloat<f64>),
916 Value(i32),
917 Char(u8),
918 Bool(bool),
919 String(SmolStr),
920 List(Vec<ExprResult>),
921 Matrix {
922 width: usize,
923 height: usize,
924 content: Vec<ExprResult>
925 }
926}
927
928impl From<String> for ExprResult {
929 fn from(f: String) -> Self {
930 ExprResult::String(f.into())
931 }
932}
933
934impl From<&SmolStr> for ExprResult {
935 fn from(f: &SmolStr) -> Self {
936 ExprResult::String(f.clone())
937 }
938}
939
940impl From<SmolStr> for ExprResult {
941 fn from(f: SmolStr) -> Self {
942 ExprResult::String(f)
943 }
944}
945
946impl From<f64> for ExprResult {
947 fn from(f: f64) -> Self {
948 ExprResult::Float(f.into())
949 }
950}
951
952impl From<bool> for ExprResult {
953 fn from(b: bool) -> Self {
954 ExprResult::Bool(b)
955 }
956}
957
958impl From<OrderedFloat<f64>> for ExprResult {
959 fn from(f: OrderedFloat<f64>) -> Self {
960 ExprResult::Float(f)
961 }
962}
963
964impl From<usize> for ExprResult {
965 fn from(i: usize) -> Self {
966 ExprResult::Value(i as _)
967 }
968}
969
970impl From<i32> for ExprResult {
971 fn from(i: i32) -> Self {
972 ExprResult::Value(i)
973 }
974}
975
976impl From<u16> for ExprResult {
977 fn from(i: u16) -> Self {
978 ExprResult::Value(i as _)
979 }
980}
981
982impl From<u8> for ExprResult {
983 fn from(i: u8) -> Self {
984 ExprResult::Value(i as _)
985 }
986}
987
988impl From<i8> for ExprResult {
989 fn from(i: i8) -> Self {
990 ExprResult::Value(i as _)
991 }
992}
993impl From<char> for ExprResult {
994 fn from(i: char) -> Self {
995 ExprResult::Char(i as _)
996 }
997}
998
999impl<T: Into<ExprResult> + Clone> From<&[T]> for ExprResult {
1000 fn from(slice: &[T]) -> Self {
1001 ExprResult::List(slice.iter().cloned().map(|e| e.into()).collect_vec())
1002 }
1003}
1004
1005impl ExprResult {
1006 pub fn is_float(&self) -> bool {
1007 match self {
1008 Self::Float(_) => true,
1009 _ => false
1010 }
1011 }
1012
1013 pub fn is_int(&self) -> bool {
1014 match self {
1015 Self::Value(_) => true,
1016 _ => false
1017 }
1018 }
1019
1020 pub fn is_char(&self) -> bool {
1021 match self {
1022 Self::Char(_) => true,
1023 _ => false
1024 }
1025 }
1026
1027 pub fn is_string(&self) -> bool {
1028 match self {
1029 Self::String(_) => true,
1030 _ => false
1031 }
1032 }
1033
1034 pub fn as_type(&self, other: &Self) -> Result<Self, ExpressionTypeError> {
1035 if other.is_char() {
1036 self.char().map(|e| e.into())
1037 }
1038 else if other.is_float() {
1039 self.float().map(|e| e.into())
1040 }
1041 else if other.is_int() {
1042 self.int().map(|e| e.into())
1043 }
1044 else {
1045 unimplemented!();
1046 }
1047 }
1048
1049 pub fn string(&self) -> Result<&str, ExpressionTypeError> {
1050 match self {
1051 ExprResult::String(s) => Ok(s.borrow()),
1052 _ => {
1053 Err(ExpressionTypeError(format!(
1054 "Try to convert {self} as an string"
1055 )))
1056 },
1057 }
1058 }
1059
1060 pub fn int(&self) -> Result<i32, ExpressionTypeError> {
1061 match self {
1062 ExprResult::Float(f) => Ok((f.into_inner() + 0.5).floor() as _), ExprResult::Value(i) => Ok(*i),
1064 ExprResult::Char(i) => Ok(*i as i32),
1065 ExprResult::Bool(b) => Ok(if *b { 1 } else { 0 }),
1066 _ => {
1067 Err(ExpressionTypeError(format!(
1068 "Try to convert {self} as an int"
1069 )))
1070 },
1071 }
1072 }
1073
1074 pub fn float(&self) -> Result<f64, ExpressionTypeError> {
1075 match self {
1076 ExprResult::Float(f) => Ok(f.into_inner()),
1077 ExprResult::Value(i) => Ok(*i as f64),
1078 ExprResult::Char(i) => Ok(*i as f64),
1079 ExprResult::Bool(b) => Ok(if *b { 1_f64 } else { 0 as f64 }),
1080 _ => {
1081 Err(ExpressionTypeError(format!(
1082 "Try to convert {self} as a float"
1083 )))
1084 },
1085 }
1086 }
1087
1088 pub fn char(&self) -> Result<char, ExpressionTypeError> {
1089 match self {
1090 ExprResult::Char(u) => Ok(*u as char),
1091 ExprResult::Float(f) => Ok(f.into_inner() as u8 as char),
1092 ExprResult::Value(v) => Ok(*v as u8 as char),
1093 ExprResult::Bool(b) => Ok(if *b { 'T' } else { 'F' }),
1094 _ => {
1095 Err(ExpressionTypeError(format!(
1096 "Try to convert {self} as a char"
1097 )))
1098 },
1099 }
1100 }
1101
1102 pub fn bool(&self) -> Result<bool, ExpressionTypeError> {
1103 match self {
1104 ExprResult::Float(f) => Ok(*f != 0.),
1105 ExprResult::Value(i) => Ok(*i != 0),
1106 ExprResult::Char(i) => Ok(*i != 0),
1107 ExprResult::Bool(b) => Ok(*b),
1108 _ => {
1109 Err(ExpressionTypeError(format!(
1110 "Try to convert {self} as a bool"
1111 )))
1112 },
1113 }
1114 }
1115
1116 pub fn not(&self) -> Result<Self, ExpressionTypeError> {
1117 match self {
1118 ExprResult::Bool(b) => Ok(Self::from(!*b)),
1119 ExprResult::Value(i) => Ok(Self::from(if *i == 0 { 1 } else { 0 })),
1120 ExprResult::Float(f) => Ok(Self::from(if *f == 0.0 { 1.0 } else { 0.0 })),
1121 _ => {
1122 Err(ExpressionTypeError(format!(
1123 "NOT is not an operation for {self}"
1124 )))
1125 },
1126 }
1127 }
1128}
1129
1130impl ExprResult {
1131 pub fn list_content(&self) -> &[ExprResult] {
1132 match self {
1133 ExprResult::List(content, ..) => content,
1134 _ => panic!("not a list")
1135 }
1136 }
1137
1138 pub fn list_len(&self) -> usize {
1139 self.list_content().len()
1140 }
1141
1142 pub fn list_get(&self, pos: usize) -> &ExprResult {
1143 &self.list_content()[pos]
1144 }
1145
1146 pub fn list_set(&mut self, pos: usize, value: ExprResult) {
1147 match self {
1148 ExprResult::List(content, ..) => content[pos] = value,
1149 _ => panic!("not a list")
1150 }
1151 }
1152}
1153
1154impl ExprResult {
1155 pub fn matrix_set(&mut self, y: usize, x: usize, value: ExprResult) {
1156 match self {
1157 ExprResult::Matrix { content, .. } => content[y].list_set(x, value),
1158 _ => panic!("not a matrix")
1159 }
1160 }
1161
1162 pub fn matrix_get(&self, y: usize, x: usize) -> &ExprResult {
1163 self.matrix_rows()[y].list_get(x)
1164 }
1165
1166 pub fn matrix_height(&self) -> usize {
1167 match self {
1168 ExprResult::Matrix { .. } => self.matrix_rows().len(),
1169 _ => panic!("not a matrix")
1170 }
1171 }
1172
1173 pub fn matrix_width(&self) -> usize {
1174 match self {
1175 ExprResult::Matrix { .. } => {
1176 self.matrix_rows()
1177 .first()
1178 .map(|r| r.list_len())
1179 .unwrap_or(0)
1180 },
1181 _ => panic!("not a matrix")
1182 }
1183 }
1184
1185 pub fn matrix_rows(&self) -> &[ExprResult] {
1186 match self {
1187 ExprResult::Matrix { content, .. } => content,
1188 _ => panic!("not a matrix")
1189 }
1190 }
1191
1192 pub fn matrix_col(&self, x: usize) -> ExprResult {
1193 let l = (0..self.matrix_height())
1194 .map(|row| self.matrix_rows()[row].list_get(x))
1195 .cloned()
1196 .collect_vec();
1197 ExprResult::List(l)
1198 }
1199
1200 pub fn matrix_set_col(&mut self, x: usize, values: &[ExprResult]) {
1201 debug_assert!(x < self.matrix_width());
1202
1203 for (y, val) in values.iter().enumerate() {
1204 self.matrix_set(y, x, val.clone())
1205 }
1206 }
1207
1208 pub fn matrix_row(&self, y: usize) -> &ExprResult {
1209 &self.matrix_rows()[y]
1210 }
1211
1212 pub fn matrix_transpose(&self) -> ExprResult {
1213 match self {
1214 ExprResult::Matrix { width, height, .. } => {
1215 let mut cols = vec![Vec::new(); *width];
1216 for row in self.matrix_rows() {
1217 for (col_idx, col_val) in row.list_content().iter().enumerate() {
1218 cols[col_idx].push(col_val.clone())
1219 }
1220 }
1221 let cols = cols.into_iter().map(ExprResult::List).collect_vec();
1222 ExprResult::Matrix {
1223 content: cols,
1224 width: *height,
1225 height: *width
1226 }
1227 },
1228 _ => panic!("not a matrix")
1229 }
1230 }
1231
1232 pub fn matrix_cols(&self) -> Vec<ExprResult> {
1233 let t = self.matrix_transpose();
1234 t.matrix_rows().iter().cloned().collect_vec()
1235 }
1236}
1237
1238impl ExprResult {
1239 pub fn floor(&self) -> Result<Self, ExpressionTypeError> {
1240 match self {
1241 ExprResult::Float(f) => Ok(f.floor().into()),
1242 ExprResult::Value(v) => Ok((*v).into()),
1243 _ => Err(ExpressionTypeError(format!("Try to apply floor to {self}")))
1244 }
1245 }
1246
1247 pub fn ceil(&self) -> Result<Self, ExpressionTypeError> {
1248 match self {
1249 ExprResult::Float(f) => Ok(f.ceil().into()),
1250 ExprResult::Value(v) => Ok((*v).into()),
1251 _ => Err(ExpressionTypeError(format!("Try to apply ceil to {self}")))
1252 }
1253 }
1254
1255 pub fn frac(&self) -> Result<Self, ExpressionTypeError> {
1256 match self {
1257 ExprResult::Float(f) => Ok(f.fract().into()),
1258 ExprResult::Value(_v) => Ok(0.into()),
1259 _ => Err(ExpressionTypeError(format!("Try to apply frac to {self}")))
1260 }
1261 }
1262
1263 pub fn sin(&self) -> Result<Self, ExpressionTypeError> {
1264 Ok((self.float()? * 3.1415926545 / 180.0).sin().into())
1265 }
1266
1267 pub fn cos(&self) -> Result<Self, ExpressionTypeError> {
1268 Ok((self.float()? * 3.1415926545 / 180.0).cos().into())
1269 }
1270
1271 pub fn asin(&self) -> Result<Self, ExpressionTypeError> {
1272 Ok((self.float()? * 180.0 / 3.1415926545).asin().into())
1273 }
1274
1275 pub fn acos(&self) -> Result<Self, ExpressionTypeError> {
1276 Ok((self.float()? * 180.0 / 3.1415926545).acos().into())
1277 }
1278
1279 pub fn atan(&self) -> Result<Self, ExpressionTypeError> {
1280 Ok((self.float()? * 180.0 / 3.1415926545).atan().into())
1281 }
1282
1283 pub fn abs(&self) -> Result<Self, ExpressionTypeError> {
1284 match self {
1285 ExprResult::Float(f) => Ok(f.abs().into()),
1286 ExprResult::Value(v) => Ok(v.abs().into()),
1287 ExprResult::Bool(_b) => Ok(self.clone()),
1288 _ => Err(ExpressionTypeError(format!("Try to apply abs to {self}")))
1289 }
1290 }
1291
1292 pub fn ln(&self) -> Result<Self, ExpressionTypeError> {
1293 Ok(self.float()?.ln().into())
1294 }
1295
1296 pub fn log10(&self) -> Result<Self, ExpressionTypeError> {
1297 Ok(self.float()?.log10().into())
1298 }
1299
1300 pub fn exp(&self) -> Result<Self, ExpressionTypeError> {
1301 Ok(self.float()?.exp().into())
1302 }
1303
1304 pub fn sqrt(&self) -> Result<Self, ExpressionTypeError> {
1305 Ok(self.float()?.sqrt().into())
1306 }
1307
1308 pub fn binary_not(&self) -> Result<Self, ExpressionTypeError> {
1309 match self {
1310 ExprResult::Float(_) => {
1311 Err(ExpressionTypeError(
1312 "Float are not compatible with ~ operator".to_owned()
1313 ))
1314 },
1315 ExprResult::Value(i) => Ok((!*i).into()),
1316 ExprResult::Bool(b) => Ok((!*b).into()),
1317 _ => Err(ExpressionTypeError(format!("Try to apply floor to {self}")))
1318 }
1319 }
1320}
1321
1322impl std::ops::Neg for ExprResult {
1323 type Output = Result<Self, ExpressionTypeError>;
1324
1325 fn neg(self) -> Self::Output {
1326 match self {
1327 ExprResult::Float(f) => Ok(f.neg().into()),
1328 ExprResult::Value(i) => Ok(i.neg().into()),
1329 ExprResult::Bool(b) => Ok((!b).into()),
1330 _ => Err(ExpressionTypeError(format!("Try to substract {self}")))
1331 }
1332 }
1333}
1334
1335impl AsRef<ExprResult> for ExprResult {
1336 fn as_ref(&self) -> &ExprResult {
1337 self
1338 }
1339}
1340
1341impl<T: AsRef<Self> + std::fmt::Display> std::ops::Add<T> for ExprResult {
1342 type Output = Result<Self, ExpressionTypeError>;
1343
1344 fn add(self, rhs: T) -> Self::Output {
1346 let rhs = rhs.as_ref();
1347 match (self, rhs) {
1348 (any, ExprResult::Bool(_)) => {
1349 let b = rhs.as_type(&any)?;
1350 any.sub(b)
1351 },
1352 (ExprResult::Bool(_), any) => {
1353 let b = rhs.as_type(any)?;
1354 b.sub(any)
1355 },
1356
1357 (ExprResult::Float(f1), ExprResult::Float(f2)) => {
1358 Ok((f1.into_inner() + f2.into_inner()).into())
1359 },
1360 (ExprResult::Float(f1), ExprResult::Value(_)) => Ok((f1 + rhs.float()?).into()),
1361 (any @ (ExprResult::Value(_) | ExprResult::Char(_)), ExprResult::Float(f2)) => {
1362 Ok((any.float()? + f2.into_inner()).into())
1363 },
1364 (ExprResult::Value(v1), ExprResult::Value(v2)) => Ok((v1 + v2).into()),
1365 (ExprResult::Char(v1), ExprResult::Char(v2)) => Ok((v1 + v2).into()),
1366 (ExprResult::Value(v1), ExprResult::Char(v2)) => Ok((v1 + *v2 as i32).into()),
1367 (ExprResult::Char(v1), ExprResult::Value(v2)) => Ok((v1 as i32 + *v2).into()),
1368
1369 (ExprResult::String(s), _) if s.len() == 1 => {
1370 ExprResult::Char(s.chars().next().unwrap() as u8) + rhs.clone()
1371 },
1372 (ExprResult::Char(c), _) => ExprResult::Value(c as _) + rhs.clone(),
1373
1374 (any, ExprResult::String(s)) if s.len() == 1 => {
1375 any + ExprResult::Char(s.chars().next().unwrap() as u8)
1376 },
1377 (any, ExprResult::Char(c)) => any + ExprResult::Value(*c as _),
1378
1379 (any, _) => {
1380 Err(ExpressionTypeError(format!(
1381 "Impossible addition between {any} and {rhs}"
1382 )))
1383 },
1384 }
1385 }
1386}
1387
1388impl<T: AsRef<Self> + std::fmt::Display> std::ops::Sub<T> for ExprResult {
1389 type Output = Result<Self, ExpressionTypeError>;
1390
1391 fn sub(self, rhs: T) -> Self::Output {
1392 let rhs = rhs.as_ref();
1393 match (self, rhs) {
1394 (any, ExprResult::Bool(_)) => {
1395 let b = rhs.as_type(&any)?;
1396 any.sub(b)
1397 },
1398 (ExprResult::Bool(_), any) => {
1399 let b = rhs.as_type(any)?;
1400 b.sub(any)
1401 },
1402
1403 (ExprResult::Float(f1), ExprResult::Float(f2)) => {
1404 Ok((f1.into_inner() - f2.into_inner()).into())
1405 },
1406 (ExprResult::Float(f1), ExprResult::Value(_)) => {
1407 Ok((f1.into_inner() - rhs.float()?).into())
1408 },
1409 (any @ ExprResult::Value(_), ExprResult::Float(f2)) => {
1410 Ok((any.float()? - f2.into_inner()).into())
1411 },
1412 (ExprResult::Value(v1), ExprResult::Value(v2)) => Ok((v1 - v2).into()),
1413
1414 (ExprResult::String(s), _) if s.len() == 1 => {
1415 ExprResult::Char(s.chars().next().unwrap() as u8) - rhs.clone()
1416 },
1417 (ExprResult::Char(c), any) => ExprResult::Value(c as _) - any,
1418
1419 (any, ExprResult::String(s)) if s.len() == 1 => {
1420 any - ExprResult::Char(s.chars().next().unwrap() as u8)
1421 },
1422 (any, ExprResult::Char(c)) => any - ExprResult::Value(*c as _),
1423
1424 (any, rhs) => {
1425 Err(ExpressionTypeError(format!(
1426 "Impossible substraction between {any} and {rhs}"
1427 )))
1428 },
1429 }
1430 }
1431}
1432
1433impl<T: AsRef<Self> + std::fmt::Display> std::ops::Mul<T> for ExprResult {
1434 type Output = Result<Self, ExpressionTypeError>;
1435
1436 fn mul(self, rhs: T) -> Self::Output {
1437 let rhs = rhs.as_ref();
1438 match (&self, rhs) {
1439 (ExprResult::Float(f1), ExprResult::Float(f2)) => {
1440 Ok((f1.into_inner() * f2.into_inner()).into())
1441 },
1442 (ExprResult::Float(f1), ExprResult::Value(_)) => {
1443 Ok((f1.into_inner() * rhs.float()?).into())
1444 },
1445 (ExprResult::Value(_), ExprResult::Float(f2)) => {
1446 Ok((self.float()? * f2.into_inner()).into())
1447 },
1448 (ExprResult::Value(v1), ExprResult::Value(v2)) => Ok((*v1 * *v2).into()),
1449
1450 (ExprResult::Value(v1), ExprResult::Char(v2))
1451 | (ExprResult::Char(v2), ExprResult::Value(v1)) => Ok((*v1 * (*v2 as i32)).into()),
1452
1453 (..) => {
1454 Err(ExpressionTypeError(format!(
1455 "Impossible multiplication between {self} and {rhs}"
1456 )))
1457 },
1458 }
1459 }
1460}
1461
1462impl<T: AsRef<Self> + std::fmt::Display> std::ops::Div<T> for ExprResult {
1463 type Output = Result<Self, ExpressionTypeError>;
1464
1465 fn div(self, rhs: T) -> Self::Output {
1466 let rhs = rhs.as_ref();
1467 match (&self, rhs) {
1468 (ExprResult::Float(f1), ExprResult::Float(f2)) => {
1469 Ok((f1.into_inner() / f2.into_inner()).into())
1470 },
1471 (ExprResult::Float(f1), ExprResult::Value(_)) => {
1472 Ok((f1.into_inner() / rhs.float()?).into())
1473 },
1474 (ExprResult::Value(_), ExprResult::Float(f2)) => {
1475 Ok((self.float()? / f2.into_inner()).into())
1476 },
1477 (ExprResult::Value(_), ExprResult::Value(_)) => {
1478 Ok((self.float()? / rhs.float()?).into())
1479 },
1480 (..) => {
1481 Err(ExpressionTypeError(format!(
1482 "Impossible division between {self} and {rhs}"
1483 )))
1484 },
1485 }
1486 }
1487}
1488
1489impl<T: AsRef<Self> + std::fmt::Display> std::ops::Rem<T> for ExprResult {
1490 type Output = Result<Self, ExpressionTypeError>;
1491
1492 fn rem(self, rhs: T) -> Self::Output {
1493 let rhs = rhs.as_ref();
1494 match (&self, &rhs) {
1495 (ExprResult::Float(f1), ExprResult::Float(f2)) => {
1496 Ok((f1.into_inner() % f2.into_inner()).into())
1497 },
1498 (ExprResult::Float(f1), ExprResult::Value(_)) => {
1499 Ok((f1.into_inner() % rhs.float()?).into())
1500 },
1501 (ExprResult::Value(_), ExprResult::Float(f2)) => {
1502 Ok((self.float()? % f2.into_inner()).into())
1503 },
1504 (ExprResult::Value(v1), ExprResult::Value(v2)) => {
1505 Ok(((*v1 as u32 % *v2 as u32) as i32).into())
1507 },
1508 (..) => {
1509 Err(ExpressionTypeError(format!(
1510 "Impossible reminder between {self} and {rhs}"
1511 )))
1512 },
1513 }
1514 }
1515}
1516
1517impl std::ops::Shr for ExprResult {
1518 type Output = Result<Self, ExpressionTypeError>;
1519
1520 fn shr(self, rhs: Self) -> Self::Output {
1521 Ok((self.int()?.wrapping_shr(rhs.int()? as _)).into())
1522 }
1523}
1524
1525impl std::ops::Shl for ExprResult {
1526 type Output = Result<Self, ExpressionTypeError>;
1527
1528 fn shl(self, rhs: Self) -> Self::Output {
1529 Ok((self.int()?.wrapping_shl(rhs.int()? as u32)).into())
1530 }
1531}
1532
1533impl std::ops::BitAnd for ExprResult {
1534 type Output = Result<Self, ExpressionTypeError>;
1535
1536 fn bitand(self, rhs: Self) -> Self::Output {
1537 Ok((self.int()? & rhs.int()?).into())
1538 }
1539}
1540
1541impl std::ops::BitOr for ExprResult {
1542 type Output = Result<Self, ExpressionTypeError>;
1543
1544 fn bitor(self, rhs: Self) -> Self::Output {
1545 Ok((self.int()? | rhs.int()?).into())
1546 }
1547}
1548
1549impl std::ops::BitXor for ExprResult {
1550 type Output = Result<Self, ExpressionTypeError>;
1551
1552 fn bitxor(self, rhs: Self) -> Self::Output {
1553 Ok((self.int()? ^ rhs.int()?).into())
1554 }
1555}
1556
1557impl std::cmp::PartialEq for ExprResult {
1558 fn eq(&self, other: &Self) -> bool {
1559 match (self, other) {
1560 (Self::Float(l0), Self::Float(r0)) => l0 == r0,
1561 (Self::Value(l0), Self::Value(r0)) => l0 == r0,
1562 (Self::String(l0), Self::String(r0)) => l0 == r0,
1563 (Self::List(l0), Self::List(r0)) => l0 == r0,
1564
1565 (Self::String(s), Self::List(l)) | (Self::List(l), Self::String(s)) => {
1566 let s = s.as_bytes();
1567 if s.len() != l.len() {
1568 return false;
1569 }
1570 s.iter().zip(l.iter()).all(|(a, b)| {
1571 match b.int() {
1572 Ok(b) => (*a as i32) == b,
1573 Err(_) => false
1574 }
1575 })
1576 },
1577
1578 (Self::String(_), _) | (_, Self::String(_)) => false,
1579 (Self::List(_), _) | (_, Self::List(_)) => false,
1580
1581 _ => self.int().unwrap() == other.int().unwrap()
1582 }
1583 }
1584}
1585
1586impl std::cmp::PartialOrd for ExprResult {
1587 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1588 match (self, other) {
1589 (Self::Float(l0), Self::Float(r0)) => l0.partial_cmp(r0),
1590 (Self::Value(l0), Self::Value(r0)) => l0.partial_cmp(r0),
1591
1592 (Self::String(l0), Self::String(r0)) => l0.partial_cmp(r0),
1593 (Self::String(_), _) | (_, Self::String(_)) => None,
1594
1595 (Self::List(l0), Self::List(r0)) => l0.partial_cmp(r0),
1596 (Self::List(_), _) | (_, Self::List(_)) => None,
1597
1598 _ => self.float().unwrap().partial_cmp(&other.float().unwrap())
1599 }
1600 }
1601}
1602
1603impl std::fmt::Display for ExprResult {
1604 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1605 match self {
1606 ExprResult::Float(f2) => write!(f, "{}", f2.into_inner()),
1607 ExprResult::Value(v) => write!(f, "{v}"),
1608 ExprResult::Char(v) => write!(f, "'{}'", *v as char),
1609 ExprResult::Bool(b) => write!(f, "{b}"),
1610 ExprResult::String(v) => write!(f, "\"{v}\""),
1611 ExprResult::List(v) => {
1612 write!(f, "[{}]", v.iter().map(|item| format!("{item}")).join(","))
1613 },
1614 ExprResult::Matrix { .. } => {
1615 write!(
1616 f,
1617 "matrix({})",
1618 self.matrix_rows()
1619 .iter()
1620 .map(|row| format!("{row}"))
1621 .join(",")
1622 )
1623 }
1624 }
1625 }
1626}
1627
1628impl std::fmt::LowerHex for ExprResult {
1629 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1630 match self {
1631 ExprResult::Float(_f2) => write!(f, "????"),
1632 ExprResult::Value(v) => write!(f, "{v:x}"),
1633 ExprResult::Char(v) => write!(f, "{v:x}"),
1634 ExprResult::Bool(v) => write!(f, "{:x}", *v as u8),
1635 ExprResult::String(_v) => write!(f, "STRING REPRESENTATION ISSUE"),
1636 ExprResult::List(v) => {
1637 write!(
1638 f,
1639 "[{}]",
1640 v.iter().map(|item| format!("{item:x}")).join(",")
1641 )
1642 },
1643 ExprResult::Matrix { .. } => {
1644 write!(
1645 f,
1646 "matrix({})",
1647 self.matrix_rows()
1648 .iter()
1649 .map(|row| format!("{row:x}"))
1650 .join(",")
1651 )
1652 }
1653 }
1654 }
1655}
1656
1657impl std::fmt::UpperHex for ExprResult {
1658 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1659 match self {
1660 ExprResult::Float(_f2) => write!(f, "????"),
1661 ExprResult::Value(v) => write!(f, "{v:X}"),
1662 ExprResult::Char(v) => write!(f, "{:X}", *v),
1663 ExprResult::Bool(v) => write!(f, "{:X}", *v as u8),
1664 ExprResult::String(_v) => write!(f, "STRING REPRESENTATION ISSUE"),
1665 ExprResult::List(v) => {
1666 write!(
1667 f,
1668 "[{}]",
1669 v.iter().map(|item| format!("{item:X}")).join(",")
1670 )
1671 },
1672 ExprResult::Matrix { .. } => {
1673 write!(
1674 f,
1675 "matrix({})",
1676 self.matrix_rows()
1677 .iter()
1678 .map(|row| format!("{row:X}"))
1679 .join(",")
1680 )
1681 }
1682 }
1683 }
1684}
1685
1686impl std::ops::AddAssign for ExprResult {
1687 fn add_assign(&mut self, rhs: Self) {
1688 if let Ok(v) = self.clone().add(rhs) {
1689 *self = v
1690 }
1691 }
1692}
1693
1694impl std::ops::SubAssign for ExprResult {
1695 fn sub_assign(&mut self, rhs: Self) {
1696 if let Ok(v) = self.clone().sub(rhs) {
1697 *self = v
1698 }
1699 }
1700}