1ast_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
67ast_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")]
84pub mod parsing {
85 use super::*;
86 use crate::parse::{Parse, ParseStream, Result};
87
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"))]
133 fn parse(input: ParseStream) -> Result<Self> {
134 parse_binop(input)
135 }
136
137 #[cfg(feature = "full")]
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 {
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")]
183mod 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 {
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 {
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