aboutsummaryrefslogtreecommitdiff
path: root/syn/src/op.rs
diff options
context:
space:
mode:
Diffstat (limited to 'syn/src/op.rs')
-rw-r--r--syn/src/op.rs231
1 files changed, 231 insertions, 0 deletions
diff --git a/syn/src/op.rs b/syn/src/op.rs
new file mode 100644
index 0000000..49fb853
--- /dev/null
+++ b/syn/src/op.rs
@@ -0,0 +1,231 @@
+ast_enum! {
+ /// A binary operator: `+`, `+=`, `&`.
+ ///
+ /// *This type is available if Syn is built with the `"derive"` or `"full"`
+ /// feature.*
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
+ pub enum BinOp {
+ /// The `+` operator (addition)
+ Add(Token![+]),
+ /// The `-` operator (subtraction)
+ Sub(Token![-]),
+ /// The `*` operator (multiplication)
+ Mul(Token![*]),
+ /// The `/` operator (division)
+ Div(Token![/]),
+ /// The `%` operator (modulus)
+ Rem(Token![%]),
+ /// The `&&` operator (logical and)
+ And(Token![&&]),
+ /// The `||` operator (logical or)
+ Or(Token![||]),
+ /// The `^` operator (bitwise xor)
+ BitXor(Token![^]),
+ /// The `&` operator (bitwise and)
+ BitAnd(Token![&]),
+ /// The `|` operator (bitwise or)
+ BitOr(Token![|]),
+ /// The `<<` operator (shift left)
+ Shl(Token![<<]),
+ /// The `>>` operator (shift right)
+ Shr(Token![>>]),
+ /// The `==` operator (equality)
+ Eq(Token![==]),
+ /// The `<` operator (less than)
+ Lt(Token![<]),
+ /// The `<=` operator (less than or equal to)
+ Le(Token![<=]),
+ /// The `!=` operator (not equal to)
+ Ne(Token![!=]),
+ /// The `>=` operator (greater than or equal to)
+ Ge(Token![>=]),
+ /// The `>` operator (greater than)
+ Gt(Token![>]),
+ /// The `+=` operator
+ AddEq(Token![+=]),
+ /// The `-=` operator
+ SubEq(Token![-=]),
+ /// The `*=` operator
+ MulEq(Token![*=]),
+ /// The `/=` operator
+ DivEq(Token![/=]),
+ /// The `%=` operator
+ RemEq(Token![%=]),
+ /// The `^=` operator
+ BitXorEq(Token![^=]),
+ /// The `&=` operator
+ BitAndEq(Token![&=]),
+ /// The `|=` operator
+ BitOrEq(Token![|=]),
+ /// The `<<=` operator
+ ShlEq(Token![<<=]),
+ /// The `>>=` operator
+ ShrEq(Token![>>=]),
+ }
+}
+
+ast_enum! {
+ /// A unary operator: `*`, `!`, `-`.
+ ///
+ /// *This type is available if Syn is built with the `"derive"` or `"full"`
+ /// feature.*
+ #[cfg_attr(feature = "clone-impls", derive(Copy))]
+ pub enum UnOp {
+ /// The `*` operator for dereferencing
+ Deref(Token![*]),
+ /// The `!` operator for logical inversion
+ Not(Token![!]),
+ /// The `-` operator for negation
+ Neg(Token![-]),
+ }
+}
+
+#[cfg(feature = "parsing")]
+pub mod parsing {
+ use super::*;
+
+ use crate::parse::{Parse, ParseStream, Result};
+
+ fn parse_binop(input: ParseStream) -> Result<BinOp> {
+ if input.peek(Token![&&]) {
+ input.parse().map(BinOp::And)
+ } else if input.peek(Token![||]) {
+ input.parse().map(BinOp::Or)
+ } else if input.peek(Token![<<]) {
+ input.parse().map(BinOp::Shl)
+ } else if input.peek(Token![>>]) {
+ input.parse().map(BinOp::Shr)
+ } else if input.peek(Token![==]) {
+ input.parse().map(BinOp::Eq)
+ } else if input.peek(Token![<=]) {
+ input.parse().map(BinOp::Le)
+ } else if input.peek(Token![!=]) {
+ input.parse().map(BinOp::Ne)
+ } else if input.peek(Token![>=]) {
+ input.parse().map(BinOp::Ge)
+ } else if input.peek(Token![+]) {
+ input.parse().map(BinOp::Add)
+ } else if input.peek(Token![-]) {
+ input.parse().map(BinOp::Sub)
+ } else if input.peek(Token![*]) {
+ input.parse().map(BinOp::Mul)
+ } else if input.peek(Token![/]) {
+ input.parse().map(BinOp::Div)
+ } else if input.peek(Token![%]) {
+ input.parse().map(BinOp::Rem)
+ } else if input.peek(Token![^]) {
+ input.parse().map(BinOp::BitXor)
+ } else if input.peek(Token![&]) {
+ input.parse().map(BinOp::BitAnd)
+ } else if input.peek(Token![|]) {
+ input.parse().map(BinOp::BitOr)
+ } else if input.peek(Token![<]) {
+ input.parse().map(BinOp::Lt)
+ } else if input.peek(Token![>]) {
+ input.parse().map(BinOp::Gt)
+ } else {
+ Err(input.error("expected binary operator"))
+ }
+ }
+
+ impl Parse for BinOp {
+ #[cfg(not(feature = "full"))]
+ fn parse(input: ParseStream) -> Result<Self> {
+ parse_binop(input)
+ }
+
+ #[cfg(feature = "full")]
+ fn parse(input: ParseStream) -> Result<Self> {
+ if input.peek(Token![+=]) {
+ input.parse().map(BinOp::AddEq)
+ } else if input.peek(Token![-=]) {
+ input.parse().map(BinOp::SubEq)
+ } else if input.peek(Token![*=]) {
+ input.parse().map(BinOp::MulEq)
+ } else if input.peek(Token![/=]) {
+ input.parse().map(BinOp::DivEq)
+ } else if input.peek(Token![%=]) {
+ input.parse().map(BinOp::RemEq)
+ } else if input.peek(Token![^=]) {
+ input.parse().map(BinOp::BitXorEq)
+ } else if input.peek(Token![&=]) {
+ input.parse().map(BinOp::BitAndEq)
+ } else if input.peek(Token![|=]) {
+ input.parse().map(BinOp::BitOrEq)
+ } else if input.peek(Token![<<=]) {
+ input.parse().map(BinOp::ShlEq)
+ } else if input.peek(Token![>>=]) {
+ input.parse().map(BinOp::ShrEq)
+ } else {
+ parse_binop(input)
+ }
+ }
+ }
+
+ impl Parse for UnOp {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(Token![*]) {
+ input.parse().map(UnOp::Deref)
+ } else if lookahead.peek(Token![!]) {
+ input.parse().map(UnOp::Not)
+ } else if lookahead.peek(Token![-]) {
+ input.parse().map(UnOp::Neg)
+ } else {
+ Err(lookahead.error())
+ }
+ }
+ }
+}
+
+#[cfg(feature = "printing")]
+mod printing {
+ use super::*;
+ use proc_macro2::TokenStream;
+ use quote::ToTokens;
+
+ impl ToTokens for BinOp {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ BinOp::Add(t) => t.to_tokens(tokens),
+ BinOp::Sub(t) => t.to_tokens(tokens),
+ BinOp::Mul(t) => t.to_tokens(tokens),
+ BinOp::Div(t) => t.to_tokens(tokens),
+ BinOp::Rem(t) => t.to_tokens(tokens),
+ BinOp::And(t) => t.to_tokens(tokens),
+ BinOp::Or(t) => t.to_tokens(tokens),
+ BinOp::BitXor(t) => t.to_tokens(tokens),
+ BinOp::BitAnd(t) => t.to_tokens(tokens),
+ BinOp::BitOr(t) => t.to_tokens(tokens),
+ BinOp::Shl(t) => t.to_tokens(tokens),
+ BinOp::Shr(t) => t.to_tokens(tokens),
+ BinOp::Eq(t) => t.to_tokens(tokens),
+ BinOp::Lt(t) => t.to_tokens(tokens),
+ BinOp::Le(t) => t.to_tokens(tokens),
+ BinOp::Ne(t) => t.to_tokens(tokens),
+ BinOp::Ge(t) => t.to_tokens(tokens),
+ BinOp::Gt(t) => t.to_tokens(tokens),
+ BinOp::AddEq(t) => t.to_tokens(tokens),
+ BinOp::SubEq(t) => t.to_tokens(tokens),
+ BinOp::MulEq(t) => t.to_tokens(tokens),
+ BinOp::DivEq(t) => t.to_tokens(tokens),
+ BinOp::RemEq(t) => t.to_tokens(tokens),
+ BinOp::BitXorEq(t) => t.to_tokens(tokens),
+ BinOp::BitAndEq(t) => t.to_tokens(tokens),
+ BinOp::BitOrEq(t) => t.to_tokens(tokens),
+ BinOp::ShlEq(t) => t.to_tokens(tokens),
+ BinOp::ShrEq(t) => t.to_tokens(tokens),
+ }
+ }
+ }
+
+ impl ToTokens for UnOp {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ match self {
+ UnOp::Deref(t) => t.to_tokens(tokens),
+ UnOp::Not(t) => t.to_tokens(tokens),
+ UnOp::Neg(t) => t.to_tokens(tokens),
+ }
+ }
+ }
+}