1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 3 ast_enum! { 4 /// A binary operator: `+`, `+=`, `&`. 5 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 6 #[non_exhaustive] 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 AddAssign(Token![+=]), 46 /// The `-=` operator 47 SubAssign(Token![-=]), 48 /// The `*=` operator 49 MulAssign(Token![*=]), 50 /// The `/=` operator 51 DivAssign(Token![/=]), 52 /// The `%=` operator 53 RemAssign(Token![%=]), 54 /// The `^=` operator 55 BitXorAssign(Token![^=]), 56 /// The `&=` operator 57 BitAndAssign(Token![&=]), 58 /// The `|=` operator 59 BitOrAssign(Token![|=]), 60 /// The `<<=` operator 61 ShlAssign(Token![<<=]), 62 /// The `>>=` operator 63 ShrAssign(Token![>>=]), 64 } 65 } 66 67 ast_enum! { 68 /// A unary operator: `*`, `!`, `-`. 69 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))] 70 #[non_exhaustive] 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(crate) mod parsing { 83 use crate::error::Result; 84 use crate::op::{BinOp, UnOp}; 85 use crate::parse::{Parse, ParseStream}; 86 87 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 88 impl Parse for BinOp { parse(input: ParseStream) -> Result<Self>89 fn parse(input: ParseStream) -> Result<Self> { 90 if input.peek(Token![+=]) { 91 input.parse().map(BinOp::AddAssign) 92 } else if input.peek(Token![-=]) { 93 input.parse().map(BinOp::SubAssign) 94 } else if input.peek(Token![*=]) { 95 input.parse().map(BinOp::MulAssign) 96 } else if input.peek(Token![/=]) { 97 input.parse().map(BinOp::DivAssign) 98 } else if input.peek(Token![%=]) { 99 input.parse().map(BinOp::RemAssign) 100 } else if input.peek(Token![^=]) { 101 input.parse().map(BinOp::BitXorAssign) 102 } else if input.peek(Token![&=]) { 103 input.parse().map(BinOp::BitAndAssign) 104 } else if input.peek(Token![|=]) { 105 input.parse().map(BinOp::BitOrAssign) 106 } else if input.peek(Token![<<=]) { 107 input.parse().map(BinOp::ShlAssign) 108 } else if input.peek(Token![>>=]) { 109 input.parse().map(BinOp::ShrAssign) 110 } else if input.peek(Token![&&]) { 111 input.parse().map(BinOp::And) 112 } else if input.peek(Token![||]) { 113 input.parse().map(BinOp::Or) 114 } else if input.peek(Token![<<]) { 115 input.parse().map(BinOp::Shl) 116 } else if input.peek(Token![>>]) { 117 input.parse().map(BinOp::Shr) 118 } else if input.peek(Token![==]) { 119 input.parse().map(BinOp::Eq) 120 } else if input.peek(Token![<=]) { 121 input.parse().map(BinOp::Le) 122 } else if input.peek(Token![!=]) { 123 input.parse().map(BinOp::Ne) 124 } else if input.peek(Token![>=]) { 125 input.parse().map(BinOp::Ge) 126 } else if input.peek(Token![+]) { 127 input.parse().map(BinOp::Add) 128 } else if input.peek(Token![-]) { 129 input.parse().map(BinOp::Sub) 130 } else if input.peek(Token![*]) { 131 input.parse().map(BinOp::Mul) 132 } else if input.peek(Token![/]) { 133 input.parse().map(BinOp::Div) 134 } else if input.peek(Token![%]) { 135 input.parse().map(BinOp::Rem) 136 } else if input.peek(Token![^]) { 137 input.parse().map(BinOp::BitXor) 138 } else if input.peek(Token![&]) { 139 input.parse().map(BinOp::BitAnd) 140 } else if input.peek(Token![|]) { 141 input.parse().map(BinOp::BitOr) 142 } else if input.peek(Token![<]) { 143 input.parse().map(BinOp::Lt) 144 } else if input.peek(Token![>]) { 145 input.parse().map(BinOp::Gt) 146 } else { 147 Err(input.error("expected binary operator")) 148 } 149 } 150 } 151 152 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))] 153 impl Parse for UnOp { parse(input: ParseStream) -> Result<Self>154 fn parse(input: ParseStream) -> Result<Self> { 155 let lookahead = input.lookahead1(); 156 if lookahead.peek(Token![*]) { 157 input.parse().map(UnOp::Deref) 158 } else if lookahead.peek(Token![!]) { 159 input.parse().map(UnOp::Not) 160 } else if lookahead.peek(Token![-]) { 161 input.parse().map(UnOp::Neg) 162 } else { 163 Err(lookahead.error()) 164 } 165 } 166 } 167 } 168 169 #[cfg(feature = "printing")] 170 mod printing { 171 use crate::op::{BinOp, UnOp}; 172 use proc_macro2::TokenStream; 173 use quote::ToTokens; 174 175 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 176 impl ToTokens for BinOp { to_tokens(&self, tokens: &mut TokenStream)177 fn to_tokens(&self, tokens: &mut TokenStream) { 178 match self { 179 BinOp::Add(t) => t.to_tokens(tokens), 180 BinOp::Sub(t) => t.to_tokens(tokens), 181 BinOp::Mul(t) => t.to_tokens(tokens), 182 BinOp::Div(t) => t.to_tokens(tokens), 183 BinOp::Rem(t) => t.to_tokens(tokens), 184 BinOp::And(t) => t.to_tokens(tokens), 185 BinOp::Or(t) => t.to_tokens(tokens), 186 BinOp::BitXor(t) => t.to_tokens(tokens), 187 BinOp::BitAnd(t) => t.to_tokens(tokens), 188 BinOp::BitOr(t) => t.to_tokens(tokens), 189 BinOp::Shl(t) => t.to_tokens(tokens), 190 BinOp::Shr(t) => t.to_tokens(tokens), 191 BinOp::Eq(t) => t.to_tokens(tokens), 192 BinOp::Lt(t) => t.to_tokens(tokens), 193 BinOp::Le(t) => t.to_tokens(tokens), 194 BinOp::Ne(t) => t.to_tokens(tokens), 195 BinOp::Ge(t) => t.to_tokens(tokens), 196 BinOp::Gt(t) => t.to_tokens(tokens), 197 BinOp::AddAssign(t) => t.to_tokens(tokens), 198 BinOp::SubAssign(t) => t.to_tokens(tokens), 199 BinOp::MulAssign(t) => t.to_tokens(tokens), 200 BinOp::DivAssign(t) => t.to_tokens(tokens), 201 BinOp::RemAssign(t) => t.to_tokens(tokens), 202 BinOp::BitXorAssign(t) => t.to_tokens(tokens), 203 BinOp::BitAndAssign(t) => t.to_tokens(tokens), 204 BinOp::BitOrAssign(t) => t.to_tokens(tokens), 205 BinOp::ShlAssign(t) => t.to_tokens(tokens), 206 BinOp::ShrAssign(t) => t.to_tokens(tokens), 207 } 208 } 209 } 210 211 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))] 212 impl ToTokens for UnOp { to_tokens(&self, tokens: &mut TokenStream)213 fn to_tokens(&self, tokens: &mut TokenStream) { 214 match self { 215 UnOp::Deref(t) => t.to_tokens(tokens), 216 UnOp::Not(t) => t.to_tokens(tokens), 217 UnOp::Neg(t) => t.to_tokens(tokens), 218 } 219 } 220 } 221 } 222