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