cpclib_tokens/tokens/
expression.rs

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/// Expression nodes.
14#[derive(Debug, PartialEq, Eq, Clone, Hash)]
15#[allow(missing_docs)]
16pub enum Expr {
17    /// Only used for disassembled code
18    RelativeDelta(i8),
19
20    /// 32 bits integer value (should be able to include any integer value manipulated by the assember.
21    Value(i32),
22    // 64bits float for all the mathematical operations,
23    Float(OrderedFloat<f64>),
24    /// Char
25    Char(char),
26    /// Boolean
27    Bool(bool),
28    /// String (for db directive)
29    String(SmolStr),
30    /// Label
31    Label(SmolStr),
32    /// List of expression
33    List(Vec<Expr>),
34
35    /// Label with a prefix
36    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    /// Function supposely coded by the user
47    AnyFunction(SmolStr, Vec<Expr>),
48
49    /// Random value
50    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
65/// All methods are unchecked
66pub 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)]
141/// Represents a prefix that provides information related to banks for a label
142pub enum LabelPrefix {
143    /// We want the bank of the label
144    Bank,
145    /// We want the page of the label
146    Page,
147    /// We want the Gate array configuration for the label
148    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/// Format to represent an expression
163/// Stolen documentation of rasm
164/// Write text, variables or the result of evaluation of an expression during assembly.
165/// By default, numerical values are formatted as
166// oating point values, but you may use prexes to change
167/// this behaviour:
168///  fhexg Display in hexadecimal format. If the value is less than #FF two digits will be displayed.
169/// If less than #FFFF, the display will be forced to 4 digits.
170///  fhex2g, fhex4g, fhex8g to force hex display with 2, 4 or 8 digits.
171///  fbing Display a binary value. If the value is less than #FF 8 bits will be displayed. Otherwise if
172/// it is less than #FFFF 16 bits will be printed. Any negative 32 bits value with all 16 upper bits
173/// set to 1 will be displayed as a 16 bits value.
174///  fbin8g,fbin16g,fbin32g Force binary display with 8, 16 or 32 bits.
175///  fintg Display value as integer.
176#[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    /// Generate the string representation of the given value
207    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/// Expression for a print expression
228#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229pub enum FormattedExpr {
230    // A raw expression is represented as it is
231    Raw(Expr),
232    // A formatted expression has a representatio nthat depends on its format
233    Formatted(ExprFormat, Expr)
234}
235
236impl FormattedExpr {
237    // pub fn fix_local_macro_labels_with_seed(&mut self, seed: usize) {
238    // match self {
239    // FormattedExpr::Raw(e) | FormattedExpr::Formatted(_, e) => e.fix_local_macro_labels_with_seed(seed),
240    // }
241    // }
242}
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/// Represent a function with one argument
260#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
261pub enum UnaryFunction {
262    /// High byte of a value
263    High,
264    /// Low byte of a value
265    Low,
266    /// Memory already assembled
267    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        //    panic!();
287        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/// Function with two arguments
413#[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
426// Macro to generate all the converters from one number to an expression
427macro_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    /// Check if it is necessary to read within a symbol table
485    fn is_context_independant(&self) -> bool {
486        use self::Expr::*;
487        match *self {
488            Label(_) => false,
489            _ => true
490        }
491    }
492
493    /// When disassembling an instruction with relative expressions, the contained value needs to be transformed as an absolute value
494    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            // Should not be displayed often
778            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
811// impl Debug for Expr {
812// fn fmt(&self, format: &mut Formatter<'_>) -> fmt::Result {
813// use self::Expr::*;
814// match *self {
815// Value(val) => write!(format, "{}", val),
816// String( string) => write!(format, "\"{}\"", string),
817// Label( label) => write!(format, "{}", label),
818// Duration( token) => write!(format, "DURATION({:?})", token),
819// OpCode( token) => write!(format, "OPCODE({:?})", token),
820//
821// Add( left,  right) => write!(format, "({:?} + {:?})", left, right),
822// Sub( left,  right) => write!(format, "({:?} - {:?})", left, right),
823// Mul( left,  right) => write!(format, "({:?} * {:?})", left, right),
824// Mod( left,  right) => write!(format, "({:?} % {:?})", left, right),
825// Div( left,  right) => write!(format, "({:?} / {:?})", left, right),
826//
827// BinaryAnd( left,  right) => write!(format, "({:?} & {:?})", left, right),
828// BinaryOr( left,  right) => write!(format, "({:?} | {:?})", left, right),
829// BinaryXor( left,  right) => write!(format, "({:?} ^ {:?})", left, right),
830//
831// Neg( e) => write!(format, "Neg({:?})", e),
832//
833// Paren( expr) => write!(format, "[{:?}]", expr),
834//
835// Equal( left,  right) => write!(format, "{:?} == {:?}", left, right),
836// GreaterOrEqual( left,  right) => write!(format, "{:?} >= {:?}", left, right),
837// StrictlyGreater( left,  right) => write!(format, "{:?} > {:?}", left, right),
838// StrictlyLower( left,  right) => write!(format, "{:?} < {:?}", left, right),
839// LowerOrEqual( left,  right) => write!(format, "{:?} <= {:?}", left, right),
840//
841// High( inner) => write!(format, "HI({:?})", inner),
842// Low( inner) => write!(format, "LO({:?})", inner),
843// }
844// }
845// }
846impl Expr {
847    // pub fn fix_local_macro_labels_with_seed(&mut self, seed: usize) {
848    // use Expr::*;
849    // match self {
850    // RelativeDelta(_) | Value(_) | String(_) | Char(_)=> {}
851    //
852    // Label(s) | PrefixedLabel(_, s) => {
853    // Self::do_apply_macro_labels_modification(s, seed);
854    // }
855    //
856    // Duration(t) | OpCode(t) => {
857    // t.fix_local_macro_labels_with_seed(seed);
858    // }
859    //
860    // Neg(b) | Paren(b) | UnaryFunction(_, b) => {
861    // b.fix_local_macro_labels_with_seed(seed);
862    // }
863    //
864    // RightShift(b1, b2)
865    // |LeftShift(b1, b2)
866    // |Add(b1, b2)
867    // | Sub(b1, b2)
868    // | Mul(b1, b2)
869    // | Div(b1, b2)
870    // | Mod(b1, b2)
871    // | BinaryAnd(b1, b2)
872    // | BinaryOr(b1, b2)
873    // | BinaryXor(b1, b2)
874    // | BooleanAnd(b1, b2)
875    // | BooleanOr(b1, b2)
876    // | Equal(b1, b2)
877    // | Different(b1, b2)
878    // | LowerOrEqual(b1, b2)
879    // | GreaterOrEqual(b1, b2)
880    // | StrictlyGreater(b1, b2)
881    // | StrictlyLower(b1, b2)
882    // | BinaryFunction(_, b1, b2) => {
883    // b1.fix_local_macro_labels_with_seed(seed);
884    // b2.fix_local_macro_labels_with_seed(seed);
885    // }
886    // }
887    // }
888
889    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/// The successful result of an evaluation.
912/// Embeds  a real,  an integer or a string
913#[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 _), /* ensure 2.9 is treated as 3 */
1063            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    /// TODO Allow "string" + &80 to add a number to the very last string
1345    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                // XXX is it the expected behavior ? (I used this formula only for ORGAMS compatibilyt. It is maybe an error)
1506                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}