From 9b867ab96df1b0d5404971f34c4937d946e96e1d Mon Sep 17 00:00:00 2001 From: Per <Per Lindgren> Date: Wed, 12 Feb 2020 18:25:00 +0100 Subject: [PATCH] POC for cortex-m-rt like code gen --- .gitignore | 2 ++ .vscode/tasks.json | 9 ++++-- examples/trust.rs | 24 ++++++++++----- expanded.rs | 68 +++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 75 ++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 159 insertions(+), 19 deletions(-) create mode 100644 .gitignore create mode 100644 expanded.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53eaa21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b4a2198..3413720 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,13 +4,16 @@ "version": "2.0.0", "tasks": [ { - "label": "cargo run --example main", + "label": "cargo expand --example trust > expanded.rs", "type": "shell", - "command": "cargo run --example main", + "command": "cargo expand --example trust > expanded.rs", "group": { "kind": "build", "isDefault": true - } + }, + "problemMatcher": [ + "$rustc" + ] }, { "label": "cargo run --example trust", diff --git a/examples/trust.rs b/examples/trust.rs index 245595a..048c4f3 100644 --- a/examples/trust.rs +++ b/examples/trust.rs @@ -3,22 +3,32 @@ use proc_collect::*; #[trust] mod kalleanka { fn hello() { + println!("in trust hello"); ext_hello(); } #[entry] - fn entry() {} + #[inline(always)] + fn entry() { + hello(); + } #[interrupt] - fn interrupt() {} + fn i1() { + println!("i1"); + } + + #[interrupt] + fn i2() { + println!("i2"); + } #[exception] - fn exception() {} + fn exception() { + println!("exc"); + } } fn ext_hello() { - println!("hello"); -} -fn main() { - hello(); + println!("ext_hello"); } diff --git a/expanded.rs b/expanded.rs new file mode 100644 index 0000000..8d0bdb6 --- /dev/null +++ b/expanded.rs @@ -0,0 +1,68 @@ +#![feature(prelude_import)] +#[prelude_import] +use std::prelude::v1::*; +#[macro_use] +extern crate std; +use proc_collect::*; + +fn hello() { + { + ::std::io::_print(::core::fmt::Arguments::new_v1( + &["in trust hello\n"], + &match () { + () => [], + }, + )); + }; + ext_hello(); +} +#[inline(always)] +fn entry() { + hello(); +} +fn i1() { + { + ::std::io::_print(::core::fmt::Arguments::new_v1( + &["i1\n"], + &match () { + () => [], + }, + )); + }; +} +fn i2() { + { + ::std::io::_print(::core::fmt::Arguments::new_v1( + &["i2\n"], + &match () { + () => [], + }, + )); + }; +} +fn exception() { + { + ::std::io::_print(::core::fmt::Arguments::new_v1( + &["exc\n"], + &match () { + () => [], + }, + )); + }; +} +fn main() { + let _ = entry(); + let _ = i1(); + let _ = i2(); + let _ = exception(); +} +fn ext_hello() { + { + ::std::io::_print(::core::fmt::Arguments::new_v1( + &["ext_hello\n"], + &match () { + () => [], + }, + )); + }; +} diff --git a/src/lib.rs b/src/lib.rs index d5a74e8..e3c3c4f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,36 +6,75 @@ use std::fs::{File, OpenOptions}; use std::io::prelude::*; use std::iter::FromIterator; use syn::parse::{Parse, ParseStream}; -use syn::{parse_macro_input, Attribute, Ident, Item, ItemMod, Result, Token}; +use syn::{parse_macro_input, Attribute, Ident, Item, ItemFn, ItemMod, Result, Token}; // use syn::{parse_macro_input, Attribute, Ident, ItemMod, Result, Token}; - #[proc_macro_attribute] pub fn entry(_args: TokenStream, input: TokenStream) -> TokenStream { - let items = parse_macro_input!(input as FnItem).items; - (quote! { #(#items)* }).into() + let fn_item = parse_macro_input!(input as ItemFn); + (quote! { #fn_item }).into() } #[proc_macro_attribute] pub fn interrupt(_args: TokenStream, input: TokenStream) -> TokenStream { - input + let fn_item = parse_macro_input!(input as ItemFn); + (quote! { #fn_item }).into() } #[proc_macro_attribute] pub fn exception(_args: TokenStream, input: TokenStream) -> TokenStream { - input + let fn_item = parse_macro_input!(input as ItemFn); + (quote! { #fn_item }).into() } #[derive(Debug)] struct TrustMod { items: Vec<Item>, + entries: Vec<Entry>, +} + +#[derive(Debug)] +enum Entry { + Entry(Ident), + Interrupt(Ident), + Exception(Ident), } impl Parse for TrustMod { fn parse(input: ParseStream) -> Result<Self> { let module: ItemMod = input.parse()?; + match module.content { - Some((_, items)) => Ok(TrustMod { items }), + Some((_, items)) => { + let mut v = vec![]; + let mut e = vec![]; + for i in items { + match i { + Item::Fn(ref item_fn) => { + for a in &item_fn.attrs { + for s in &a.path.segments { + match s.ident.to_string().as_str() { + "entry" => e.push(Entry::Entry(item_fn.sig.ident.clone())), + "interrupt" => { + e.push(Entry::Interrupt(item_fn.sig.ident.clone())) + } + "exception" => { + e.push(Entry::Exception(item_fn.sig.ident.clone())) + } + _ => (), + } + } + } + } + _ => (), + } + v.push(i); + } + Ok(TrustMod { + items: v, + entries: e, + }) + } _ => panic!("illegal trust module"), } } @@ -43,6 +82,24 @@ impl Parse for TrustMod { #[proc_macro_attribute] pub fn trust(_args: TokenStream, input: TokenStream) -> TokenStream { - let items = parse_macro_input!(input as TrustMod).items; - (quote! { #(#items)* }).into() + let trust_mod = parse_macro_input!(input as TrustMod); + let items = trust_mod.items; + + let mut calls = vec![]; + for e in trust_mod.entries { + let id = match e { + Entry::Entry(id) => id, + Entry::Interrupt(id) => id, + Entry::Exception(id) => id, + }; + calls.push(quote! { let _ = #id(); }); + } + + (quote! { + #(#items)* + fn main() { + #(#calls)* + } + }) + .into() } -- GitLab