#[macro_export]
macro_rules! variable {
($b:ident) => {{
$crate::Variable(stringify!($b).into(), None)
}};
($b:expr) => {{
$crate::Variable($b.into(), None)
}};
($b:ident, $ty:ident) => {{
$crate::Variable(stringify!($b).into(), Some(stringify!($ty).into()))
}};
($b:expr, $ty:ident) => {{
$crate::Variable($b.into(), Some(stringify!($ty).into()))
}};
}
#[macro_export]
macro_rules! var {
($b:ident) => {{
$crate::Expression::Var(variable!($b))
}};
($b:expr) => {{
$crate::Expression::Var(variable!($b))
}}
}
#[macro_export]
macro_rules! abs {
{. $body:ident} => {{
$crate::Expression::build_abs(1, vec![], Some(var!($body)))
}};
{. $body:expr} => {{
$crate::Expression::build_abs(1, vec![], Some($body.into()))
}};
{$($arg:ident : $ty:ident)* . $body:ident} => {{
let mut ids: Vec<$crate::Variable> = Vec::new();
$(ids.push(variable!($arg, $ty));)*
$crate::Expression::build_abs(1, ids, Some(var!($body)))
}};
{$($arg:ident)* . $body:ident} => {{
let mut ids: Vec<$crate::Variable> = Vec::new();
$(ids.push(variable!($arg));)*
$crate::Expression::build_abs(1, ids, Some(var!($body)))
}};
{$($arg:ident : $ty:ident)* . $body:expr} => {{
let mut ids: Vec<$crate::Variable> = Vec::new();
$(ids.push(variable!($arg, $ty));)*
$crate::Expression::build_abs(1, ids, Some($body.into()))
}};
{$($arg:ident)* . $body:expr} => {{
let mut ids: Vec<$crate::Variable> = Vec::new();
$(ids.push(variable!($arg));)*
$crate::Expression::build_abs(1, ids, Some($body.into()))
}};
}
#[macro_export]
macro_rules! app {
($func:ident, $arg:ident) => {{
$crate::Expression::App(
$crate::Application(box var!($func),
box var!($arg)))
}};
($func:ident, $arg:expr) => {{
$crate::Expression::App(
$crate::Application(box var!($func),
box $arg.clone().into()))
}};
($func:expr, $arg:ident) => {{
$crate::Expression::App(
$crate::Application(box $func.clone().into(),
box var!($arg)))
}};
($func:expr, $arg:expr) => {{
$crate::Expression::App(
$crate::Application(box $func.clone().into(),
box $arg.clone().into()))
}};
}
#[macro_export]
macro_rules! λ {
{. $body:ident} => {
abs!($body)
};
{. $body:expr} => {
abs!($body)
};
{$($arg:ident)* : $ty:ident . $body:ident} => {
abs!($($arg)* . $body)
};
{$($arg:ident)* . $body:ident} => {
abs!($($arg)* . $body)
};
{$($arg:ident)* : $ty:ident . $body:expr} => {{
abs!($($arg)* . $body)
}};
{$($arg:ident)* . $body:expr} => {{
abs!($($arg)* . $body)
}};
}
#[macro_export]
macro_rules! γ {
($func:ident, $arg:ident) => {
app!(var!($func), var!($arg))
};
($func:ident, $arg:expr) => {
app!(var!($func), $arg)
};
($func:expr, $arg:ident) => {
app!($func, var!($arg))
};
($func:expr, $arg:expr) => {
app!($func, $arg)
};
}
macro_rules! set {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(set!(@single $rest)),*]));
($($key:expr,)+) => {
set!($($key),+)
};
($($key:expr),*) => {
{
let _cap = set!(@count $($key),*);
let mut _set = ::std::collections::HashSet::with_capacity(_cap);
$(
let _ = _set.insert($key);
)*
_set
}
};
}
#[cfg(test)]
macro_rules! map {
($($key:expr => $value:expr,)+) => {
map!($($key => $value),+)
};
($($key:expr => $value:expr),*) => {
{
let mut _map = ::std::collections::HashMap::new();
$(
let _ = _map.insert($key, $value);
)*
_map
}
};
}