1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::fmt::Display;
/// An operator used in the intermediate representation
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Operator {
// Arithmetic
/// Add (+) operator
Add,
/// Sub (-) operator
Sub,
/// Mul (*) operator
Mul,
/// Div (/) operator
Div,
/// Rem (%) operator
Rem,
// Arithmetic Assign
/// Add assign (+=) operator
AddAssign,
/// Sub assign (-=) operator
SubAssign,
/// Mul assign (*=) operator
MulAssign,
/// Div assign (/=) operator
DivAssign,
/// Rem assign (%=) operator
RemAssign,
// Comparison
/// Equals (==) operator
Eq,
/// Not equal (!=) operator
Ne,
/// Less than (<) operator
Lt,
/// Less than equals (<=) operator
Le,
/// Greater than equal (>=) operator
Ge,
/// Greater than (>) operator
Gt,
// Boolean
/// And (&&) operator
And,
/// Or (||) operator
Or,
/// Bitwise XOR (^) operator
BitXor,
/// Bitwise And (&) operator
BitAnd,
/// Bitwise Or (|) operator
BitOr,
// Boolean assign
/// Bitwise xor assign (^=) operator
BitXorAssign,
/// Bitwise and assign (&=) operator
BitAndAssign,
/// Bitwise or assign (|=) operator
BitOrAssign,
/// Shift left (<<) operator
Shl,
/// Shift right (>>) operator
Shr,
/// Shift left assign (<<=) operator
ShlAssign,
/// Shift right assign (>>= operator)
ShrAssign,
// Unary
/// Dereference operator (*)
Deref,
/// Not operator (!)
Not,
/// Negation unary operator (-)
Neg,
}
impl Display for Operator {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{self:?}"))
}
}
impl Operator {
/// Whether this is an assign op, aka whether the output is the same as the
/// left hand side
pub fn is_assign(&self) -> bool {
matches!(
self,
Operator::AddAssign
| Operator::SubAssign
| Operator::MulAssign
| Operator::DivAssign
| Operator::RemAssign
| Operator::BitXorAssign
| Operator::BitAndAssign
| Operator::BitOrAssign
| Operator::ShlAssign
| Operator::ShrAssign
)
}
/// Get the expanded op name for this operation
pub fn op_name(&self) -> String {
if self.is_assign() {
let name = self.to_string().to_lowercase();
format!("{}_assign_op", &name[..name.len() - 6])
} else {
self.to_string().to_lowercase()
}
}
/// Get the expanded op name for this array operation
pub fn array_op_name(&self) -> String {
if self.is_assign() {
let name = self.to_string().to_lowercase();
format!("{}_assign_array_op", &name[..name.len() - 6])
} else {
self.to_string().to_lowercase()
}
}
}