1mod utils;
3
4use proc_macro::TokenStream;
5use proc_macro2::{Ident, Span};
6use quote::quote;
7use utils::{
8 ArrayAssign, StructAssign, TreeLevel, parse_arr_assign, parse_struct_assign,
9};
10
11#[proc_macro]
19pub fn generate_locations(input: TokenStream) -> TokenStream {
20 let ArrayAssign {
21 var_name,
22 var_val,
23 num_locations,
24 } = parse_arr_assign(input);
25
26 let var_iter = std::iter::repeat_n(&var_name, num_locations);
27
28 quote! {
29 let mut #var_name = #var_val;
30 #( #var_iter = #var_val; )*
31 }
32 .into()
33}
34
35#[proc_macro]
49pub fn generate_unique_lifetimes(input: TokenStream) -> TokenStream {
50 let ArrayAssign {
51 var_name,
52 var_val,
53 num_locations,
54 } = parse_arr_assign(input);
55
56 let idents = (1 ..= num_locations)
57 .map(|num| Ident::new(format!("borrow_{num}").as_str(), Span::call_site()));
58
59 quote! {
60 let #var_name = #var_val;
61 #( let #idents = &#var_name; )*
62 }
63 .into()
64}
65
66#[proc_macro]
84pub fn generate_flow(input: TokenStream) -> TokenStream {
85 let ArrayAssign {
86 var_name,
87 var_val,
88 num_locations,
89 } = parse_arr_assign(input);
90
91 let idents = (1 ..= num_locations)
92 .map(|num| Ident::new(format!("temp_{num}").as_str(), Span::call_site()));
93
94 quote! {
95 let mut #var_name = #var_val;
96
97 #(
98 let #idents = #var_name;
99 #var_name = #idents;
100 )*
101 }
102 .into()
103}
104
105#[proc_macro]
114pub fn generate_places(input: TokenStream) -> TokenStream {
115 let StructAssign {
116 var_name,
117 struct_name,
118 field_val,
119 field_ty,
120 num_fields,
121 } = parse_struct_assign(input);
122
123 let fields = (1 ..= num_fields)
124 .map(|num| Ident::new(format!("field_{num}").as_str(), Span::call_site()))
125 .collect::<Vec<_>>();
126
127 quote! {
128 struct #struct_name {
129 #(#fields: #field_ty,)*
130 }
131
132 let #var_name = #struct_name {
133 #(#fields: #field_val,)*
134 };
135 }
136 .into()
137}
138
139#[proc_macro]
148pub fn generate_same_lifetime(input: TokenStream) -> TokenStream {
149 let lt_ident = syn::Lifetime::new("'a", Span::call_site());
150
151 let StructAssign {
152 var_name,
153 struct_name,
154 field_val,
155 field_ty,
156 num_fields,
157 } = parse_struct_assign(input);
158
159 let fields = (1 ..= num_fields)
160 .map(|num| Ident::new(format!("field_{num}").as_str(), Span::call_site()))
161 .collect::<Vec<_>>();
162
163 quote! {
164 struct #struct_name<#lt_ident> {
165 #(#fields: &#lt_ident #field_ty,)*
166 }
167
168 let #var_name = #struct_name {
169 #(#fields: &#field_val,)*
170 };
171 }
172 .into()
173}
174
175#[proc_macro]
198pub fn generate_nested_struct(input: TokenStream) -> TokenStream {
199 let StructAssign {
200 field_val,
201 field_ty,
202 num_fields,
203 ..
204 } = parse_struct_assign(input);
205
206 let fields = (1 ..= num_fields)
207 .map(|num| Ident::new(format!("field_{num}").as_str(), Span::call_site()))
208 .collect::<Vec<_>>();
209
210 let mut levels = vec![];
212 for level_num in (0 ..= num_fields).rev() {
213 let level = TreeLevel::new(
214 level_num,
215 fields.clone(),
216 levels.last(),
217 &field_val,
218 &field_ty,
219 );
220 levels.push(level);
221 }
222
223 let defs = levels.iter().map(|level| level.def.clone());
224 let instants = levels.iter().map(|level| level.instantiation.clone());
225 quote! {
226 #(#defs)*
227
228 #(#instants)*
229 }
230 .into()
231}