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