Multiply entities beyond necessity even more (force better build parallelism)
[hiphop-php.git] / hphp / hack / src / parser / operator.rs
blobca8f80fef38ac91c7f2c5d43afcc1e08468cd89c
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
4 // This source code is licensed under the MIT license found in the
5 // LICENSE file in the "hack" directory of this source tree.
7 use crate::parser_env::ParserEnv;
8 use parser_core_types::token_kind::TokenKind;
10 pub use crate::operator_generated::*;
12 #[derive(PartialEq)]
13 pub enum Assoc {
14     LeftAssociative,
15     RightAssociative,
16     NotAssociative,
19 use self::Operator::*;
21 impl Operator {
22     pub fn precedence(&self, _env: &ParserEnv) -> usize {
23         // TODO: eval
24         // TODO: Comma
25         // TODO: elseif
26         // TODO: else
27         // TODO: endif
28         // TODO: variable operator $
29         match self {
30             IncludeOperator | IncludeOnceOperator | RequireOperator | RequireOnceOperator => 1,
31             PrintOperator => 5,
32             AssignmentOperator
33             | AdditionAssignmentOperator
34             | SubtractionAssignmentOperator
35             | MultiplicationAssignmentOperator
36             | DivisionAssignmentOperator
37             | ExponentiationAssignmentOperator
38             | RemainderAssignmentOperator
39             | ConcatenationAssignmentOperator
40             | AndAssignmentOperator
41             | OrAssignmentOperator
42             | ExclusiveOrAssignmentOperator
43             | LeftShiftAssignmentOperator
44             | RightShiftAssignmentOperator
45             | CoalesceAssignmentOperator => 6,
46             PipeOperator => 7,
47             ConditionalQuestionOperator
48             | ConditionalColonOperator
49             | DegenerateConditionalOperator => 8,
50             CoalesceOperator => 9,
51             LogicalOrOperator => 10,
52             LogicalAndOperator => 11,
53             OrOperator => 12,
54             ExclusiveOrOperator => 13,
55             AndOperator => 14,
56             EqualOperator
57             | StrictEqualOperator
58             | PhpNotEqualOperator
59             | NotEqualOperator
60             | StrictNotEqualOperator => 15,
61             SpaceshipOperator
62             | LessThanOperator
63             | LessThanOrEqualOperator
64             | GreaterThanOperator
65             | GreaterThanOrEqualOperator => 16,
66             LeftShiftOperator | RightShiftOperator => 17,
67             AdditionOperator | SubtractionOperator | ConcatenationOperator => 18,
68             MultiplicationOperator | DivisionOperator | RemainderOperator | SuspendOperator => 19,
69             LogicalNotOperator | NotOperator | UnaryPlusOperator | UnaryMinusOperator => 20,
70             InstanceofOperator | IsOperator | AsOperator | NullableAsOperator => 21,
71             CastOperator
72             | ErrorControlOperator
73             | PrefixIncrementOperator
74             | PrefixDecrementOperator
75             | ExponentOperator => 22,
76             PostfixIncrementOperator | PostfixDecrementOperator | AwaitOperator => 23,
77             CloneOperator => 24,
78             // value 25 is reserved for assignment that appear in expressions
79             ReferenceOperator => 26,
80             FunctionCallOperator => 27,
81             NewOperator => 28,
82             MemberSelectionOperator | NullSafeMemberSelectionOperator => 29,
83             IndexingOperator => 30,
84             ScopeResolutionOperator => 31,
85             DollarOperator => 32,
86         }
87     }
89     pub fn precedence_for_assignment_in_expressions() -> usize {
90         25
91     }
93     pub fn associativity(&self, _env: &ParserEnv) -> Assoc {
94         match self {
95             | EqualOperator | StrictEqualOperator | NotEqualOperator | PhpNotEqualOperator
96             | StrictNotEqualOperator | LessThanOperator | LessThanOrEqualOperator
97             | GreaterThanOperator | GreaterThanOrEqualOperator | InstanceofOperator
98             | NewOperator | CloneOperator | SpaceshipOperator => Assoc::NotAssociative,
99             | DegenerateConditionalOperator
100             | PipeOperator | ConditionalQuestionOperator | ConditionalColonOperator
101             | LogicalOrOperator | ExclusiveOrOperator | LogicalAndOperator
102             | OrOperator | AndOperator | LeftShiftOperator | RightShiftOperator
103             | AdditionOperator | SubtractionOperator | ConcatenationOperator
104             | MultiplicationOperator | DivisionOperator | RemainderOperator
105             | MemberSelectionOperator | NullSafeMemberSelectionOperator
106             | ScopeResolutionOperator | FunctionCallOperator | IndexingOperator
107             | IncludeOperator | IncludeOnceOperator | RequireOperator
108             | RequireOnceOperator | IsOperator | AsOperator | NullableAsOperator
109                 // eval
110                 // Comma
111                 // elseif
112                 // else
113                 // endif
114                 => Assoc::LeftAssociative,
115             | CoalesceOperator | CoalesceAssignmentOperator | LogicalNotOperator | NotOperator | CastOperator
116             | DollarOperator | UnaryPlusOperator | UnaryMinusOperator  // TODO: Correct?
117             | ErrorControlOperator | ReferenceOperator // TODO: Correct?
118             | PostfixIncrementOperator | PostfixDecrementOperator
119             | PrefixIncrementOperator | PrefixDecrementOperator | ExponentOperator
120             | AssignmentOperator | AdditionAssignmentOperator
121             | SubtractionAssignmentOperator | MultiplicationAssignmentOperator
122             | DivisionAssignmentOperator | ExponentiationAssignmentOperator
123             | ConcatenationAssignmentOperator
124             | RemainderAssignmentOperator | AndAssignmentOperator
125             | OrAssignmentOperator | ExclusiveOrAssignmentOperator
126             | LeftShiftAssignmentOperator | RightShiftAssignmentOperator
127             | PrintOperator | SuspendOperator | AwaitOperator => Assoc::RightAssociative,
128         }
129     }
131     pub fn prefix_unary_from_token(token: TokenKind) -> Operator {
132         match token {
133             TokenKind::Suspend => SuspendOperator,
134             TokenKind::Await => AwaitOperator,
135             TokenKind::Exclamation => LogicalNotOperator,
136             TokenKind::Tilde => NotOperator,
137             TokenKind::PlusPlus => PrefixIncrementOperator,
138             TokenKind::MinusMinus => PrefixDecrementOperator,
139             TokenKind::Dollar => DollarOperator,
140             TokenKind::Plus => UnaryPlusOperator,
141             TokenKind::Minus => UnaryMinusOperator,
142             TokenKind::Ampersand => ReferenceOperator,
143             TokenKind::At => ErrorControlOperator,
144             TokenKind::New => NewOperator,
145             TokenKind::Clone => CloneOperator,
146             TokenKind::Include => IncludeOperator,
147             TokenKind::Include_once => IncludeOnceOperator,
148             TokenKind::Require => RequireOperator,
149             TokenKind::Require_once => RequireOnceOperator,
150             TokenKind::Print => PrintOperator,
151             _ => panic!("not a unary operator"),
152         }
153     }
155     // Is this a token that can appear after an expression?
156     pub fn is_trailing_operator_token(token: TokenKind) -> bool {
157         match token {
158             TokenKind::PlusPlus
159             | TokenKind::MinusMinus
160             | TokenKind::LeftParen
161             | TokenKind::LeftBracket
162             | TokenKind::LeftBrace
163             | TokenKind::Plus
164             | TokenKind::Minus
165             | TokenKind::Ampersand
166             | TokenKind::BarGreaterThan
167             | TokenKind::Question
168             | TokenKind::QuestionQuestion
169             | TokenKind::QuestionQuestionEqual
170             | TokenKind::QuestionColon
171             | TokenKind::BarBar
172             | TokenKind::Carat
173             | TokenKind::AmpersandAmpersand
174             | TokenKind::Bar
175             | TokenKind::EqualEqual
176             | TokenKind::EqualEqualEqual
177             | TokenKind::ExclamationEqual
178             | TokenKind::ExclamationEqualEqual
179             | TokenKind::LessThanEqualGreaterThan
180             | TokenKind::LessThan
181             | TokenKind::LessThanEqual
182             | TokenKind::GreaterThan
183             | TokenKind::GreaterThanEqual
184             | TokenKind::LessThanLessThan
185             | TokenKind::GreaterThanGreaterThan
186             | TokenKind::Dot
187             | TokenKind::Star
188             | TokenKind::Slash
189             | TokenKind::Percent
190             | TokenKind::Instanceof
191             | TokenKind::Is
192             | TokenKind::As
193             | TokenKind::QuestionAs
194             | TokenKind::StarStar
195             | TokenKind::Equal
196             | TokenKind::PlusEqual
197             | TokenKind::MinusEqual
198             | TokenKind::StarEqual
199             | TokenKind::SlashEqual
200             | TokenKind::StarStarEqual
201             | TokenKind::DotEqual
202             | TokenKind::PercentEqual
203             | TokenKind::AmpersandEqual
204             | TokenKind::BarEqual
205             | TokenKind::CaratEqual
206             | TokenKind::LessThanLessThanEqual
207             | TokenKind::GreaterThanGreaterThanEqual
208             | TokenKind::MinusGreaterThan
209             | TokenKind::QuestionMinusGreaterThan
210             | TokenKind::ColonColon
211             | TokenKind::ColonAt => true,
212             _ => false,
213         }
214     }
216     pub fn trailing_from_token(token: TokenKind) -> Operator {
217         match token {
218             TokenKind::BarGreaterThan => PipeOperator,
219             TokenKind::Question => ConditionalQuestionOperator,
220             TokenKind::Colon => ConditionalColonOperator,
221             TokenKind::QuestionQuestion => CoalesceOperator,
222             TokenKind::QuestionQuestionEqual => CoalesceAssignmentOperator,
223             TokenKind::QuestionColon => DegenerateConditionalOperator,
224             TokenKind::BarBar => LogicalOrOperator,
225             TokenKind::Carat => ExclusiveOrOperator,
226             TokenKind::AmpersandAmpersand => LogicalAndOperator,
227             TokenKind::Bar => OrOperator,
228             TokenKind::Ampersand => AndOperator,
229             TokenKind::EqualEqual => EqualOperator,
230             TokenKind::EqualEqualEqual => StrictEqualOperator,
231             TokenKind::ExclamationEqual => NotEqualOperator,
232             TokenKind::ExclamationEqualEqual => StrictNotEqualOperator,
233             TokenKind::LessThan => LessThanOperator,
234             TokenKind::LessThanEqualGreaterThan => SpaceshipOperator,
235             TokenKind::LessThanEqual => LessThanOrEqualOperator,
236             TokenKind::GreaterThan => GreaterThanOperator,
237             TokenKind::GreaterThanEqual => GreaterThanOrEqualOperator,
238             TokenKind::LessThanLessThan => LeftShiftOperator,
239             TokenKind::GreaterThanGreaterThan => RightShiftOperator,
240             TokenKind::Plus => AdditionOperator,
241             TokenKind::Minus => SubtractionOperator,
242             TokenKind::Dot => ConcatenationOperator,
243             TokenKind::Star => MultiplicationOperator,
244             TokenKind::Slash => DivisionOperator,
245             TokenKind::Percent => RemainderOperator,
246             TokenKind::Instanceof => InstanceofOperator,
247             TokenKind::Is => IsOperator,
248             TokenKind::As => AsOperator,
249             TokenKind::QuestionAs => NullableAsOperator,
250             TokenKind::StarStar => ExponentOperator,
251             TokenKind::Equal => AssignmentOperator,
252             TokenKind::PlusEqual => AdditionAssignmentOperator,
253             TokenKind::MinusEqual => SubtractionAssignmentOperator,
254             TokenKind::StarEqual => MultiplicationAssignmentOperator,
255             TokenKind::SlashEqual => DivisionAssignmentOperator,
256             TokenKind::StarStarEqual => ExponentiationAssignmentOperator,
257             TokenKind::DotEqual => ConcatenationAssignmentOperator,
258             TokenKind::PercentEqual => RemainderAssignmentOperator,
259             TokenKind::AmpersandEqual => AndAssignmentOperator,
260             TokenKind::BarEqual => OrAssignmentOperator,
261             TokenKind::CaratEqual => ExclusiveOrAssignmentOperator,
262             TokenKind::LessThanLessThanEqual => LeftShiftAssignmentOperator,
263             TokenKind::GreaterThanGreaterThanEqual => RightShiftAssignmentOperator,
264             TokenKind::MinusGreaterThan => MemberSelectionOperator,
265             TokenKind::QuestionMinusGreaterThan => NullSafeMemberSelectionOperator,
266             TokenKind::ColonColon => ScopeResolutionOperator,
267             TokenKind::PlusPlus => PostfixIncrementOperator,
268             TokenKind::MinusMinus => PostfixDecrementOperator,
269             TokenKind::LeftParen => FunctionCallOperator,
270             TokenKind::LeftBracket => IndexingOperator,
271             TokenKind::LeftBrace => IndexingOperator,
272             TokenKind::ColonAt => ScopeResolutionOperator,
273             _ => panic!("not a trailing operator"),
274         }
275     }
277     pub fn is_binary_operator_token(token: TokenKind) -> bool {
278         match token {
279             TokenKind::Plus
280             | TokenKind::Minus
281             | TokenKind::Ampersand
282             | TokenKind::BarGreaterThan
283             | TokenKind::QuestionQuestion
284             | TokenKind::QuestionQuestionEqual
285             | TokenKind::QuestionColon
286             | TokenKind::BarBar
287             | TokenKind::Carat
288             | TokenKind::AmpersandAmpersand
289             | TokenKind::Bar
290             | TokenKind::EqualEqual
291             | TokenKind::EqualEqualEqual
292             | TokenKind::ExclamationEqual
293             | TokenKind::ExclamationEqualEqual
294             | TokenKind::LessThanEqualGreaterThan
295             | TokenKind::LessThan
296             | TokenKind::LessThanEqual
297             | TokenKind::GreaterThan
298             | TokenKind::GreaterThanEqual
299             | TokenKind::LessThanLessThan
300             | TokenKind::GreaterThanGreaterThan
301             | TokenKind::Dot
302             | TokenKind::Star
303             | TokenKind::Slash
304             | TokenKind::Percent
305             | TokenKind::StarStar
306             | TokenKind::Equal
307             | TokenKind::PlusEqual
308             | TokenKind::MinusEqual
309             | TokenKind::StarEqual
310             | TokenKind::SlashEqual
311             | TokenKind::DotEqual
312             | TokenKind::PercentEqual
313             | TokenKind::AmpersandEqual
314             | TokenKind::BarEqual
315             | TokenKind::CaratEqual
316             | TokenKind::LessThanLessThanEqual
317             | TokenKind::GreaterThanGreaterThanEqual
318             | TokenKind::MinusGreaterThan
319             | TokenKind::QuestionMinusGreaterThan => true,
320             _ => false,
321         }
322     }
324     pub fn is_assignment(&self) -> bool {
325         match self {
326             AssignmentOperator
327             | AdditionAssignmentOperator
328             | SubtractionAssignmentOperator
329             | MultiplicationAssignmentOperator
330             | DivisionAssignmentOperator
331             | ExponentiationAssignmentOperator
332             | ConcatenationAssignmentOperator
333             | RemainderAssignmentOperator
334             | AndAssignmentOperator
335             | OrAssignmentOperator
336             | ExclusiveOrAssignmentOperator
337             | LeftShiftAssignmentOperator
338             | RightShiftAssignmentOperator
339             | CoalesceAssignmentOperator => true,
340             _ => false,
341         }
342     }
344     pub fn is_comparison(&self) -> bool {
345         match self {
346             EqualOperator
347             | StrictEqualOperator
348             | NotEqualOperator
349             | PhpNotEqualOperator
350             | StrictNotEqualOperator
351             | LessThanOperator
352             | LessThanOrEqualOperator
353             | GreaterThanOperator
354             | GreaterThanOrEqualOperator
355             | SpaceshipOperator => true,
356             _ => false,
357         }
358     }