aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen-verbose.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen-verbose.rs')
-rw-r--r--macros/src/codegen-verbose.rs226
1 files changed, 226 insertions, 0 deletions
diff --git a/macros/src/codegen-verbose.rs b/macros/src/codegen-verbose.rs
new file mode 100644
index 00000000..2b71cf5c
--- /dev/null
+++ b/macros/src/codegen-verbose.rs
@@ -0,0 +1,226 @@
+use proc_macro2::TokenStream as TokenStream2;
+use quote::quote;
+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;
+mod schedule;
+mod schedule_body;
+mod software_tasks;
+mod spawn;
+mod spawn_body;
+mod timer_queue;
+mod util;
+
+// TODO document the syntax here or in `rtic-syntax`
+pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 {
+ let mut const_app = vec![];
+ let mut mains = vec![];
+ let mut root = vec![];
+ let mut user = vec![];
+ let mut imports = vec![];
+
+ // generate a `main` function for each core
+ for core in 0..app.args.cores {
+ let assertion_stmts = assertions::codegen(core, analysis, extra);
+
+ let (const_app_pre_init, pre_init_stmts) = pre_init::codegen(core, &app, analysis, extra);
+
+ let (const_app_init, _root_init, user_init, user_init_imports, call_init) =
+ init::codegen(core, app, analysis, extra);
+
+ let (const_app_post_init, post_init_stmts) =
+ post_init::codegen(core, &app, analysis, extra);
+
+ let (const_app_idle, _root_idle, user_idle, user_idle_imports, call_idle) =
+ idle::codegen(core, app, analysis, extra);
+
+ user.push(quote!(
+ /// USER INIT
+ #user_init
+
+ /// USER IDLE
+ #user_idle
+ ));
+
+ // Stow away the imports generated for each core
+ imports.push(quote!(
+ /// USER IMPORTS
+ #(#user_init_imports)*
+
+ /// USER IDLE
+ #(#user_idle_imports)*
+ ));
+
+ root.push(quote!(
+ #(#_root_init)*
+
+ #(#_root_idle)*
+ ));
+
+ const_app.push(quote!(
+ #(#const_app_pre_init)*
+
+ #const_app_init
+
+ #(#const_app_post_init)*
+
+ #const_app_idle
+ ));
+
+ let cfg_core = util::cfg_core(core, app.args.cores);
+ let main = util::suffixed("main", core);
+ let section = util::link_section("text", core);
+ mains.push(quote!(
+ #[no_mangle]
+ #section
+ #cfg_core
+ unsafe extern "C" fn #main() -> ! {
+ #(#assertion_stmts)*
+
+ #(#pre_init_stmts)*
+
+ #call_init
+
+ #(#post_init_stmts)*
+
+ #call_idle
+ }
+ ));
+ }
+
+ let (const_app_resources, mod_resources, mod_resources_imports) =
+ resources::codegen(app, analysis, extra);
+
+ let (
+ const_app_hardware_tasks,
+ root_hardware_tasks,
+ user_hardware_tasks,
+ user_hardware_tasks_imports,
+ ) = hardware_tasks::codegen(app, analysis, extra);
+
+ let (
+ const_app_software_tasks,
+ root_software_tasks,
+ user_software_tasks,
+ user_software_tasks_imports,
+ ) = software_tasks::codegen(app, analysis, extra);
+
+ let const_app_dispatchers = dispatchers::codegen(app, analysis, extra);
+
+ let const_app_spawn = spawn::codegen(app, analysis, extra);
+
+ let const_app_timer_queue = timer_queue::codegen(app, analysis, extra);
+
+ let const_app_schedule = schedule::codegen(app, extra);
+
+ let cores = app.args.cores.to_string();
+ let cfg_core = quote!(#[cfg(core = #cores)]);
+ let msg = format!(
+ "specified {} core{} but tried to compile for more than {0} core{1}",
+ app.args.cores,
+ if app.args.cores > 1 { "s" } else { "" }
+ );
+ let check_excess_cores = quote!(
+ #cfg_core
+ compile_error!(#msg);
+ );
+
+ /*
+ for s in root.clone() {
+ println!("{}", s.to_string());
+ }
+ */
+
+ let user_imports = app.user_imports.clone();
+ let user_code = app.user_code.clone();
+ let name = &app.name;
+ let device = extra.device;
+ let endresult = quote!(
+ /// USER
+ #(#user)*
+
+ /// USER_HW_TASKS
+ #(#user_hardware_tasks)*
+
+ /// USER_SW_TASKS
+ #(#user_software_tasks)*
+
+ /// ROOT
+ //#(#root)*
+
+ /// MOD_RESOURCES
+ #mod_resources
+
+ /// root_hardware_tasks
+ #(#root_hardware_tasks)*
+
+ /// root_software_tasks
+ #(#root_software_tasks)*
+
+ /// Implementation details
+ mod #name {
+ /// Always include the device crate which contains the vector table
+ use #device as _;
+ #(#imports)*
+ /// User imports
+ #(#user_imports)*
+
+ /// User code from within the module
+ #(#user_code)*
+
+ /// User hardware tasks import
+ #(#user_hardware_tasks_imports)*
+
+ /// User software_tasks
+ #(#user_software_tasks_imports)*
+
+ /// Mod resources imports
+ #(#mod_resources_imports)*
+
+ #check_excess_cores
+
+ /// Const app
+ #(#const_app)*
+
+ /// Const app resources
+ #(#const_app_resources)*
+
+ /// Const app hw tasks
+ #(#const_app_hardware_tasks)*
+
+ /// Const app sw tasks
+ #(#const_app_software_tasks)*
+
+ /// Const app dispatchers
+ #(#const_app_dispatchers)*
+
+ /// Const app spawn
+ #(#const_app_spawn)*
+ /// Const app spawn end
+
+ #(#const_app_timer_queue)*
+
+ #(#const_app_schedule)*
+
+ /// Mains
+ #(#mains)*
+ }
+ );
+ for s in endresult.clone() {
+ eprintln!("{}", s.to_string());
+ }
+
+ endresult
+}