#[allow(unused_macros)]
#[macro_export]
macro_rules! yer {
(
$struct_name:ident =>
let! $var_name:ident$(: $var_type:ty)? = $expression:expr;
$($tail:tt)*
) => {
$struct_name::bind($expression, &|$var_name $(: $var_type)?| {
yer!($struct_name => $($tail)*)
})
};
(
$struct_name:ident =>
do! $expression:expr;
$($tail:tt)*
) => {
$struct_name::bind($expression, &|_| {
yer!($struct_name => $($tail)*)
})
};
(
$struct_name:ident =>
let $var_name:ident $(: $var_type:ty)? = $expression:expr;
$($tail:tt)*
) => {
{
let $var_name $(: $var_type)? = $expression;
(yer!($struct_name => $($tail)*))
}
};
(
$struct_name:ident =>
do $expression:expr;
$($tail:tt)*
) => {
{
$expression;
yer!($struct_name => $($tail)*)
}
};
( $struct_name:ident => ret <$($gtype:ty),+> $expression:expr ) => {
$struct_name::ret::<$($gtype),+>($expression)
};
( $struct_name:ident => ret $expression:expr ) => {
$struct_name::ret($expression)
};
( $struct_name:ident => ret! $expression:expr ) => {
$struct_name::ret_from($expression)
};
( $struct_name:ident => ret! <$($gtype:ty),+> $expression:expr ) => {
$struct_name::ret_from::<$($gtype),+>($expression)
};
(
$struct_name:ident =>
yield! $expression:expr;
) => {
$struct_name::ret_yield_from($expression)
};
(
$struct_name:ident =>
yield! $expression:expr;
$($tail:tt)*
) => {
$struct_name::combine(
yer!($struct_name => $($tail)*),
$struct_name::ret_yield_from($expression)
)
};
(
$struct_name:ident =>
yield $expression:expr;
) => {
$struct_name::ret_yield($expression)
};
(
$struct_name:ident =>
yield $expression:expr;
$($tail:tt)*
) => {
$struct_name::combine(
yer!($struct_name => $($tail)*),
$struct_name::ret_yield($expression)
)
};
( run $struct_name:ident => $($tail:tt)* ) => {
$struct_name::run({yer!($struct_name => $($tail)*)})
};
( $struct_name:ident >> $($tail:tt)* ) => {
$struct_name::run({yer!($struct_name => $($tail)*)})
};
( $previous_struct_name:ident => $struct_name:ident => $($tail:tt)* ) => {
$previous_struct_name::ret(yer!($struct_name => $($tail)*))
};
( $previous_struct_name:ident => $struct_name:ident! => $($tail:tt)* ) => {
$previous_struct_name::ret_from(yer!($struct_name => $($tail)*))
};
(
$struct_name:ident =>
if ($if_expr:expr) {
$($if_block:tt)*
} else zero;
$($tail:tt)*
) => {
{
$struct_name::combine(
yer!($struct_name => $($tail)*),
if $if_expr {
yer!(
$struct_name =>
$($if_block)*
)
}
else { $struct_name::zero() }
)
}
};
(
$struct_name:ident =>
if ($if_expr:expr) {
$($if_block:tt)*
}
$( else if ($else_if_expr:expr) {
$($else_if_block:tt)*
})*
else {
$($else_block:tt)*
}
$($tail:tt)*
) => {
{
$struct_name::combine(
yer!($struct_name => $($tail)*),
if $if_expr {
yer!(
$struct_name =>
$($if_block)*
)
}
$(else if $else_if_expr {
yer!($struct_name => $($else_if_block)*)
})*
else {
yer!($struct_name => $($else_block)*)
}
)
}
};
( $struct_name:ident => ) => { };
}