extern crate proc_macro;
extern crate proc_macro2;
mod tokens;
pub use tokens::Tokens;
mod to_tokens;
pub use to_tokens::{ToTokens, ByteStr};
pub mod __rt {
pub use proc_macro2::*;
pub fn parse(tokens: &mut ::Tokens, s: &str) {
let s: TokenStream = s.parse().expect("invalid token stream");
tokens.append_all(s.into_iter());
}
pub fn append_kind(tokens: &mut ::Tokens, kind: TokenNode) {
tokens.append(TokenTree {
span: Default::default(),
kind: kind,
})
}
}
#[macro_export]
macro_rules! quote {
() => {
$crate::Tokens::new()
};
($($tt:tt)+) => {
{
let mut _s = $crate::Tokens::new();
quote_each_token!(_s $($tt)*);
_s
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! pounded_var_names {
($finish:ident ($($found:ident)*) # ( $($inner:tt)* ) $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
};
($finish:ident ($($found:ident)*) # [ $($inner:tt)* ] $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
};
($finish:ident ($($found:ident)*) # { $($inner:tt)* } $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
};
($finish:ident ($($found:ident)*) # $first:ident $($rest:tt)*) => {
pounded_var_names!($finish ($($found)* $first) $($rest)*)
};
($finish:ident ($($found:ident)*) ( $($inner:tt)* ) $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
};
($finish:ident ($($found:ident)*) [ $($inner:tt)* ] $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
};
($finish:ident ($($found:ident)*) { $($inner:tt)* } $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($inner)* $($rest)*)
};
($finish:ident ($($found:ident)*) $ignore:tt $($rest:tt)*) => {
pounded_var_names!($finish ($($found)*) $($rest)*)
};
($finish:ident ($($found:ident)*)) => {
$finish!(() $($found)*)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! nested_tuples_pat {
(()) => {
&()
};
(() $first:ident $($rest:ident)*) => {
nested_tuples_pat!(($first) $($rest)*)
};
(($pat:pat) $first:ident $($rest:ident)*) => {
nested_tuples_pat!((($pat, $first)) $($rest)*)
};
(($done:pat)) => {
$done
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! multi_zip_expr {
(()) => {
&[]
};
(() $single:ident) => {
$single
};
(() $first:ident $($rest:ident)*) => {
multi_zip_expr!(($first.into_iter()) $($rest)*)
};
(($zips:expr) $first:ident $($rest:ident)*) => {
multi_zip_expr!(($zips.zip($first)) $($rest)*)
};
(($done:expr)) => {
$done
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! quote_each_token {
($tokens:ident) => {};
($tokens:ident # ! $($rest:tt)*) => {
quote_each_token!($tokens #);
quote_each_token!($tokens !);
quote_each_token!($tokens $($rest)*);
};
($tokens:ident # ( $($inner:tt)* ) * $($rest:tt)*) => {
for pounded_var_names!(nested_tuples_pat () $($inner)*)
in pounded_var_names!(multi_zip_expr () $($inner)*) {
quote_each_token!($tokens $($inner)*);
}
quote_each_token!($tokens $($rest)*);
};
($tokens:ident # ( $($inner:tt)* ) $sep:tt * $($rest:tt)*) => {
for (_i, pounded_var_names!(nested_tuples_pat () $($inner)*))
in pounded_var_names!(multi_zip_expr () $($inner)*).into_iter().enumerate() {
if _i > 0 {
quote_each_token!($tokens $sep);
}
quote_each_token!($tokens $($inner)*);
}
quote_each_token!($tokens $($rest)*);
};
($tokens:ident # [ $($inner:tt)* ] $($rest:tt)*) => {
quote_each_token!($tokens #);
$crate::__rt::append_kind(&mut $tokens,
$crate::__rt::TokenNode::Group(
$crate::__rt::Delimiter::Bracket,
quote! { $($inner)* }.into()
));
quote_each_token!($tokens $($rest)*);
};
($tokens:ident # $first:ident $($rest:tt)*) => {
$crate::ToTokens::to_tokens(&$first, &mut $tokens);
quote_each_token!($tokens $($rest)*);
};
($tokens:ident ( $($first:tt)* ) $($rest:tt)*) => {
$crate::__rt::append_kind(&mut $tokens,
$crate::__rt::TokenNode::Group(
$crate::__rt::Delimiter::Parenthesis,
quote! { $($first)* }.into()
));
quote_each_token!($tokens $($rest)*);
};
($tokens:ident [ $($first:tt)* ] $($rest:tt)*) => {
$crate::__rt::append_kind(&mut $tokens,
$crate::__rt::TokenNode::Group(
$crate::__rt::Delimiter::Bracket,
quote! { $($first)* }.into()
));
quote_each_token!($tokens $($rest)*);
};
($tokens:ident { $($first:tt)* } $($rest:tt)*) => {
$crate::__rt::append_kind(&mut $tokens,
$crate::__rt::TokenNode::Group(
$crate::__rt::Delimiter::Brace,
quote! { $($first)* }.into()
));
quote_each_token!($tokens $($rest)*);
};
($tokens:ident $first:tt $($rest:tt)*) => {
$crate::__rt::parse(&mut $tokens, stringify!($first));
quote_each_token!($tokens $($rest)*);
};
}