1 ast_enum! { 2 /// A binary operator: `+`, `+=`, `&`. 3 /// 4 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 5 /// feature.* 6 pub enum BinOp { 7 /// The `+` operator (addition) 8 Add(Token![+]), 9 /// The `-` operator (subtraction) 10 Sub(Token![-]), 11 /// The `*` operator (multiplication) 12 Mul(Token![*]), 13 /// The `/` operator (division) 14 Div(Token![/]), 15 /// The `%` operator (modulus) 16 Rem(Token![%]), 17 /// The `&&` operator (logical and) 18 And(Token![&&]), 19 /// The `||` operator (logical or) 20 Or(Token![||]), 21 /// The `^` operator (bitwise xor) 22 BitXor(Token![^]), 23 /// The `&` operator (bitwise and) 24 BitAnd(Token![&]), 25 /// The `|` operator (bitwise or) 26 BitOr(Token![|]), 27 /// The `<<` operator (shift left) 28 Shl(Token![<<]), 29 /// The `>>` operator (shift right) 30 Shr(Token![>>]), 31 /// The `==` operator (equality) 32 Eq(Token![==]), 33 /// The `<` operator (less than) 34 Lt(Token![<]), 35 /// The `<=` operator (less than or equal to) 36 Le(Token![<=]), 37 /// The `!=` operator (not equal to) 38 Ne(Token![!=]), 39 /// The `>=` operator (greater than or equal to) 40 Ge(Token![>=]), 41 /// The `>` operator (greater than) 42 Gt(Token![>]), 43 /// The `+=` operator 44 AddEq(Token![+=]), 45 /// The `-=` operator 46 SubEq(Token![-=]), 47 /// The `*=` operator 48 MulEq(Token![*=]), 49 /// The `/=` operator 50 DivEq(Token![/=]), 51 /// The `%=` operator 52 RemEq(Token![%=]), 53 /// The `^=` operator 54 BitXorEq(Token![^=]), 55 /// The `&=` operator 56 BitAndEq(Token![&=]), 57 /// The `|=` operator 58 BitOrEq(Token![|=]), 59 /// The `<<=` operator 60 ShlEq(Token![<<=]), 61 /// The `>>=` operator 62 ShrEq(Token![>>=]), 63 } 64 } 65 66 ast_enum! { 67 /// A unary operator: `*`, `!`, `-`. 68 /// 69 /// *This type is available only if Syn is built with the `"derive"` or `"full"` 70 /// feature.* 71 pub enum UnOp { 72 /// The `*` operator for dereferencing 73 Deref(Token![*]), 74 /// The `!` operator for logical inversion 75 Not(Token![!]), 76 /// The `-` operator for negation 77 Neg(Token![-]), 78 } 79 } 80 81 #[cfg(feature = "parsing")] 82 pub mod parsing { 83 use super::*; 84 use crate::parse::{Parse, ParseStream, Result}; 85 parse_binop(input: ParseStream) -> Result<BinOp>86 fn parse_binop(input: ParseStream) -> Result<BinOp> { 87 if input.peek(Token![&&]) { 88 input.parse().map(BinOp::And) 89 } else if input.peek(Token![||]) { 90 input.parse().map(BinOp::Or) 91 } else if input.peek(Token![<<]) { 92 input.parse().map(BinOp::Shl) 93 } else if input.peek(Token![>>]) { 94 input.parse().map(BinOp::Shr) 95 } else if input.peek(Token![==]) { 96 input.parse().map(BinOp::Eq) 97 } else if input.peek(Token![<=]) { 98 input.parse().map(BinOp::Le) 99 } else if input.peek(Token![!=]) { 100 input.parse().map(BinOp::Ne) 101 } else if input.peek(Token![>=]) { 102 input.parse().map(BinOp::Ge) 103 } else if input.peek(Token![+]) { 104 input.parse().map(BinOp::Add) 105 } else if input.peek(Token![-]) { 106 input.parse().map(BinOp::Sub) 107 } else if input.peek(Token![*]) { 108 input.parse().map(BinOp::Mul) 109 } else if input.peek(Token![/]) { 110 input.parse().map(BinOp::Div) 111 } else if input.peek(Token![%]) { 112 input.parse().map(BinOp::Rem) 113 } else if input.peek(Token![^]) { 114 input.parse().map(BinOp::BitXor) 115 } else if input.peek(Token![&]) { 116 input.parse().map(BinOp::BitAnd) 117 } else if input.peek(Token![|]) { 118 input.parse().map(BinOp::BitOr) 119 } else if input.peek(Token![<]) { 120 input.parse().map(BinOp::Lt) 121 } else if input.peek(Token![>]) { 122 input.parse().map(BinOp::Gt) 123 } else { 124 Err(input.error("expected binary operator")) 125 } 126 } 127 128 impl Parse for BinOp { 129 #[cfg(not(feature = "full"))] parse(input: ParseStream) -> Result<Self>130 fn parse(input: ParseStream) -> Result<Self> { 131 parse_binop(input) 132 } 133 134 #[cfg(feature = "full")] parse(input: ParseStream) -> Result<Self>135 fn parse(input: ParseStream) -> Result<Self> { 136 if input.peek(Token![+=]) { 137 input.parse().map(BinOp::AddEq) 138 } else if input.peek(Token![-=]) { 139 input.parse().map(BinOp::SubEq) 140 } else if input.peek(Token![*=]) { 141 input.parse().map(BinOp::MulEq) 142 } else if input.peek(Token![/=]) { 143 input.parse().map(BinOp::DivEq) 144 } else if input.peek(Token![%=]) { 145 input.parse().map(BinOp::RemEq) 146 } else if input.peek(Token![^=]) { 147 input.parse().map(BinOp::BitXorEq) 148 } else if input.peek(Token![&=]) { 149 input.parse().map(BinOp::BitAndEq) 150 } else if input.peek(Token![|=]) { 151 input.parse().map(BinOp::BitOrEq) 152 } else if input.peek(Token![<<=]) { 153 input.parse().map(BinOp::ShlEq) 154 } else if input.peek(Token![>>=]) { 155 input.parse().map(BinOp::ShrEq) 156 } else { 157 parse_binop(input) 158 } 159 } 160 } 161 162 impl Parse for UnOp { parse(input: ParseStream) -> Result<Self>163 fn parse(input: ParseStream) -> Result<Self> { 164 let lookahead = input.lookahead1(); 165 if lookahead.peek(Token![*]) { 166 input.parse().map(UnOp::Deref) 167 } else if lookahead.peek(Token![!]) { 168 input.parse().map(UnOp::Not) 169 } else if lookahead.peek(Token![-]) { 170 input.parse().map(UnOp::Neg) 171 } else { 172 Err(lookahead.error()) 173 } 174 } 175 } 176 } 177 178 #[cfg(feature = "printing")] 179 mod printing { 180 use super::*; 181 use proc_macro2::TokenStream; 182 use quote::ToTokens; 183 184 impl ToTokens for BinOp { to_tokens(&self, tokens: &mut TokenStream)185 fn to_tokens(&self, tokens: &mut TokenStream) { 186 match self { 187 BinOp::Add(t) => t.to_tokens(tokens), 188 BinOp::Sub(t) => t.to_tokens(tokens), 189 BinOp::Mul(t) => t.to_tokens(tokens), 190 BinOp::Div(t) => t.to_tokens(tokens), 191 BinOp::Rem(t) => t.to_tokens(tokens), 192 BinOp::And(t) => t.to_tokens(tokens), 193 BinOp::Or(t) => t.to_tokens(tokens), 194 BinOp::BitXor(t) => t.to_tokens(tokens), 195 BinOp::BitAnd(t) => t.to_tokens(tokens), 196 BinOp::BitOr(t) => t.to_tokens(tokens), 197 BinOp::Shl(t) => t.to_tokens(tokens), 198 BinOp::Shr(t) => t.to_tokens(tokens), 199 BinOp::Eq(t) => t.to_tokens(tokens), 200 BinOp::Lt(t) => t.to_tokens(tokens), 201 BinOp::Le(t) => t.to_tokens(tokens), 202 BinOp::Ne(t) => t.to_tokens(tokens), 203 BinOp::Ge(t) => t.to_tokens(tokens), 204 BinOp::Gt(t) => t.to_tokens(tokens), 205 BinOp::AddEq(t) => t.to_tokens(tokens), 206 BinOp::SubEq(t) => t.to_tokens(tokens), 207 BinOp::MulEq(t) => t.to_tokens(tokens), 208 BinOp::DivEq(t) => t.to_tokens(tokens), 209 BinOp::RemEq(t) => t.to_tokens(tokens), 210 BinOp::BitXorEq(t) => t.to_tokens(tokens), 211 BinOp::BitAndEq(t) => t.to_tokens(tokens), 212 BinOp::BitOrEq(t) => t.to_tokens(tokens), 213 BinOp::ShlEq(t) => t.to_tokens(tokens), 214 BinOp::ShrEq(t) => t.to_tokens(tokens), 215 } 216 } 217 } 218 219 impl ToTokens for UnOp { to_tokens(&self, tokens: &mut TokenStream)220 fn to_tokens(&self, tokens: &mut TokenStream) { 221 match self { 222 UnOp::Deref(t) => t.to_tokens(tokens), 223 UnOp::Not(t) => t.to_tokens(tokens), 224 UnOp::Neg(t) => t.to_tokens(tokens), 225 } 226 } 227 } 228 } 229