]>
Commit | Line | Data |
---|---|---|
92a42be0 SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | use parse::token::{Token, BinOpToken, keywords}; | |
7453a54e | 11 | use ast::BinOpKind; |
92a42be0 SL |
12 | |
13 | /// Associative operator with precedence. | |
14 | /// | |
15 | /// This is the enum which specifies operator precedence and fixity to the parser. | |
16 | #[derive(Debug, PartialEq, Eq)] | |
17 | pub enum AssocOp { | |
18 | /// `+` | |
19 | Add, | |
20 | /// `-` | |
21 | Subtract, | |
22 | /// `*` | |
23 | Multiply, | |
24 | /// `/` | |
25 | Divide, | |
26 | /// `%` | |
27 | Modulus, | |
28 | /// `&&` | |
29 | LAnd, | |
30 | /// `||` | |
31 | LOr, | |
32 | /// `^` | |
33 | BitXor, | |
34 | /// `&` | |
35 | BitAnd, | |
36 | /// `|` | |
37 | BitOr, | |
38 | /// `<<` | |
39 | ShiftLeft, | |
40 | /// `>>` | |
41 | ShiftRight, | |
42 | /// `==` | |
43 | Equal, | |
44 | /// `<` | |
45 | Less, | |
46 | /// `<=` | |
47 | LessEqual, | |
48 | /// `!=` | |
49 | NotEqual, | |
50 | /// `>` | |
51 | Greater, | |
52 | /// `>=` | |
53 | GreaterEqual, | |
54 | /// `=` | |
55 | Assign, | |
56 | /// `<-` | |
57 | Inplace, | |
58 | /// `?=` where ? is one of the BinOpToken | |
59 | AssignOp(BinOpToken), | |
60 | /// `as` | |
61 | As, | |
62 | /// `..` range | |
9cc50fc6 | 63 | DotDot, |
54a0048b SL |
64 | /// `...` range |
65 | DotDotDot, | |
9cc50fc6 SL |
66 | /// `:` |
67 | Colon, | |
92a42be0 SL |
68 | } |
69 | ||
70 | #[derive(Debug, PartialEq, Eq)] | |
71 | pub enum Fixity { | |
72 | /// The operator is left-associative | |
73 | Left, | |
74 | /// The operator is right-associative | |
75 | Right, | |
76 | /// The operator is not associative | |
77 | None | |
78 | } | |
79 | ||
80 | impl AssocOp { | |
81 | /// Create a new AssocOP from a token | |
82 | pub fn from_token(t: &Token) -> Option<AssocOp> { | |
83 | use self::AssocOp::*; | |
84 | match *t { | |
85 | Token::BinOpEq(k) => Some(AssignOp(k)), | |
86 | Token::LArrow => Some(Inplace), | |
87 | Token::Eq => Some(Assign), | |
88 | Token::BinOp(BinOpToken::Star) => Some(Multiply), | |
89 | Token::BinOp(BinOpToken::Slash) => Some(Divide), | |
90 | Token::BinOp(BinOpToken::Percent) => Some(Modulus), | |
91 | Token::BinOp(BinOpToken::Plus) => Some(Add), | |
92 | Token::BinOp(BinOpToken::Minus) => Some(Subtract), | |
93 | Token::BinOp(BinOpToken::Shl) => Some(ShiftLeft), | |
94 | Token::BinOp(BinOpToken::Shr) => Some(ShiftRight), | |
95 | Token::BinOp(BinOpToken::And) => Some(BitAnd), | |
96 | Token::BinOp(BinOpToken::Caret) => Some(BitXor), | |
97 | Token::BinOp(BinOpToken::Or) => Some(BitOr), | |
98 | Token::Lt => Some(Less), | |
99 | Token::Le => Some(LessEqual), | |
100 | Token::Ge => Some(GreaterEqual), | |
101 | Token::Gt => Some(Greater), | |
102 | Token::EqEq => Some(Equal), | |
103 | Token::Ne => Some(NotEqual), | |
104 | Token::AndAnd => Some(LAnd), | |
105 | Token::OrOr => Some(LOr), | |
106 | Token::DotDot => Some(DotDot), | |
54a0048b | 107 | Token::DotDotDot => Some(DotDotDot), |
9cc50fc6 | 108 | Token::Colon => Some(Colon), |
92a42be0 SL |
109 | _ if t.is_keyword(keywords::As) => Some(As), |
110 | _ => None | |
111 | } | |
112 | } | |
113 | ||
7453a54e SL |
114 | /// Create a new AssocOp from ast::BinOpKind. |
115 | pub fn from_ast_binop(op: BinOpKind) -> Self { | |
92a42be0 SL |
116 | use self::AssocOp::*; |
117 | match op { | |
7453a54e SL |
118 | BinOpKind::Lt => Less, |
119 | BinOpKind::Gt => Greater, | |
120 | BinOpKind::Le => LessEqual, | |
121 | BinOpKind::Ge => GreaterEqual, | |
122 | BinOpKind::Eq => Equal, | |
123 | BinOpKind::Ne => NotEqual, | |
124 | BinOpKind::Mul => Multiply, | |
125 | BinOpKind::Div => Divide, | |
126 | BinOpKind::Rem => Modulus, | |
127 | BinOpKind::Add => Add, | |
128 | BinOpKind::Sub => Subtract, | |
129 | BinOpKind::Shl => ShiftLeft, | |
130 | BinOpKind::Shr => ShiftRight, | |
131 | BinOpKind::BitAnd => BitAnd, | |
132 | BinOpKind::BitXor => BitXor, | |
133 | BinOpKind::BitOr => BitOr, | |
134 | BinOpKind::And => LAnd, | |
135 | BinOpKind::Or => LOr | |
92a42be0 SL |
136 | } |
137 | } | |
138 | ||
139 | /// Gets the precedence of this operator | |
140 | pub fn precedence(&self) -> usize { | |
141 | use self::AssocOp::*; | |
142 | match *self { | |
9cc50fc6 | 143 | As | Colon => 14, |
92a42be0 SL |
144 | Multiply | Divide | Modulus => 13, |
145 | Add | Subtract => 12, | |
146 | ShiftLeft | ShiftRight => 11, | |
147 | BitAnd => 10, | |
148 | BitXor => 9, | |
149 | BitOr => 8, | |
150 | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => 7, | |
151 | LAnd => 6, | |
152 | LOr => 5, | |
54a0048b | 153 | DotDot | DotDotDot => 4, |
92a42be0 SL |
154 | Inplace => 3, |
155 | Assign | AssignOp(_) => 2, | |
156 | } | |
157 | } | |
158 | ||
159 | /// Gets the fixity of this operator | |
160 | pub fn fixity(&self) -> Fixity { | |
161 | use self::AssocOp::*; | |
162 | // NOTE: it is a bug to have an operators that has same precedence but different fixities! | |
163 | match *self { | |
164 | Inplace | Assign | AssignOp(_) => Fixity::Right, | |
165 | As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | | |
166 | BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | | |
9cc50fc6 | 167 | LAnd | LOr | Colon => Fixity::Left, |
54a0048b | 168 | DotDot | DotDotDot => Fixity::None |
92a42be0 SL |
169 | } |
170 | } | |
171 | ||
172 | pub fn is_comparison(&self) -> bool { | |
173 | use self::AssocOp::*; | |
174 | match *self { | |
175 | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true, | |
176 | Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract | | |
54a0048b SL |
177 | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | |
178 | DotDot | DotDotDot | Colon => false | |
92a42be0 SL |
179 | } |
180 | } | |
181 | ||
182 | pub fn is_assign_like(&self) -> bool { | |
183 | use self::AssocOp::*; | |
184 | match *self { | |
185 | Assign | AssignOp(_) | Inplace => true, | |
186 | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide | | |
187 | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | | |
54a0048b | 188 | LOr | DotDot | DotDotDot | Colon => false |
92a42be0 SL |
189 | } |
190 | } | |
191 | ||
7453a54e | 192 | pub fn to_ast_binop(&self) -> Option<BinOpKind> { |
92a42be0 SL |
193 | use self::AssocOp::*; |
194 | match *self { | |
7453a54e SL |
195 | Less => Some(BinOpKind::Lt), |
196 | Greater => Some(BinOpKind::Gt), | |
197 | LessEqual => Some(BinOpKind::Le), | |
198 | GreaterEqual => Some(BinOpKind::Ge), | |
199 | Equal => Some(BinOpKind::Eq), | |
200 | NotEqual => Some(BinOpKind::Ne), | |
201 | Multiply => Some(BinOpKind::Mul), | |
202 | Divide => Some(BinOpKind::Div), | |
203 | Modulus => Some(BinOpKind::Rem), | |
204 | Add => Some(BinOpKind::Add), | |
205 | Subtract => Some(BinOpKind::Sub), | |
206 | ShiftLeft => Some(BinOpKind::Shl), | |
207 | ShiftRight => Some(BinOpKind::Shr), | |
208 | BitAnd => Some(BinOpKind::BitAnd), | |
209 | BitXor => Some(BinOpKind::BitXor), | |
210 | BitOr => Some(BinOpKind::BitOr), | |
211 | LAnd => Some(BinOpKind::And), | |
212 | LOr => Some(BinOpKind::Or), | |
54a0048b | 213 | Inplace | Assign | AssignOp(_) | As | DotDot | DotDotDot | Colon => None |
92a42be0 SL |
214 | } |
215 | } | |
92a42be0 | 216 | } |