logic_tracer/tokens/
operators.rs

1use super::*;
2
3use crate::impl_enum_token;
4
5pub trait OperatorTrait: Token {
6    // * Add properties and methods for the operator type...
7    // todo: Add all the stuff below...
8    // todo: Add `precedence`, `associativity`, and `arity` properties for the operator type...
9    // todo: Add `is_unary`, `is_binary`, and `is_nary` methods for the operator type... (use `arity`)
10    // todo: Add `is_left_associative`, `is_right_associative`, and `is_non_associative` methods for the operator type... (use `associativity`)
11}
12#[derive(Debug, Clone, PartialEq)]
13pub struct Operator;
14
15pub trait OperatorNegator: OperatorTrait {
16    const NEGATOR: Self;
17}
18
19/// Macro to implement operator tokens and their associated traits.
20///
21/// # Parameters
22///
23/// - `$token_type`: The type of the token (e.g., `Operator`).
24/// - `$trait_name`: The name of the trait that all operator tokens will implement.
25/// - `$name`: The name of the enum representing a specific operator type (e.g., `MathOp`).
26/// - `$negator`: An optional parameter representing the negator variant for the operator type.
27/// - `$variant`: The variants of the operator enum, mapping strings to enum variants.
28///
29/// # Example
30///
31/// ```rust
32/// impl_operator_token!(Operator; OperatorTrait;
33///     MathOp (Subtract;  // this will be the negator of the operator type
34///         Add => ("+"),
35///         Subtract => ("-"),
36///         Multiply => ("*"),
37///         Divide => ("/"),
38///         Modulo => ("%"),
39///         Power => ("^"),
40///         Root => ("√"),
41///         Factorial => ("!"),
42///     ),
43///     LogicOp (Not;  // this will be the negator of the operator type
44///         And => ("&", "^", "∧", "+"),
45///         Or => ("|", "||", "*"),
46///         Not => ("!", "~", "¬"),
47///         XOr => ("^", "⊻", "⨁"),
48///         XNOr => ("⊙", "⊽"),
49///         NAnd => ("↑"),
50///         NOr => ("↓"),
51///     ),
52///     RelationalOp (NotEqual;
53///         Equal => ("==", "="),
54///         NotEqual => ("!=", "≠"),
55///         LessThan => ("<"),
56///         LessThanOrEqual => ("<=", "≤"),
57///         GreaterThan => (">"),
58///         GreaterThanOrEqual => (">=", "≥"),
59///     ),
60///     SomeOtherOp (;  // this will not have a negator (don't implement OperatorNegator for it)
61///         SomeOp => ("some_op"),
62///         AnotherOp => ("another_op"),
63///    ),
64/// );
65/// ```
66macro_rules! impl_operator_token {
67    ($token_type:ident; $trait_name:ident;
68        $($name:ident (
69            $( $negator:ident )?;
70            $(
71                $variant:ident => ($($str:expr),+)
72                $(,)?
73            )+
74        )),+
75        $(,)?
76    ) => {
77        impl_enum_token!($token_type; $trait_name;
78            $($name (
79                $(
80                    $variant => ($($str),+)
81                )+
82            )),+
83        );
84
85        $(
86            $(
87                impl OperatorNegator for $name {
88                    const NEGATOR: Self = $name::$negator;
89                }
90            )?
91        )+
92    };
93}
94
95impl_operator_token!(Operator; OperatorTrait;
96    MathOp (Subtract;
97        Add => ("+"),
98        Subtract => ("-"),
99        Multiply => ("*"),
100        Divide => ("/"),
101        Modulo => ("%"),
102        Power => ("^"),
103        Root => ("√"),
104        Factorial => ("!"),
105    ),
106    LogicOp (Not;
107        And => ("&", "^", "∧", "+"),
108        Or => ("|", "||", "*"),
109        Not => ("!", "~", "¬"),
110        XOr => ("^", "⊻", "⨁"),
111        XNOr => ("⊙", "⊽"),
112        NAnd => ("↑"),
113        NOr => ("↓"),
114    ),
115    RelationalOp (;  // ^ without implementing OperatorNegator trait
116        Equal => ("==", "="),
117        NotEqual => ("!=", "≠"),
118        LessThan => ("<"),
119        LessThanOrEqual => ("<=", "≤"),
120        GreaterThan => (">"),
121        GreaterThanOrEqual => (">=", "≥"),
122    ),
123);