blob: c7772428480a84decc252c039237b4bc0c080d06 [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
Alex Crichton62a0a592017-05-22 13:58:53 -07009ast_enum! {
David Tolnay05658502018-01-07 09:56:37 -080010 /// A binary operator: `+`, `+=`, `&`.
David Tolnay461d98e2018-01-07 11:07:19 -080011 ///
12 /// *This type is available if Syn is built with the `"derive"` or `"full"`
13 /// feature.*
Alex Crichton2e0229c2017-05-23 09:34:50 -070014 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -070015 pub enum BinOp {
16 /// The `+` operator (addition)
David Tolnayf8db7ba2017-11-11 22:52:16 -080017 Add(Token![+]),
Alex Crichton62a0a592017-05-22 13:58:53 -070018 /// The `-` operator (subtraction)
David Tolnayf8db7ba2017-11-11 22:52:16 -080019 Sub(Token![-]),
Alex Crichton62a0a592017-05-22 13:58:53 -070020 /// The `*` operator (multiplication)
David Tolnayf8db7ba2017-11-11 22:52:16 -080021 Mul(Token![*]),
Alex Crichton62a0a592017-05-22 13:58:53 -070022 /// The `/` operator (division)
David Tolnayf8db7ba2017-11-11 22:52:16 -080023 Div(Token![/]),
Alex Crichton62a0a592017-05-22 13:58:53 -070024 /// The `%` operator (modulus)
David Tolnayf8db7ba2017-11-11 22:52:16 -080025 Rem(Token![%]),
Alex Crichton62a0a592017-05-22 13:58:53 -070026 /// The `&&` operator (logical and)
David Tolnayf8db7ba2017-11-11 22:52:16 -080027 And(Token![&&]),
Alex Crichton62a0a592017-05-22 13:58:53 -070028 /// The `||` operator (logical or)
David Tolnayf8db7ba2017-11-11 22:52:16 -080029 Or(Token![||]),
Alex Crichton62a0a592017-05-22 13:58:53 -070030 /// The `^` operator (bitwise xor)
David Tolnayf8db7ba2017-11-11 22:52:16 -080031 BitXor(Token![^]),
Alex Crichton62a0a592017-05-22 13:58:53 -070032 /// The `&` operator (bitwise and)
David Tolnayf8db7ba2017-11-11 22:52:16 -080033 BitAnd(Token![&]),
Alex Crichton62a0a592017-05-22 13:58:53 -070034 /// The `|` operator (bitwise or)
David Tolnayf8db7ba2017-11-11 22:52:16 -080035 BitOr(Token![|]),
Alex Crichton62a0a592017-05-22 13:58:53 -070036 /// The `<<` operator (shift left)
David Tolnayf8db7ba2017-11-11 22:52:16 -080037 Shl(Token![<<]),
Alex Crichton62a0a592017-05-22 13:58:53 -070038 /// The `>>` operator (shift right)
David Tolnayf8db7ba2017-11-11 22:52:16 -080039 Shr(Token![>>]),
Alex Crichton62a0a592017-05-22 13:58:53 -070040 /// The `==` operator (equality)
David Tolnayf8db7ba2017-11-11 22:52:16 -080041 Eq(Token![==]),
Alex Crichton62a0a592017-05-22 13:58:53 -070042 /// The `<` operator (less than)
David Tolnayf8db7ba2017-11-11 22:52:16 -080043 Lt(Token![<]),
Alex Crichton62a0a592017-05-22 13:58:53 -070044 /// The `<=` operator (less than or equal to)
David Tolnayf8db7ba2017-11-11 22:52:16 -080045 Le(Token![<=]),
Alex Crichton62a0a592017-05-22 13:58:53 -070046 /// The `!=` operator (not equal to)
David Tolnayf8db7ba2017-11-11 22:52:16 -080047 Ne(Token![!=]),
Alex Crichton62a0a592017-05-22 13:58:53 -070048 /// The `>=` operator (greater than or equal to)
David Tolnayf8db7ba2017-11-11 22:52:16 -080049 Ge(Token![>=]),
Alex Crichton62a0a592017-05-22 13:58:53 -070050 /// The `>` operator (greater than)
David Tolnayf8db7ba2017-11-11 22:52:16 -080051 Gt(Token![>]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070052 /// The `+=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080053 AddEq(Token![+=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070054 /// The `-=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080055 SubEq(Token![-=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070056 /// The `*=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080057 MulEq(Token![*=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070058 /// The `/=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080059 DivEq(Token![/=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070060 /// The `%=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080061 RemEq(Token![%=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070062 /// The `^=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080063 BitXorEq(Token![^=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070064 /// The `&=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080065 BitAndEq(Token![&=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070066 /// The `|=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080067 BitOrEq(Token![|=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070068 /// The `<<=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080069 ShlEq(Token![<<=]),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070070 /// The `>>=` operator
David Tolnayf8db7ba2017-11-11 22:52:16 -080071 ShrEq(Token![>>=]),
Alex Crichton62a0a592017-05-22 13:58:53 -070072 }
David Tolnay3cb23a92016-10-07 23:02:21 -070073}
74
Alex Crichton62a0a592017-05-22 13:58:53 -070075ast_enum! {
David Tolnay05658502018-01-07 09:56:37 -080076 /// A unary operator: `*`, `!`, `-`.
David Tolnay461d98e2018-01-07 11:07:19 -080077 ///
78 /// *This type is available if Syn is built with the `"derive"` or `"full"`
79 /// feature.*
Alex Crichton2e0229c2017-05-23 09:34:50 -070080 #[cfg_attr(feature = "clone-impls", derive(Copy))]
Alex Crichton62a0a592017-05-22 13:58:53 -070081 pub enum UnOp {
82 /// The `*` operator for dereferencing
David Tolnayf8db7ba2017-11-11 22:52:16 -080083 Deref(Token![*]),
Alex Crichton62a0a592017-05-22 13:58:53 -070084 /// The `!` operator for logical inversion
David Tolnayf8db7ba2017-11-11 22:52:16 -080085 Not(Token![!]),
Alex Crichton62a0a592017-05-22 13:58:53 -070086 /// The `-` operator for negation
David Tolnayf8db7ba2017-11-11 22:52:16 -080087 Neg(Token![-]),
Alex Crichton62a0a592017-05-22 13:58:53 -070088 }
David Tolnay3cb23a92016-10-07 23:02:21 -070089}
90
91#[cfg(feature = "parsing")]
92pub mod parsing {
93 use super::*;
David Tolnay2a54cfb2018-08-26 18:54:19 -040094
95 use parse::{Parse, ParseStream, Result};
David Tolnay3cb23a92016-10-07 23:02:21 -070096
David Tolnay01218d12018-08-29 18:13:07 -070097 fn parse_binop(input: ParseStream) -> Result<BinOp> {
98 if input.peek(Token![&&]) {
99 input.parse().map(BinOp::And)
100 } else if input.peek(Token![||]) {
101 input.parse().map(BinOp::Or)
102 } else if input.peek(Token![<<]) {
103 input.parse().map(BinOp::Shl)
104 } else if input.peek(Token![>>]) {
105 input.parse().map(BinOp::Shr)
106 } else if input.peek(Token![==]) {
107 input.parse().map(BinOp::Eq)
108 } else if input.peek(Token![<=]) {
109 input.parse().map(BinOp::Le)
110 } else if input.peek(Token![!=]) {
111 input.parse().map(BinOp::Ne)
112 } else if input.peek(Token![>=]) {
113 input.parse().map(BinOp::Ge)
114 } else if input.peek(Token![+]) {
115 input.parse().map(BinOp::Add)
116 } else if input.peek(Token![-]) {
117 input.parse().map(BinOp::Sub)
118 } else if input.peek(Token![*]) {
119 input.parse().map(BinOp::Mul)
120 } else if input.peek(Token![/]) {
121 input.parse().map(BinOp::Div)
122 } else if input.peek(Token![%]) {
123 input.parse().map(BinOp::Rem)
124 } else if input.peek(Token![^]) {
125 input.parse().map(BinOp::BitXor)
126 } else if input.peek(Token![&]) {
127 input.parse().map(BinOp::BitAnd)
128 } else if input.peek(Token![|]) {
129 input.parse().map(BinOp::BitOr)
130 } else if input.peek(Token![<]) {
131 input.parse().map(BinOp::Lt)
132 } else if input.peek(Token![>]) {
133 input.parse().map(BinOp::Gt)
134 } else {
135 Err(input.error("expected binary operator"))
136 }
137 }
138
139 impl Parse for BinOp {
140 #[cfg(not(feature = "full"))]
141 fn parse(input: ParseStream) -> Result<Self> {
142 parse_binop(input)
David Tolnay2a54cfb2018-08-26 18:54:19 -0400143 }
David Tolnay3cb23a92016-10-07 23:02:21 -0700144
Alex Crichton954046c2017-05-30 21:49:42 -0700145 #[cfg(feature = "full")]
David Tolnay01218d12018-08-29 18:13:07 -0700146 fn parse(input: ParseStream) -> Result<Self> {
147 if input.peek(Token![+=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400148 input.parse().map(BinOp::AddEq)
David Tolnay01218d12018-08-29 18:13:07 -0700149 } else if input.peek(Token![-=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400150 input.parse().map(BinOp::SubEq)
David Tolnay01218d12018-08-29 18:13:07 -0700151 } else if input.peek(Token![*=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400152 input.parse().map(BinOp::MulEq)
David Tolnay01218d12018-08-29 18:13:07 -0700153 } else if input.peek(Token![/=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400154 input.parse().map(BinOp::DivEq)
David Tolnay01218d12018-08-29 18:13:07 -0700155 } else if input.peek(Token![%=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400156 input.parse().map(BinOp::RemEq)
David Tolnay01218d12018-08-29 18:13:07 -0700157 } else if input.peek(Token![^=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400158 input.parse().map(BinOp::BitXorEq)
David Tolnay01218d12018-08-29 18:13:07 -0700159 } else if input.peek(Token![&=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400160 input.parse().map(BinOp::BitAndEq)
David Tolnay01218d12018-08-29 18:13:07 -0700161 } else if input.peek(Token![|=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400162 input.parse().map(BinOp::BitOrEq)
David Tolnay01218d12018-08-29 18:13:07 -0700163 } else if input.peek(Token![<<=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400164 input.parse().map(BinOp::ShlEq)
David Tolnay01218d12018-08-29 18:13:07 -0700165 } else if input.peek(Token![>>=]) {
David Tolnay2a54cfb2018-08-26 18:54:19 -0400166 input.parse().map(BinOp::ShrEq)
167 } else {
David Tolnay01218d12018-08-29 18:13:07 -0700168 parse_binop(input)
David Tolnay2a54cfb2018-08-26 18:54:19 -0400169 }
170 }
Alex Crichton954046c2017-05-30 21:49:42 -0700171 }
David Tolnay438c9052016-10-07 23:24:48 -0700172
David Tolnay2a54cfb2018-08-26 18:54:19 -0400173 impl Parse for UnOp {
174 fn parse(input: ParseStream) -> Result<Self> {
175 let lookahead = input.lookahead1();
176 if lookahead.peek(Token![*]) {
177 input.parse().map(UnOp::Deref)
178 } else if lookahead.peek(Token![!]) {
179 input.parse().map(UnOp::Not)
180 } else if lookahead.peek(Token![-]) {
181 input.parse().map(UnOp::Neg)
182 } else {
183 Err(lookahead.error())
184 }
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800185 }
Alex Crichton954046c2017-05-30 21:49:42 -0700186 }
David Tolnay3cb23a92016-10-07 23:02:21 -0700187}
188
189#[cfg(feature = "printing")]
190mod printing {
191 use super::*;
Alex Crichtona74a1c82018-05-16 10:20:44 -0700192 use proc_macro2::TokenStream;
David Tolnay65fb5662018-05-20 20:02:28 -0700193 use quote::ToTokens;
David Tolnay3cb23a92016-10-07 23:02:21 -0700194
David Tolnay3cb23a92016-10-07 23:02:21 -0700195 impl ToTokens for BinOp {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700196 fn to_tokens(&self, tokens: &mut TokenStream) {
David Tolnay3cb23a92016-10-07 23:02:21 -0700197 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700198 BinOp::Add(ref t) => t.to_tokens(tokens),
199 BinOp::Sub(ref t) => t.to_tokens(tokens),
200 BinOp::Mul(ref t) => t.to_tokens(tokens),
201 BinOp::Div(ref t) => t.to_tokens(tokens),
202 BinOp::Rem(ref t) => t.to_tokens(tokens),
203 BinOp::And(ref t) => t.to_tokens(tokens),
204 BinOp::Or(ref t) => t.to_tokens(tokens),
205 BinOp::BitXor(ref t) => t.to_tokens(tokens),
206 BinOp::BitAnd(ref t) => t.to_tokens(tokens),
207 BinOp::BitOr(ref t) => t.to_tokens(tokens),
208 BinOp::Shl(ref t) => t.to_tokens(tokens),
209 BinOp::Shr(ref t) => t.to_tokens(tokens),
210 BinOp::Eq(ref t) => t.to_tokens(tokens),
211 BinOp::Lt(ref t) => t.to_tokens(tokens),
212 BinOp::Le(ref t) => t.to_tokens(tokens),
213 BinOp::Ne(ref t) => t.to_tokens(tokens),
214 BinOp::Ge(ref t) => t.to_tokens(tokens),
215 BinOp::Gt(ref t) => t.to_tokens(tokens),
216 BinOp::AddEq(ref t) => t.to_tokens(tokens),
217 BinOp::SubEq(ref t) => t.to_tokens(tokens),
218 BinOp::MulEq(ref t) => t.to_tokens(tokens),
219 BinOp::DivEq(ref t) => t.to_tokens(tokens),
220 BinOp::RemEq(ref t) => t.to_tokens(tokens),
221 BinOp::BitXorEq(ref t) => t.to_tokens(tokens),
222 BinOp::BitAndEq(ref t) => t.to_tokens(tokens),
223 BinOp::BitOrEq(ref t) => t.to_tokens(tokens),
224 BinOp::ShlEq(ref t) => t.to_tokens(tokens),
225 BinOp::ShrEq(ref t) => t.to_tokens(tokens),
David Tolnay3cb23a92016-10-07 23:02:21 -0700226 }
227 }
228 }
229
230 impl ToTokens for UnOp {
Alex Crichtona74a1c82018-05-16 10:20:44 -0700231 fn to_tokens(&self, tokens: &mut TokenStream) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700232 match *self {
233 UnOp::Deref(ref t) => t.to_tokens(tokens),
234 UnOp::Not(ref t) => t.to_tokens(tokens),
235 UnOp::Neg(ref t) => t.to_tokens(tokens),
236 }
David Tolnay3cb23a92016-10-07 23:02:21 -0700237 }
238 }
239}