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);