ast_enum! {
#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
#[non_exhaustive]
pub enum BinOp {
Add(Token![+]),
Sub(Token![-]),
Mul(Token![*]),
Div(Token![/]),
Rem(Token![%]),
And(Token![&&]),
Or(Token![||]),
BitXor(Token![^]),
BitAnd(Token![&]),
BitOr(Token![|]),
Shl(Token![<<]),
Shr(Token![>>]),
Eq(Token![==]),
Lt(Token![<]),
Le(Token![<=]),
Ne(Token![!=]),
Ge(Token![>=]),
Gt(Token![>]),
AddAssign(Token![+=]),
SubAssign(Token![-=]),
MulAssign(Token![*=]),
DivAssign(Token![/=]),
RemAssign(Token![%=]),
BitXorAssign(Token![^=]),
BitAndAssign(Token![&=]),
BitOrAssign(Token![|=]),
ShlAssign(Token![<<=]),
ShrAssign(Token![>>=]),
Equiv(Token![<==>]),
Imply(Token![==>]),
Exply(Token![<==]),
BigEq(Token![===]),
BigNe(Token![!==]),
ExtEq(Token![=~=]),
ExtNe(Token![!~=]),
ExtDeepEq(Token![=~~=]),
ExtDeepNe(Token![!~~=]),
}
}
ast_enum! {
#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
#[non_exhaustive]
pub enum UnOp {
Deref(Token![*]),
Not(Token![!]),
Neg(Token![-]),
Proof(Token![proof]),
Forall(Token![forall]),
Exists(Token![exists]),
Choose(Token![choose]),
}
}
#[cfg(feature = "parsing")]
pub(crate) mod parsing {
use crate::error::Result;
use crate::op::{BinOp, UnOp};
use crate::parse::{Parse, ParseStream};
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
impl Parse for BinOp {
fn parse(input: ParseStream) -> Result<Self> {
if input.peek(Token![<==>]) {
input.parse().map(BinOp::Equiv)
} else if input.peek(Token![==>]) {
input.parse().map(BinOp::Imply)
} else if input.peek(Token![<==]) {
input.parse().map(BinOp::Exply)
} else if input.peek(Token![===]) {
input.parse().map(BinOp::BigEq)
} else if input.peek(Token![!==]) {
input.parse().map(BinOp::BigNe)
} else if input.peek(Token![=~=]) {
input.parse().map(BinOp::ExtEq)
} else if input.peek(Token![!~=]) {
input.parse().map(BinOp::ExtNe)
} else if input.peek(Token![=~~=]) {
input.parse().map(BinOp::ExtDeepEq)
} else if input.peek(Token![!~~=]) {
input.parse().map(BinOp::ExtDeepNe)
} else if input.peek(Token![+=]) {
input.parse().map(BinOp::AddAssign)
} else if input.peek(Token![-=]) {
input.parse().map(BinOp::SubAssign)
} else if input.peek(Token![*=]) {
input.parse().map(BinOp::MulAssign)
} else if input.peek(Token![/=]) {
input.parse().map(BinOp::DivAssign)
} else if input.peek(Token![%=]) {
input.parse().map(BinOp::RemAssign)
} else if input.peek(Token![^=]) {
input.parse().map(BinOp::BitXorAssign)
} else if input.peek(Token![&=]) {
input.parse().map(BinOp::BitAndAssign)
} else if input.peek(Token![|=]) {
input.parse().map(BinOp::BitOrAssign)
} else if input.peek(Token![<<=]) {
input.parse().map(BinOp::ShlAssign)
} else if input.peek(Token![>>=]) {
input.parse().map(BinOp::ShrAssign)
} else 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"))
}
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
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 if lookahead.peek(Token![proof]) {
input.parse().map(UnOp::Proof)
} else if lookahead.peek(Token![forall]) {
input.parse().map(UnOp::Forall)
} else if lookahead.peek(Token![exists]) {
input.parse().map(UnOp::Exists)
} else if lookahead.peek(Token![choose]) {
input.parse().map(UnOp::Choose)
} else {
Err(lookahead.error())
}
}
}
}
#[cfg(feature = "printing")]
mod printing {
use crate::op::{BinOp, UnOp};
use proc_macro2::TokenStream;
use quote::ToTokens;
#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
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::AddAssign(t) => t.to_tokens(tokens),
BinOp::SubAssign(t) => t.to_tokens(tokens),
BinOp::MulAssign(t) => t.to_tokens(tokens),
BinOp::DivAssign(t) => t.to_tokens(tokens),
BinOp::RemAssign(t) => t.to_tokens(tokens),
BinOp::BitXorAssign(t) => t.to_tokens(tokens),
BinOp::BitAndAssign(t) => t.to_tokens(tokens),
BinOp::BitOrAssign(t) => t.to_tokens(tokens),
BinOp::ShlAssign(t) => t.to_tokens(tokens),
BinOp::ShrAssign(t) => t.to_tokens(tokens),
BinOp::Equiv(t) => t.to_tokens(tokens),
BinOp::Imply(t) => t.to_tokens(tokens),
BinOp::Exply(t) => t.to_tokens(tokens),
BinOp::BigEq(t) => t.to_tokens(tokens),
BinOp::BigNe(t) => t.to_tokens(tokens),
BinOp::ExtEq(t) => t.to_tokens(tokens),
BinOp::ExtNe(t) => t.to_tokens(tokens),
BinOp::ExtDeepEq(t) => t.to_tokens(tokens),
BinOp::ExtDeepNe(t) => t.to_tokens(tokens),
}
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
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),
UnOp::Proof(t) => t.to_tokens(tokens),
UnOp::Forall(t) => t.to_tokens(tokens),
UnOp::Exists(t) => t.to_tokens(tokens),
UnOp::Choose(t) => t.to_tokens(tokens),
}
}
}
}