rtic/macros/src/codegen.rs

183 lines
3.9 KiB
Rust
Raw Normal View History

use proc_macro2::TokenStream as TokenStream2;
2018-11-03 17:02:41 +01:00
use quote::quote;
2020-06-11 19:18:29 +02:00
use rtic_syntax::ast::App;
use crate::{analyze::Analysis, check::Extra};
mod assertions;
mod dispatchers;
mod hardware_tasks;
mod idle;
mod init;
mod locals;
mod module;
mod post_init;
mod pre_init;
mod resources;
mod resources_struct;
2020-10-11 18:38:38 +02:00
// mod schedule;
// mod schedule_body;
mod software_tasks;
2020-10-11 18:38:38 +02:00
// mod spawn;
// mod spawn_body;
mod timer_queue;
mod util;
2020-06-11 19:18:29 +02:00
// TODO document the syntax here or in `rtic-syntax`
pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
2020-10-01 18:17:15 +02:00
let mut mod_app = vec![];
let mut mod_app_imports = vec![];
let mut mains = vec![];
let mut root = vec![];
let mut user = vec![];
let mut imports = vec![];
2018-11-03 17:02:41 +01:00
2020-09-01 19:04:55 +02:00
// Generate the `main` function
2020-08-27 13:21:56 +02:00
let assertion_stmts = assertions::codegen(analysis);
2018-11-03 17:02:41 +01:00
2020-08-27 13:21:56 +02:00
let pre_init_stmts = pre_init::codegen(&app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
let (mod_app_init, root_init, user_init, user_init_imports, call_init) =
2020-09-08 17:22:32 +02:00
init::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-09-01 19:04:55 +02:00
let post_init_stmts = post_init::codegen(&app, analysis);
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
let (mod_app_idle, root_idle, user_idle, user_idle_imports, call_idle) =
2020-09-08 17:22:32 +02:00
idle::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
if user_init.is_some() {
2020-10-01 18:17:15 +02:00
mod_app_imports.push(quote!(
use super::init;
))
}
if user_idle.is_some() {
2020-10-01 18:17:15 +02:00
mod_app_imports.push(quote!(
use super::idle;
))
}
2020-08-27 13:21:56 +02:00
user.push(quote!(
#user_init
2018-11-03 17:02:41 +01:00
2020-08-27 13:21:56 +02:00
#user_idle
));
2018-11-03 17:02:41 +01:00
imports.push(quote!(
#(#user_init_imports)*
#(#user_idle_imports)*
));
2020-08-27 13:21:56 +02:00
root.push(quote!(
#(#root_init)*
2018-11-03 17:02:41 +01:00
2020-08-27 13:21:56 +02:00
#(#root_idle)*
));
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
mod_app.push(quote!(
#mod_app_init
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
#mod_app_idle
2020-08-27 13:21:56 +02:00
));
2020-08-27 13:21:56 +02:00
let main = util::suffixed("main");
mains.push(quote!(
#[no_mangle]
unsafe extern "C" fn #main() -> ! {
let _TODO: () = ();
2020-08-27 13:21:56 +02:00
#(#assertion_stmts)*
2020-05-26 22:21:32 +02:00
2020-08-27 13:21:56 +02:00
#(#pre_init_stmts)*
2020-08-27 13:21:56 +02:00
#call_init
2020-08-27 13:21:56 +02:00
#(#post_init_stmts)*
2020-08-27 13:21:56 +02:00
#call_idle
}
));
2020-10-01 18:17:15 +02:00
let (mod_app_resources, mod_resources, mod_resources_imports) =
2020-09-08 17:22:32 +02:00
resources::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-09-08 17:22:32 +02:00
let (
2020-10-01 18:17:15 +02:00
mod_app_hardware_tasks,
2020-09-08 17:22:32 +02:00
root_hardware_tasks,
user_hardware_tasks,
user_hardware_tasks_imports,
) = hardware_tasks::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-09-08 17:22:32 +02:00
let (
2020-10-01 18:17:15 +02:00
mod_app_software_tasks,
2020-09-08 17:22:32 +02:00
root_software_tasks,
user_software_tasks,
user_software_tasks_imports,
) = software_tasks::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
let mod_app_dispatchers = dispatchers::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-10-11 18:38:38 +02:00
// let mod_app_spawn = spawn::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
let mod_app_timer_queue = timer_queue::codegen(app, analysis, extra);
2018-11-03 17:02:41 +01:00
2020-10-11 18:38:38 +02:00
// let mod_app_schedule = schedule::codegen(app, extra);
2018-11-03 17:02:41 +01:00
let user_imports = app.user_imports.clone();
let user_code = app.user_code.clone();
let name = &app.name;
let device = extra.device;
quote!(
#(#user)*
#(#user_hardware_tasks)*
2019-02-16 00:22:00 +01:00
#(#user_software_tasks)*
#(#root)*
2018-11-03 17:02:41 +01:00
2019-08-20 15:11:24 +02:00
#mod_resources
2018-11-03 17:02:41 +01:00
#(#root_hardware_tasks)*
2018-11-03 17:02:41 +01:00
#(#root_software_tasks)*
/// Implementation details
mod #name {
/// Always include the device crate which contains the vector table
use #device as _;
#(#imports)*
#(#user_imports)*
2019-02-15 19:52:25 +01:00
/// User code from within the module
#(#user_code)*
/// User code end
#(#user_hardware_tasks_imports)*
#(#user_software_tasks_imports)*
#(#mod_resources_imports)*
2020-10-01 18:17:15 +02:00
/// app module
#(#mod_app)*
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
#(#mod_app_resources)*
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
#(#mod_app_hardware_tasks)*
2020-10-01 18:17:15 +02:00
#(#mod_app_software_tasks)*
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
#(#mod_app_dispatchers)*
2018-11-03 17:02:41 +01:00
2020-10-11 18:38:38 +02:00
// #(#mod_app_spawn)*
2018-11-03 17:02:41 +01:00
2020-10-01 18:17:15 +02:00
#(#mod_app_timer_queue)*
2020-10-11 18:38:38 +02:00
// #(#mod_app_schedule)*
2018-11-03 17:02:41 +01:00
#(#mains)*
}
2018-11-03 17:02:41 +01:00
)
}