#[macro_export]
macro_rules! wtflip {
(@as_statement mut $ident:ident := $($expr:tt)+) => {
let mut $ident = wtflip!(@as_expr $($expr)+);
};
(@as_statement $ident:ident $(: $(@$($_:tt)* $declaration:tt)?)?= $($expr:tt)+) => {
$($($declaration)? let)? $ident = wtflip!(@as_expr $($expr)+);
};
(@as_statement @{ $($compat:tt)* }) => ($($compat)*);
(@as_expr @ $(:: $(@$($_:tt)* $prefixed:tt)?)? $ident:ident $(:: $path:ident)* $(($($args:tt)*))?) => (
$crate::args_splitter!(
[$($($prefixed)? ::)? $ident $(:: $path)*!]
[$crate::wtflip!]
[]
[]
[$($($args)*)?]
);
);
(@as_expr $($tokens:tt)*) => (wtflip!(@callback [] [] @as_expr $($tokens)*));
(@callback [$($cb:tt)*] [$($args:tt)*]
@as_expr $lit:literal $($tail:tt)*
) => (wtflip!(@callback [$($cb)*] [$($args)* [$lit]] $($tail)*));
(@callback [$($cb:tt)*] [$($args:tt)*]
@as_expr @{ $($tokens:tt)* } $($tail:tt)*
) => (wtflip!(@callback [$($cb)*] [$($args)* [{ $($tokens)* }]]));
(@callback [$($cb:tt)*] [$([$($arg:tt)*])*]) => ($($cb)*($($($arg)*),*));
(@statement_accumulator [$($buffer:tt)*] ; $($tail:tt)*) => {
wtflip!(@as_statement $($buffer)*);
wtflip!($($tail)*);
};
(@statement_accumulator [$($buffer:tt)*] $token:tt $($tail:tt)*) => (wtflip!(
@statement_accumulator [$($buffer)* $token] $($tail)*
));
() => ();
($($tokens:tt)+) => (wtflip!(
@statement_accumulator [] $($tokens)*
));
}
#[macro_export]
macro_rules! args_splitter {
(
[$($wrap:tt)*]
[$($processor:tt)*]
[]
[$([ $($out:tt)* ])*]
[]
) => ($($processor)*(@callback [$($wrap)*] [] $(@as_expr $($out)*)*));
(
[$($wrap:tt)*]
[$($processor:tt)*]
[$($current:tt)*]
[$($out:tt)*]
[$(, $($rest:tt)*)?]
) => ($crate::args_splitter!(
[$($wrap)*]
[$($processor)*]
[]
[$($out)* [$($current)*]]
[$($($rest)*)?]
));
(
[$($wrap:tt)*]
[$($processor:tt)*]
[$($current:tt)*]
$out:tt
[$no_comma:tt $($rest:tt)*]
) => ($crate::args_splitter!(
[$($wrap)*]
[$($processor)*]
[$($current)* $no_comma]
$out
[$($rest)*]
));
}