dyn_stack_macros/
lib.rs

1use proc_macro::*;
2
3#[proc_macro]
4pub fn alloc_impl_proc(item: TokenStream) -> TokenStream {
5	let mut item = item.into_iter();
6	let Some(TokenTree::Group(krate)) = item.next() else { panic!() };
7	let krate = krate.stream();
8	let stack = match item.next() {
9		Some(TokenTree::Group(stack)) => {
10			let mut stack = stack.stream().into_iter();
11			_ = stack.next();
12			let Some(TokenTree::Ident(stack)) = stack.next() else { panic!() };
13			stack
14		},
15		Some(_) => {
16			let Some(TokenTree::Ident(stack)) = item.next() else { panic!() };
17			stack
18		},
19
20		_ => panic!(),
21	};
22	let Some(TokenTree::Group(block)) = item.next() else { panic!() };
23
24	let mut tokens = Vec::new();
25
26	tokens.extend([
27		TokenTree::Ident(Ident::new("let", Span::call_site())),
28		TokenTree::Ident(stack.clone()),
29		TokenTree::Punct(Punct::new('=', Spacing::Alone)),
30		TokenTree::Punct(Punct::new('&', Spacing::Alone)),
31		TokenTree::Ident(Ident::new("mut", Span::call_site())),
32		TokenTree::Punct(Punct::new('*', Spacing::Alone)),
33		TokenTree::Ident(stack.clone()),
34		TokenTree::Punct(Punct::new(';', Spacing::Alone)),
35	]);
36
37	let mut cur_stmt = vec![TokenTree::Ident(stack.clone())];
38	for token in block.stream().into_iter() {
39		match token {
40			TokenTree::Punct(p) if p.as_char() == ';' => {
41				tokens.extend(krate.clone().into_iter().chain([
42					TokenTree::Punct(Punct::new(':', Spacing::Joint)),
43					TokenTree::Punct(Punct::new(':', Spacing::Alone)),
44					TokenTree::Ident(Ident::new("alloc_impl_rules", Span::call_site())),
45					TokenTree::Punct(Punct::new('!', Spacing::Alone)),
46					TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::from_iter(cur_stmt))),
47					TokenTree::Punct(Punct::new(';', Spacing::Alone)),
48				]));
49
50				cur_stmt = vec![TokenTree::Ident(stack.clone())];
51			},
52			token => cur_stmt.push(token),
53		}
54	}
55
56	tokens.extend([
57		TokenTree::Ident(Ident::new("let", Span::call_site())),
58		TokenTree::Ident(Ident::new("_", Span::call_site())),
59		TokenTree::Punct(Punct::new('=', Spacing::Alone)),
60		TokenTree::Ident(stack.clone()),
61		TokenTree::Punct(Punct::new(';', Spacing::Alone)),
62	]);
63
64	TokenStream::from_iter(tokens)
65}