1
1
use rustc_span:: kw;
2
2
3
- use crate :: ast:: { self , BinOpKind } ;
3
+ use crate :: ast:: { self , BinOpKind , RangeLimits } ;
4
4
use crate :: token:: { self , BinOpToken , Token } ;
5
5
6
- /// Associative operator with precedence.
7
- ///
8
- /// This is the enum which specifies operator precedence and fixity to the parser.
6
+ /// Associative operator.
9
7
#[ derive( Copy , Clone , PartialEq , Debug ) ]
10
8
pub enum AssocOp {
11
- /// `+`
12
- Add ,
13
- /// `-`
14
- Subtract ,
15
- /// `*`
16
- Multiply ,
17
- /// `/`
18
- Divide ,
19
- /// `%`
20
- Modulus ,
21
- /// `&&`
22
- LAnd ,
23
- /// `||`
24
- LOr ,
25
- /// `^`
26
- BitXor ,
27
- /// `&`
28
- BitAnd ,
29
- /// `|`
30
- BitOr ,
31
- /// `<<`
32
- ShiftLeft ,
33
- /// `>>`
34
- ShiftRight ,
35
- /// `==`
36
- Equal ,
37
- /// `<`
38
- Less ,
39
- /// `<=`
40
- LessEqual ,
41
- /// `!=`
42
- NotEqual ,
43
- /// `>`
44
- Greater ,
45
- /// `>=`
46
- GreaterEqual ,
9
+ /// A binary op.
10
+ Binary ( BinOpKind ) ,
11
+ /// `?=` where ? is one of the assignable BinOps
12
+ AssignOp ( BinOpKind ) ,
47
13
/// `=`
48
14
Assign ,
49
- /// `?=` where ? is one of the BinOpToken
50
- AssignOp ( BinOpToken ) ,
51
15
/// `as`
52
- As ,
53
- /// `..` range
54
- DotDot ,
55
- /// `..=` range
56
- DotDotEq ,
16
+ Cast ,
17
+ /// `..` or `..=` range
18
+ Range ( RangeLimits ) ,
57
19
}
58
20
59
21
#[ derive( PartialEq , Debug ) ]
@@ -67,81 +29,56 @@ pub enum Fixity {
67
29
}
68
30
69
31
impl AssocOp {
70
- /// Creates a new AssocOP from a token
32
+ /// Creates a new AssocOp from a token.
71
33
pub fn from_token ( t : & Token ) -> Option < AssocOp > {
72
34
use AssocOp :: * ;
73
35
match t. kind {
74
- token:: BinOpEq ( k) => Some ( AssignOp ( k) ) ,
75
36
token:: Eq => Some ( Assign ) ,
76
- token:: BinOp ( BinOpToken :: Star ) => Some ( Multiply ) ,
77
- token:: BinOp ( BinOpToken :: Slash ) => Some ( Divide ) ,
78
- token:: BinOp ( BinOpToken :: Percent ) => Some ( Modulus ) ,
79
- token:: BinOp ( BinOpToken :: Plus ) => Some ( Add ) ,
80
- token:: BinOp ( BinOpToken :: Minus ) => Some ( Subtract ) ,
81
- token:: BinOp ( BinOpToken :: Shl ) => Some ( ShiftLeft ) ,
82
- token:: BinOp ( BinOpToken :: Shr ) => Some ( ShiftRight ) ,
83
- token:: BinOp ( BinOpToken :: And ) => Some ( BitAnd ) ,
84
- token:: BinOp ( BinOpToken :: Caret ) => Some ( BitXor ) ,
85
- token:: BinOp ( BinOpToken :: Or ) => Some ( BitOr ) ,
86
- token:: Lt => Some ( Less ) ,
87
- token:: Le => Some ( LessEqual ) ,
88
- token:: Ge => Some ( GreaterEqual ) ,
89
- token:: Gt => Some ( Greater ) ,
90
- token:: EqEq => Some ( Equal ) ,
91
- token:: Ne => Some ( NotEqual ) ,
92
- token:: AndAnd => Some ( LAnd ) ,
93
- token:: OrOr => Some ( LOr ) ,
94
- token:: DotDot => Some ( DotDot ) ,
95
- token:: DotDotEq => Some ( DotDotEq ) ,
37
+ token:: BinOp ( BinOpToken :: Plus ) => Some ( Binary ( BinOpKind :: Add ) ) ,
38
+ token:: BinOp ( BinOpToken :: Minus ) => Some ( Binary ( BinOpKind :: Sub ) ) ,
39
+ token:: BinOp ( BinOpToken :: Star ) => Some ( Binary ( BinOpKind :: Mul ) ) ,
40
+ token:: BinOp ( BinOpToken :: Slash ) => Some ( Binary ( BinOpKind :: Div ) ) ,
41
+ token:: BinOp ( BinOpToken :: Percent ) => Some ( Binary ( BinOpKind :: Rem ) ) ,
42
+ token:: BinOp ( BinOpToken :: Caret ) => Some ( Binary ( BinOpKind :: BitXor ) ) ,
43
+ token:: BinOp ( BinOpToken :: And ) => Some ( Binary ( BinOpKind :: BitAnd ) ) ,
44
+ token:: BinOp ( BinOpToken :: Or ) => Some ( Binary ( BinOpKind :: BitOr ) ) ,
45
+ token:: BinOp ( BinOpToken :: Shl ) => Some ( Binary ( BinOpKind :: Shl ) ) ,
46
+ token:: BinOp ( BinOpToken :: Shr ) => Some ( Binary ( BinOpKind :: Shr ) ) ,
47
+ token:: BinOpEq ( BinOpToken :: Plus ) => Some ( AssignOp ( BinOpKind :: Add ) ) ,
48
+ token:: BinOpEq ( BinOpToken :: Minus ) => Some ( AssignOp ( BinOpKind :: Sub ) ) ,
49
+ token:: BinOpEq ( BinOpToken :: Star ) => Some ( AssignOp ( BinOpKind :: Mul ) ) ,
50
+ token:: BinOpEq ( BinOpToken :: Slash ) => Some ( AssignOp ( BinOpKind :: Div ) ) ,
51
+ token:: BinOpEq ( BinOpToken :: Percent ) => Some ( AssignOp ( BinOpKind :: Rem ) ) ,
52
+ token:: BinOpEq ( BinOpToken :: Caret ) => Some ( AssignOp ( BinOpKind :: BitXor ) ) ,
53
+ token:: BinOpEq ( BinOpToken :: And ) => Some ( AssignOp ( BinOpKind :: BitAnd ) ) ,
54
+ token:: BinOpEq ( BinOpToken :: Or ) => Some ( AssignOp ( BinOpKind :: BitOr ) ) ,
55
+ token:: BinOpEq ( BinOpToken :: Shl ) => Some ( AssignOp ( BinOpKind :: Shl ) ) ,
56
+ token:: BinOpEq ( BinOpToken :: Shr ) => Some ( AssignOp ( BinOpKind :: Shr ) ) ,
57
+ token:: Lt => Some ( Binary ( BinOpKind :: Lt ) ) ,
58
+ token:: Le => Some ( Binary ( BinOpKind :: Le ) ) ,
59
+ token:: Ge => Some ( Binary ( BinOpKind :: Ge ) ) ,
60
+ token:: Gt => Some ( Binary ( BinOpKind :: Gt ) ) ,
61
+ token:: EqEq => Some ( Binary ( BinOpKind :: Eq ) ) ,
62
+ token:: Ne => Some ( Binary ( BinOpKind :: Ne ) ) ,
63
+ token:: AndAnd => Some ( Binary ( BinOpKind :: And ) ) ,
64
+ token:: OrOr => Some ( Binary ( BinOpKind :: Or ) ) ,
65
+ token:: DotDot => Some ( Range ( RangeLimits :: HalfOpen ) ) ,
96
66
// DotDotDot is no longer supported, but we need some way to display the error
97
- token:: DotDotDot => Some ( DotDotEq ) ,
67
+ token:: DotDotEq | token :: DotDotDot => Some ( Range ( RangeLimits :: Closed ) ) ,
98
68
// `<-` should probably be `< -`
99
- token:: LArrow => Some ( Less ) ,
100
- _ if t. is_keyword ( kw:: As ) => Some ( As ) ,
69
+ token:: LArrow => Some ( Binary ( BinOpKind :: Lt ) ) ,
70
+ _ if t. is_keyword ( kw:: As ) => Some ( Cast ) ,
101
71
_ => None ,
102
72
}
103
73
}
104
74
105
- /// Creates a new AssocOp from ast::BinOpKind.
106
- pub fn from_ast_binop ( op : BinOpKind ) -> Self {
107
- use AssocOp :: * ;
108
- match op {
109
- BinOpKind :: Lt => Less ,
110
- BinOpKind :: Gt => Greater ,
111
- BinOpKind :: Le => LessEqual ,
112
- BinOpKind :: Ge => GreaterEqual ,
113
- BinOpKind :: Eq => Equal ,
114
- BinOpKind :: Ne => NotEqual ,
115
- BinOpKind :: Mul => Multiply ,
116
- BinOpKind :: Div => Divide ,
117
- BinOpKind :: Rem => Modulus ,
118
- BinOpKind :: Add => Add ,
119
- BinOpKind :: Sub => Subtract ,
120
- BinOpKind :: Shl => ShiftLeft ,
121
- BinOpKind :: Shr => ShiftRight ,
122
- BinOpKind :: BitAnd => BitAnd ,
123
- BinOpKind :: BitXor => BitXor ,
124
- BinOpKind :: BitOr => BitOr ,
125
- BinOpKind :: And => LAnd ,
126
- BinOpKind :: Or => LOr ,
127
- }
128
- }
129
-
130
75
/// Gets the precedence of this operator
131
76
pub fn precedence ( & self ) -> ExprPrecedence {
132
77
use AssocOp :: * ;
133
78
match * self {
134
- As => ExprPrecedence :: Cast ,
135
- Multiply | Divide | Modulus => ExprPrecedence :: Product ,
136
- Add | Subtract => ExprPrecedence :: Sum ,
137
- ShiftLeft | ShiftRight => ExprPrecedence :: Shift ,
138
- BitAnd => ExprPrecedence :: BitAnd ,
139
- BitXor => ExprPrecedence :: BitXor ,
140
- BitOr => ExprPrecedence :: BitOr ,
141
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => ExprPrecedence :: Compare ,
142
- LAnd => ExprPrecedence :: LAnd ,
143
- LOr => ExprPrecedence :: LOr ,
144
- DotDot | DotDotEq => ExprPrecedence :: Range ,
79
+ Cast => ExprPrecedence :: Cast ,
80
+ Binary ( bin_op) => bin_op. precedence ( ) ,
81
+ Range ( _) => ExprPrecedence :: Range ,
145
82
Assign | AssignOp ( _) => ExprPrecedence :: Assign ,
146
83
}
147
84
}
@@ -152,57 +89,25 @@ impl AssocOp {
152
89
// NOTE: it is a bug to have an operators that has same precedence but different fixities!
153
90
match * self {
154
91
Assign | AssignOp ( _) => Fixity :: Right ,
155
- As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd
156
- | BitXor | BitOr | LAnd | LOr => Fixity :: Left ,
157
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | DotDot | DotDotEq => {
158
- Fixity :: None
159
- }
92
+ Binary ( binop) => binop. fixity ( ) ,
93
+ Cast => Fixity :: Left ,
94
+ Range ( _) => Fixity :: None ,
160
95
}
161
96
}
162
97
163
98
pub fn is_comparison ( & self ) -> bool {
164
99
use AssocOp :: * ;
165
100
match * self {
166
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true ,
167
- Assign | AssignOp ( _) | As | Multiply | Divide | Modulus | Add | Subtract
168
- | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq => {
169
- false
170
- }
101
+ Binary ( binop) => binop. is_comparison ( ) ,
102
+ Assign | AssignOp ( _) | Cast | Range ( _) => false ,
171
103
}
172
104
}
173
105
174
106
pub fn is_assign_like ( & self ) -> bool {
175
107
use AssocOp :: * ;
176
108
match * self {
177
109
Assign | AssignOp ( _) => true ,
178
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply
179
- | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor
180
- | BitOr | LAnd | LOr | DotDot | DotDotEq => false ,
181
- }
182
- }
183
-
184
- pub fn to_ast_binop ( & self ) -> Option < BinOpKind > {
185
- use AssocOp :: * ;
186
- match * self {
187
- Less => Some ( BinOpKind :: Lt ) ,
188
- Greater => Some ( BinOpKind :: Gt ) ,
189
- LessEqual => Some ( BinOpKind :: Le ) ,
190
- GreaterEqual => Some ( BinOpKind :: Ge ) ,
191
- Equal => Some ( BinOpKind :: Eq ) ,
192
- NotEqual => Some ( BinOpKind :: Ne ) ,
193
- Multiply => Some ( BinOpKind :: Mul ) ,
194
- Divide => Some ( BinOpKind :: Div ) ,
195
- Modulus => Some ( BinOpKind :: Rem ) ,
196
- Add => Some ( BinOpKind :: Add ) ,
197
- Subtract => Some ( BinOpKind :: Sub ) ,
198
- ShiftLeft => Some ( BinOpKind :: Shl ) ,
199
- ShiftRight => Some ( BinOpKind :: Shr ) ,
200
- BitAnd => Some ( BinOpKind :: BitAnd ) ,
201
- BitXor => Some ( BinOpKind :: BitXor ) ,
202
- BitOr => Some ( BinOpKind :: BitOr ) ,
203
- LAnd => Some ( BinOpKind :: And ) ,
204
- LOr => Some ( BinOpKind :: Or ) ,
205
- Assign | AssignOp ( _) | As | DotDot | DotDotEq => None ,
110
+ Cast | Binary ( _) | Range ( _) => false ,
206
111
}
207
112
}
208
113
@@ -212,20 +117,23 @@ impl AssocOp {
212
117
/// parentheses while having a high degree of confidence on the correctness of the suggestion.
213
118
pub fn can_continue_expr_unambiguously ( & self ) -> bool {
214
119
use AssocOp :: * ;
120
+ use BinOpKind :: * ;
215
121
matches ! (
216
122
self ,
217
- BitXor | // `{ 42 } ^ 3`
218
123
Assign | // `{ 42 } = { 42 }`
219
- Divide | // `{ 42 } / 42`
220
- Modulus | // `{ 42 } % 2`
221
- ShiftRight | // `{ 42 } >> 2`
222
- LessEqual | // `{ 42 } <= 3`
223
- Greater | // `{ 42 } > 3`
224
- GreaterEqual | // `{ 42 } >= 3`
124
+ Binary (
125
+ BitXor | // `{ 42 } ^ 3`
126
+ Div | // `{ 42 } / 42`
127
+ Rem | // `{ 42 } % 2`
128
+ Shr | // `{ 42 } >> 2`
129
+ Le | // `{ 42 } <= 3`
130
+ Gt | // `{ 42 } > 3`
131
+ Ge // `{ 42 } >= 3`
132
+ ) |
225
133
AssignOp ( _) | // `{ 42 } +=`
226
134
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
227
135
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.
228
- As // `{ 42 } as usize`
136
+ Cast // `{ 42 } as usize`
229
137
)
230
138
}
231
139
}
0 commit comments