From a3783a6d3d90ab549766b13651ec8ff8013762c5 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 28 Oct 2019 21:11:13 -0500 Subject: WIP generators tasks --- macros/src/codegen/post_init.rs | 62 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) (limited to 'macros/src/codegen/post_init.rs') 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, Vec) { +) -> ( + // const_app + Vec, + // root + Vec, + // stmts + Vec, +) { 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; + + // #[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) } -- cgit v1.2.3