aboutsummaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/syntax/mod.rs1
-rw-r--r--macros/src/syntax/parse.rs66
-rw-r--r--macros/src/trans.rs32
3 files changed, 56 insertions, 43 deletions
diff --git a/macros/src/syntax/mod.rs b/macros/src/syntax/mod.rs
index c856617e..53c17a82 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<Ident>,
}
#[derive(Debug)]
diff --git a/macros/src/syntax/parse.rs b/macros/src/syntax/parse.rs
index e6d3f461..9cfbd78b 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<TokenTree>,
- allows_locals: bool,
-) -> (Option<Resources>, Tokens, HashSet<Ident>) {
+pub fn idle(tts: Vec<TokenTree>) -> 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<TokenTree>) -> 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<TokenTree>) -> Init {
- let (_, path, resources) = idle_init(tts, false);
+ let mut tts = tts.into_iter();
+
+ 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, resources }
+ Init { path: path.expect("path field is missing") }
}
fn idents(tts: Vec<TokenTree>) -> HashSet<Ident> {
diff --git a/macros/src/trans.rs b/macros/src/trans.rs
index 6cf3a517..14d24fd8 100644
--- a/macros/src/trans.rs
+++ b/macros/src/trans.rs
@@ -33,32 +33,24 @@ fn init(app: &App, main: &mut Vec<Tokens>, root: &mut Vec<Tokens>) {
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;
-
- fields.push(quote! {
- pub #name: &'a mut #ty,
- });
+ let ty = &resource.ty;
- exprs.push(quote! {
- #name: &mut *super::#name.get(),
- });
- } else {
- fields.push(quote! {
- pub #name: &'a mut ::#device::#name,
- });
+ fields.push(quote! {
+ pub #name: &'a mut #ty,
+ });
- 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<Tokens>, root: &mut Vec<Tokens>) {
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)*