diff --git a/src/parse.rs b/src/parse.rs index b1bce2381a4d9c4c3b0979b402df8d1d204c759d..deac90026991af253df8eec921cb8daf11535f03 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -2,13 +2,11 @@ use std::collections::{HashMap, HashSet}; use std::iter::Peekable; use std::slice::Iter; -use syn::{self, DelimToken, Ident, IntTy, Lit, Path, Token, BinOpToken, - TokenTree, Ty}; +use syn::{self, DelimToken, Ident, IntTy, Lit, Path, Token, BinOpToken, TokenTree, Ty}; use error::*; -use {Cro, Ips, Ops, App, Idle, Init, Resources, Static, Statics, Task, Tasks, - Expr}; +use {Cro, Ips, Ops, App, Idle, Init, Resources, Static, Statics, Task, Tasks, Expr}; /// Parses the contents of `app! { $App }` pub fn app(input: &str) -> Result<App> { @@ -25,8 +23,7 @@ pub fn app(input: &str) -> Result<App> { "device" => { ensure!(device.is_none(), "duplicated `device` field"); - device = - Some(::parse::path(tts).chain_err(|| "parsing `device`")?); + device = Some(::parse::path(tts).chain_err(|| "parsing `device`")?); } "idle" => { ensure!(idle.is_none(), "duplicated `idle` field"); @@ -41,15 +38,12 @@ pub fn app(input: &str) -> Result<App> { "resources" => { ensure!(resources.is_none(), "duplicated `resources` field"); - resources = Some(::parse::statics(tts).chain_err( - || "parsing `resources`", - )?); + resources = Some(::parse::statics(tts).chain_err(|| "parsing `resources`")?); } "tasks" => { ensure!(tasks.is_none(), "duplicated `tasks` field"); - tasks = - Some(::parse::tasks(tts).chain_err(|| "parsing `tasks`")?); + tasks = Some(::parse::tasks(tts).chain_err(|| "parsing `tasks`")?); } _ => bail!("unknown field: `{}`", key), } @@ -77,11 +71,7 @@ fn bool(tt: Option<&TokenTree>) -> Result<bool> { } /// Parses a delimited token tree -fn delimited<R, F>( - tts: &mut Peekable<Iter<TokenTree>>, - delimiter: DelimToken, - f: F, -) -> Result<R> +fn delimited<R, F>(tts: &mut Peekable<Iter<TokenTree>>, delimiter: DelimToken, f: F) -> Result<R> where F: FnOnce(&[TokenTree]) -> Result<R>, { @@ -147,14 +137,9 @@ fn idle(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Idle> { path = Some(::parse::path(tts)?); } "resources" => { - ensure!( - resources.is_none(), - "duplicated `resources` field" - ); + ensure!(resources.is_none(), "duplicated `resources` field"); - resources = Some(::parse::resources(tts).chain_err( - || "parsing `resources`", - )?); + resources = Some(::parse::resources(tts).chain_err(|| "parsing `resources`")?); } _ => bail!("unknown field: `{}`", key), } @@ -203,10 +188,7 @@ fn resources(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Resources> { let mut tts = tts.iter().peekable(); while let Some(tt) = tts.next() { if let &TokenTree::Token(Token::Ident(ref ident)) = tt { - ensure!( - !idents.contains(ident), - "ident {} listed more than once" - ); + ensure!(!idents.contains(ident), "ident {} listed more than once"); idents.insert(ident.clone()); @@ -280,20 +262,18 @@ fn statics(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Statics> { let mut tts = tts.iter(); while let Some(tt) = tts.next() { match tt { - &TokenTree::Token(Token::Ident(ref id)) - if id.as_ref() == "static" => {} + &TokenTree::Token(Token::Ident(ref id)) if id.as_ref() == "static" => {} _ => { bail!("expected keyword `static`, found {:?}", tt); } } let tt = tts.next(); - let ident = - if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { - id - } else { - bail!("expected Ident, found {:?}", tt); - }; + let ident = if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { + id + } else { + bail!("expected Ident, found {:?}", tt); + }; ensure!( !statics.contains_key(ident), @@ -354,33 +334,22 @@ fn task(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Task> { "enabled" => { ensure!(enabled.is_none(), "duplicated `enabled` field"); - enabled = Some(::parse::bool(tts.next()).chain_err( - || "parsing `enabled`", - )?); + enabled = Some(::parse::bool(tts.next()).chain_err(|| "parsing `enabled`")?); } "path" => { ensure!(path.is_none(), "duplicated `path` field"); - path = Some( - ::parse::path(tts).chain_err(|| "parsing `path`")?, - ); + path = Some(::parse::path(tts).chain_err(|| "parsing `path`")?); } "priority" => { ensure!(priority.is_none(), "duplicated `priority` field"); - priority = Some(::parse::u8(tts.next()).chain_err( - || "parsing `priority`", - )?); + priority = Some(::parse::u8(tts.next()).chain_err(|| "parsing `priority`")?); } "resources" => { - ensure!( - resources.is_none(), - "duplicated `resources` field" - ); + ensure!(resources.is_none(), "duplicated `resources` field"); - resources = Some(::parse::resources(tts).chain_err( - || "parsing `resources`", - )?); + resources = Some(::parse::resources(tts).chain_err(|| "parsing `resources`")?); } _ => bail!("unknown field: `{}`", key), } @@ -521,48 +490,98 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> { ident ); - let tt = tts.next(); if let Some(&TokenTree::Token(Token::Colon)) = tt { } else { bail!("expected Colon, found {:?}", tt); } - let tt = tts.next(); - let meth = - if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { - id - } else { - bail!("expected Ident, found {:?}", tt); - }; - - //let ty_param: Result<Ty> = - let ty_param = - ::parse::delimited(&mut tts, DelimToken::Paren, |tts| { - Ok(syn::parse_type(&format!("{}", quote!(#(#tts)*)))?) - })?; - + let mut ty_arg = syn::parse_type(&"()")?; + let mut ty_ret = syn::parse_type(&"()")?; + let _ = ::parse::delimited(&mut tts, DelimToken::Brace, |tts| { + fields(&tts, |key, mut tts| { + match key.as_ref() { + "sig" => { + let tt = tts.next(); + if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { + ensure!(id.as_ref() == "fn", "expected `fn` Ident, found {:?}", tt); + } else { + bail!("expected `fn` Ident, found {:?}", tt); + } + ty_arg = ::parse::delimited(&mut tts, DelimToken::Paren, |tts| { + Ok(syn::parse_type(&format!("{}", quote!(#(#tts)*)))?) + })?; + + let tt = tts.peek().cloned(); + let ty_ret: Result<Ty> = match tt { + Some(&TokenTree::Token(Token::Comma)) => Ok( + syn::parse_type(&"()")?, + ), + Some(&TokenTree::Token(Token::RArrow)) => { + ::parse::ty(&TokenTree::Token(Token::Comma), &mut tts) + } + _ => bail!("expected `-> Type,' or `,` found {:?}", tt), + }; + + } + "sync" => (), + "async" => (), + _ => bail!("unknown field: `{}`", key), + }; + Ok(()) + }) + })?; let tt = tts.next(); - // let ty_return: Result<Ty> = Ok(syn::parse_type(&"()")?); - let ty_return: Result<Ty> = match tt { - Some(&TokenTree::Token(Token::Comma)) => { - tts.next(); - Ok(syn::parse_type(&"()")?) - } - Some(&TokenTree::Token(Token::RArrow)) => { - ::parse::ty(&TokenTree::Token(Token::Comma), &mut tts) - } - _ => bail!("expected `-> Type,' or `,` found {:?}", tt), - }; - - //let tt = tts.next(); - // if let Some(&TokenTree::Token(Token::Comma)) = tt { + match tt { + None | + Some(&TokenTree::Token(Token::Comma)) => {} + _ => bail!("expected Comma, found {:?}", tt), + } + // Ok(()))?; + // + // + // let tt = tts.next(); + // if let Some(&TokenTree::Token(Token::Colon)) = tt { // } else { - // bail!("expected Comma, found {:?}", tt); + // bail!("expected Colon, found {:?}", tt); + // } + // + // let tt = tts.next(); + // let meth = + // if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { + // id + // } else { + // bail!("expected Ident, found {:?}", tt); + // }; + // + // //let ty_param: Result<Ty> = + // let ty_param = + // ::parse::delimited(&mut tts, DelimToken::Paren, |tts| { + // Ok(syn::parse_type(&format!("{}", quote!(#(#tts)*)))?) + // })?; + // + // + // let tt = tts.next(); + // // let ty_return: Result<Ty> = Ok(syn::parse_type(&"()")?); + // let ty_return: Result<Ty> = match tt { + // Some(&TokenTree::Token(Token::Comma)) => { + // tts.next(); + // Ok(syn::parse_type(&"()")?) + // } + // Some(&TokenTree::Token(Token::RArrow)) => { + // ::parse::ty(&TokenTree::Token(Token::Comma), &mut tts) + // } + // _ => bail!("expected `-> Type,' or `,` found {:?}", tt), // }; - - ips.insert(ident.clone(), (meth.clone(), ty_param, ty_return?)); + // + // //let tt = tts.next(); + // // if let Some(&TokenTree::Token(Token::Comma)) = tt { + // // } else { + // // bail!("expected Comma, found {:?}", tt); + // // }; + // + // ips.insert(ident.clone(), (meth.clone(), ty_param, ty_return?)); } Ok(ips) @@ -593,14 +612,12 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> { bail!("expected Colon, found {:?}", tt); } - let ty = - ::parse::ty(&TokenTree::Token(Token::Eq), &mut tts) - .chain_err(|| format!("parsing `type` for {:?}", ident))?; + let ty = ::parse::ty(&TokenTree::Token(Token::Eq), &mut tts) + .chain_err(|| format!("parsing `type` for {:?}", ident))?; - let expr = - ::parse::expr(&TokenTree::Token(Token::Lt), &mut tts) - .chain_err(|| format!("parsing `type` for {:?}", ident))?; + let expr = ::parse::expr(&TokenTree::Token(Token::Lt), &mut tts) + .chain_err(|| format!("parsing `type` for {:?}", ident))?; @@ -619,11 +636,12 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> { fn ty(token: &TokenTree, tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ty> { let mut fragments = vec![]; loop { - if let Some(tt) = tts.next() { + if let Some(tt) = tts.peek().cloned() { if tt == token { break; } else { fragments.push(tt); + tts.next(); } } else { bail!("expected `{:?}`, found end of macro", token); @@ -635,10 +653,7 @@ fn ty(token: &TokenTree, tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ty> { } /// Parses `$Expr ` -fn expr( - token: &TokenTree, - tts: &mut Peekable<Iter<TokenTree>>, -) -> Result<::Expr> { +fn expr(token: &TokenTree, tts: &mut Peekable<Iter<TokenTree>>) -> Result<::Expr> { let mut fragments = vec![]; loop { if let Some(tt) = tts.next() {