1use crate::operator::Arity::*;
2use crate::operator::Associativity::*;
3use crate::operator::OperatorName::*;
4use ahash::AHashMap;
5use once_cell::sync::Lazy;
6use serde::Serialize;
7
8#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize)]
9pub enum OperatorName {
10 Addition,
11 Assignment,
12 AssignmentAddition,
13 AssignmentBitwiseAnd,
14 AssignmentBitwiseLeftShift,
15 AssignmentBitwiseOr,
16 AssignmentBitwiseRightShift,
17 AssignmentBitwiseUnsignedRightShift,
18 AssignmentBitwiseXor,
19 AssignmentDivision,
20 AssignmentExponentiation,
21 AssignmentLogicalAnd,
22 AssignmentLogicalOr,
23 AssignmentMultiplication,
24 AssignmentNullishCoalescing,
25 AssignmentRemainder,
26 AssignmentSubtraction,
27 Await,
28 BitwiseAnd,
29 BitwiseLeftShift,
30 BitwiseNot,
31 BitwiseOr,
32 BitwiseRightShift,
33 BitwiseUnsignedRightShift,
34 BitwiseXor,
35 Call,
36 Comma,
37 ComputedMemberAccess,
38 Conditional,
39 ConditionalAlternate,
41 Delete,
42 Division,
43 Equality,
44 Exponentiation,
45 GreaterThan,
46 GreaterThanOrEqual,
47 In,
48 Inequality,
49 Instanceof,
50 LessThan,
51 LessThanOrEqual,
52 LogicalAnd,
53 LogicalNot,
54 LogicalOr,
55 MemberAccess,
56 Multiplication,
57 New,
58 NullishCoalescing,
59 OptionalChainingMemberAccess,
60 OptionalChainingComputedMemberAccess,
61 OptionalChainingCall,
62 PostfixDecrement,
63 PostfixIncrement,
64 PrefixDecrement,
65 PrefixIncrement,
66 Remainder,
67 StrictEquality,
68 StrictInequality,
69 Subtraction,
70 Typeof,
71 UnaryNegation,
72 UnaryPlus,
73 Void,
74 Yield,
75 YieldDelegated,
76}
77
78impl OperatorName {
79 pub fn is_assignment(self) -> bool {
80 match self {
81 OperatorName::Assignment
82 | OperatorName::AssignmentAddition
83 | OperatorName::AssignmentBitwiseAnd
84 | OperatorName::AssignmentBitwiseLeftShift
85 | OperatorName::AssignmentBitwiseOr
86 | OperatorName::AssignmentBitwiseRightShift
87 | OperatorName::AssignmentBitwiseUnsignedRightShift
88 | OperatorName::AssignmentBitwiseXor
89 | OperatorName::AssignmentDivision
90 | OperatorName::AssignmentExponentiation
91 | OperatorName::AssignmentLogicalAnd
92 | OperatorName::AssignmentLogicalOr
93 | OperatorName::AssignmentMultiplication
94 | OperatorName::AssignmentNullishCoalescing
95 | OperatorName::AssignmentRemainder
96 | OperatorName::AssignmentSubtraction => true,
97 _ => false,
98 }
99 }
100}
101
102#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
103pub enum Arity {
104 Unary,
105 Binary,
106 Ternary,
107}
108
109#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
110pub enum Associativity {
111 Left,
112 Right,
113}
114
115pub struct Operator {
116 pub name: OperatorName,
117 pub arity: Arity,
118 pub associativity: Associativity,
119 pub precedence: u8,
120}
121
122const PRECEDENCE_LEVELS: &[&[(OperatorName, Arity, Associativity)]] = &[
123 &[
124 (MemberAccess, Binary, Left),
125 (ComputedMemberAccess, Binary, Left),
126 (Call, Binary, Left),
127 (New, Unary, Right),
128 (OptionalChainingMemberAccess, Binary, Left),
129 (OptionalChainingComputedMemberAccess, Binary, Left),
130 (OptionalChainingCall, Binary, Left),
131 ],
132 &[
133 (PostfixIncrement, Unary, Left),
134 (PostfixDecrement, Unary, Left),
135 ],
136 &[
137 (LogicalNot, Unary, Right),
138 (BitwiseNot, Unary, Right),
139 (UnaryPlus, Unary, Right),
140 (UnaryNegation, Unary, Right),
141 (PrefixIncrement, Unary, Right),
142 (PrefixDecrement, Unary, Right),
143 (Typeof, Unary, Right),
144 (Void, Unary, Right),
145 (Delete, Unary, Right),
146 (Await, Unary, Right),
147 ],
148 &[(Exponentiation, Binary, Right)],
149 &[
150 (Multiplication, Binary, Left),
151 (Division, Binary, Left),
152 (Remainder, Binary, Left),
153 ],
154 &[(Addition, Binary, Left), (Subtraction, Binary, Left)],
155 &[
156 (BitwiseLeftShift, Binary, Left),
157 (BitwiseRightShift, Binary, Left),
158 (BitwiseUnsignedRightShift, Binary, Left),
159 ],
160 &[
161 (LessThan, Binary, Left),
162 (LessThanOrEqual, Binary, Left),
163 (GreaterThan, Binary, Left),
164 (GreaterThanOrEqual, Binary, Left),
165 (In, Binary, Left),
166 (Instanceof, Binary, Left),
167 ],
168 &[
169 (Equality, Binary, Left),
170 (Inequality, Binary, Left),
171 (StrictEquality, Binary, Left),
172 (StrictInequality, Binary, Left),
173 ],
174 &[(BitwiseAnd, Binary, Left)],
175 &[(BitwiseXor, Binary, Left)],
176 &[(BitwiseOr, Binary, Left)],
177 &[(LogicalAnd, Binary, Left)],
178 &[(LogicalOr, Binary, Left), (NullishCoalescing, Binary, Left)],
179 &[(Conditional, Ternary, Right)],
180 &[
181 (Assignment, Binary, Right),
182 (AssignmentAddition, Binary, Right),
183 (AssignmentBitwiseAnd, Binary, Right),
184 (AssignmentBitwiseLeftShift, Binary, Right),
185 (AssignmentBitwiseOr, Binary, Right),
186 (AssignmentBitwiseRightShift, Binary, Right),
187 (AssignmentBitwiseUnsignedRightShift, Binary, Right),
188 (AssignmentBitwiseXor, Binary, Right),
189 (AssignmentDivision, Binary, Right),
190 (AssignmentExponentiation, Binary, Right),
191 (AssignmentLogicalAnd, Binary, Right),
192 (AssignmentLogicalOr, Binary, Right),
193 (AssignmentMultiplication, Binary, Right),
194 (AssignmentNullishCoalescing, Binary, Right),
195 (AssignmentRemainder, Binary, Right),
196 (AssignmentSubtraction, Binary, Right),
197 (Yield, Unary, Right),
198 (YieldDelegated, Unary, Right),
199 ],
200 &[(ConditionalAlternate, Ternary, Right)],
202 &[(Comma, Binary, Left)],
203];
204
205pub static OPERATORS: Lazy<AHashMap<OperatorName, Operator>> = Lazy::new(|| {
206 let mut map = AHashMap::<OperatorName, Operator>::new();
207 for (i, ops) in PRECEDENCE_LEVELS.iter().enumerate() {
208 let precedence = (PRECEDENCE_LEVELS.len() - i) as u8;
209 for &(name, arity, associativity) in ops.iter() {
210 map.insert(name, Operator {
211 name,
212 arity,
213 associativity,
214 precedence,
215 });
216 }
217 }
218 map
219});