aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/post_init.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/post_init.rs')
-rw-r--r--macros/src/codegen/post_init.rs62
1 files changed, 59 insertions, 3 deletions
diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs
index 19773e45..d4b13181 100644
--- a/macros/src/codegen/post_init.rs
+++ b/macros/src/codegen/post_init.rs
@@ -1,15 +1,29 @@
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
+use rtfm_syntax::{ast::App, Context};
-use crate::{analyze::Analysis, check::Extra, codegen::util};
+use crate::{
+ analyze::Analysis,
+ check::Extra,
+ codegen::{locals, util},
+};
/// Generates code that runs after `#[init]` returns
pub fn codegen(
core: u8,
+ app: &App,
analysis: &Analysis,
extra: &Extra,
-) -> (Vec<TokenStream2>, Vec<TokenStream2>) {
+) -> (
+ // const_app
+ Vec<TokenStream2>,
+ // root
+ Vec<TokenStream2>,
+ // stmts
+ Vec<TokenStream2>,
+) {
let mut const_app = vec![];
+ let mut root = vec![];
let mut stmts = vec![];
// initialize late resources
@@ -22,6 +36,48 @@ pub fn codegen(
}
}
+ // TODO WIP
+ for (name, task) in &app.hardware_tasks {
+ if task.is_generator {
+ let name_s = name.to_string();
+ let gen_i = util::generator_ident(&name_s);
+ let gen_t = util::generator_type(&name_s);
+ const_app.push(quote!(
+ static mut #gen_i: core::mem::MaybeUninit<#gen_t> =
+ core::mem::MaybeUninit::uninit();
+ ));
+
+ let (locals_pat, locals_new) = if task.locals.is_empty() {
+ (None, quote!())
+ } else {
+ let (struct_, pat) =
+ locals::codegen(Context::HardwareTask(name), &task.locals, core, app);
+
+ root.push(struct_);
+
+ (Some(pat), quote!(#name::Locals::new(),))
+ };
+
+ let context = &task.context;
+ let task_stmts = &task.stmts;
+ let locals_pat = locals_pat.iter();
+ root.push(quote!(
+ type #gen_t = impl core::ops::Generator<Yield = (), Return = !>;
+
+ // #[allow(non_snake_case)]
+ fn #name(#(#locals_pat,)* #context: #name::Context) -> #gen_t {
+ use rtfm::Mutex as _;
+
+ #(#task_stmts)*
+ }
+ ));
+
+ stmts.push(quote!(
+ #gen_i.as_mut_ptr().write(#name(#locals_new #name::Context::new()));
+ ));
+ }
+ }
+
if analysis.timer_queues.is_empty() {
// cross-initialization barriers -- notify *other* cores that their resources have been
// initialized
@@ -151,5 +207,5 @@ pub fn codegen(
// enable the interrupts -- this completes the `init`-ialization phase
stmts.push(quote!(rtfm::export::interrupt::enable();));
- (const_app, stmts)
+ (const_app, root, stmts)
}