diff --git a/macros/src/syntax/mod.rs b/macros/src/syntax/mod.rs index c856617ea1..53c17a82d4 100644 --- a/macros/src/syntax/mod.rs +++ b/macros/src/syntax/mod.rs @@ -17,7 +17,6 @@ pub struct App { #[derive(Debug)] pub struct Init { pub path: Tokens, - pub resources: HashSet, } #[derive(Debug)] diff --git a/macros/src/syntax/parse.rs b/macros/src/syntax/parse.rs index e6d3f461cd..9cfbd78bdd 100644 --- a/macros/src/syntax/parse.rs +++ b/macros/src/syntax/parse.rs @@ -1,7 +1,6 @@ use std::collections::{HashMap, HashSet}; use syn::{self, DelimToken, Ident, IntTy, Lit, Token, TokenTree}; -use quote::Tokens; use syntax::{App, Idle, Init, Kind, Resource, Resources, Task, Tasks}; @@ -136,10 +135,7 @@ pub fn app(input: &str) -> App { } } -fn idle_init( - tts: Vec, - allows_locals: bool, -) -> (Option, Tokens, HashSet) { +pub fn idle(tts: Vec) -> Idle { let mut tts = tts.into_iter(); let mut local = None; @@ -161,7 +157,7 @@ fn idle_init( ); match id.as_ref() { - "local" if allows_locals => { + "local" => { assert!(local.is_none(), "duplicated local field"); let tt = tts.next(); @@ -183,7 +179,8 @@ fn idle_init( let mut pieces = vec![]; loop { - let tt = tts.next().expect("expected comma, found EOM"); + let tt = tts.next() + .expect("expected comma, found end of macro"); if tt == TokenTree::Token(Token::Comma) { path = Some(quote!(#(#pieces)*)); @@ -225,27 +222,52 @@ fn idle_init( ); } - ( - local, - path.expect("path field is missing"), - resources.unwrap_or(HashSet::new()), - ) -} - -pub fn idle(tts: Vec) -> Idle { - let (locals, path, resources) = idle_init(tts, true); - Idle { - local: locals.expect("local field is missing"), - path, - resources, + local: local.unwrap_or(HashMap::new()), + path: path.expect("path field is missing"), + resources: resources.unwrap_or(HashSet::new()), } } pub fn init(tts: Vec) -> Init { - let (_, path, resources) = idle_init(tts, false); + let mut tts = tts.into_iter(); - Init { path, resources } + let mut path = None; + while let Some(tt) = tts.next() { + let id = if let TokenTree::Token(Token::Ident(id)) = tt { + id + } else { + panic!("expected ident, found {:?}", tt); + }; + + let tt = tts.next(); + assert_eq!( + tt, + Some(TokenTree::Token(Token::Colon)), + "expected colon, found {:?}", + tt + ); + + match id.as_ref() { + "path" => { + let mut pieces = vec![]; + loop { + let tt = tts.next() + .expect("expected comma, found end of macro"); + + if tt == TokenTree::Token(Token::Comma) { + path = Some(quote!(#(#pieces)*)); + break; + } else { + pieces.push(tt); + } + } + } + id => panic!("unexpected field {}", id), + } + } + + Init { path: path.expect("path field is missing") } } fn idents(tts: Vec) -> HashSet { diff --git a/macros/src/trans.rs b/macros/src/trans.rs index 6cf3a51750..14d24fd81c 100644 --- a/macros/src/trans.rs +++ b/macros/src/trans.rs @@ -33,32 +33,24 @@ fn init(app: &App, main: &mut Vec, root: &mut Vec) { let mut fields = vec![]; let mut exprs = vec![]; let mut lifetime = None; - for name in &app.init.resources { + for (name, resource) in &app.resources { lifetime = Some(quote!('a)); - if let Some(resource) = app.resources.get(name) { - let ty = &resource.ty; + let ty = &resource.ty; - fields.push(quote! { - pub #name: &'a mut #ty, - }); + fields.push(quote! { + pub #name: &'a mut #ty, + }); - exprs.push(quote! { - #name: &mut *super::#name.get(), - }); - } else { - fields.push(quote! { - pub #name: &'a mut ::#device::#name, - }); - - exprs.push(quote! { - #name: &mut *::#device::#name.get(), - }); - } + exprs.push(quote! { + #name: &mut *super::#name.get(), + }); } root.push(quote! { mod init { + pub use ::#device::Peripherals; + #[allow(non_snake_case)] pub struct Resources<#lifetime> { #(#fields)* @@ -122,10 +114,10 @@ fn init(app: &App, main: &mut Vec, root: &mut Vec) { let init = &app.init.path; main.push(quote! { // type check - let init: fn(init::Resources) = #init; + let init: fn(init::Peripherals, init::Resources) = #init; #krate::atomic(|cs| unsafe { - init(init::Resources::new()); + init(init::Peripherals::all(), init::Resources::new()); #(#exceptions)* #(#interrupts)*