cortex_m_rtic_macros/codegen/
init.rs
1use proc_macro2::TokenStream as TokenStream2;
2use quote::quote;
3use rtic_syntax::{ast::App, Context};
4
5use crate::{
6 analyze::Analysis,
7 check::Extra,
8 codegen::{local_resources_struct, module},
9};
10
11type CodegenResult = (
12 Option<TokenStream2>,
14 Vec<TokenStream2>,
20 TokenStream2,
22 TokenStream2,
24);
25
26pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> CodegenResult {
28 let init = &app.init;
29 let mut local_needs_lt = false;
30 let name = &init.name;
31
32 let mut root_init = vec![];
33
34 let context = &init.context;
35 let attrs = &init.attrs;
36 let stmts = &init.stmts;
37 let shared = &init.user_shared_struct;
38 let local = &init.user_local_struct;
39
40 let shared_resources: Vec<_> = app
41 .shared_resources
42 .iter()
43 .map(|(k, v)| {
44 let ty = &v.ty;
45 let cfgs = &v.cfgs;
46 let docs = &v.docs;
47 quote!(
48 #(#cfgs)*
49 #(#docs)*
50 #k: #ty,
51 )
52 })
53 .collect();
54 let local_resources: Vec<_> = app
55 .local_resources
56 .iter()
57 .map(|(k, v)| {
58 let ty = &v.ty;
59 let cfgs = &v.cfgs;
60 let docs = &v.docs;
61 quote!(
62 #(#cfgs)*
63 #(#docs)*
64 #k: #ty,
65 )
66 })
67 .collect();
68
69 let shared_resources_doc = " RTIC shared resource struct".to_string();
70 let local_resources_doc = " RTIC local resource struct".to_string();
71 root_init.push(quote! {
72 #[doc = #shared_resources_doc]
73 struct #shared {
74 #(#shared_resources)*
75 }
76
77 #[doc = #local_resources_doc]
78 struct #local {
79 #(#local_resources)*
80 }
81 });
82
83 let user_init_return = quote! {#shared, #local, #name::Monotonics};
84 let user_init_doc = " User provided init function".to_string();
85
86 let user_init = quote!(
87 #(#attrs)*
88 #[doc = #user_init_doc]
89 #[inline(always)]
90 #[allow(non_snake_case)]
91 fn #name(#context: #name::Context) -> (#user_init_return) {
92 #(#stmts)*
93 }
94 );
95
96 let mut mod_app = None;
97
98 if !init.args.local_resources.is_empty() {
100 let (item, constructor) =
101 local_resources_struct::codegen(Context::Init, &mut local_needs_lt, app);
102
103 root_init.push(item);
104
105 mod_app = Some(constructor);
106 }
107
108 let call_init = quote! {
109 let (shared_resources, local_resources, mut monotonics) = #name(#name::Context::new(core.into()));
110 };
111
112 root_init.push(module::codegen(
113 Context::Init,
114 false,
115 local_needs_lt,
116 app,
117 analysis,
118 extra,
119 ));
120
121 (mod_app, root_init, user_init, call_init)
122}