Skip to content
Snippets Groups Projects
Commit e2c3257f authored by pln's avatar pln
Browse files

cro only

parent 63695403
No related branches found
No related tags found
No related merge requests found
...@@ -114,8 +114,8 @@ pub enum IpTo { ...@@ -114,8 +114,8 @@ pub enum IpTo {
Method(Ident), Method(Ident),
} }
/// `$($Ident: $Ty > $Path,)*` /// `$($Ident: Ident ($Ty) -> $Ty )*`
pub type Ips = HashMap<Ident, (Ty, Path)>; pub type Ips = HashMap<Ident, (Ident, Ty, Ty)>;
/// `$($Ident: $Ty = $Expr < $Path,)*` /// `$($Ident: $Ty = $Expr < $Path,)*`
pub type Ops = HashMap<Ident, (Ty, Expr, Path)>; pub type Ops = HashMap<Ident, (Ty, Expr, Path)>;
......
...@@ -2,11 +2,13 @@ use std::collections::{HashMap, HashSet}; ...@@ -2,11 +2,13 @@ use std::collections::{HashMap, HashSet};
use std::iter::Peekable; use std::iter::Peekable;
use std::slice::Iter; 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 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 }` /// Parses the contents of `app! { $App }`
pub fn app(input: &str) -> Result<App> { pub fn app(input: &str) -> Result<App> {
...@@ -23,7 +25,8 @@ pub fn app(input: &str) -> Result<App> { ...@@ -23,7 +25,8 @@ pub fn app(input: &str) -> Result<App> {
"device" => { "device" => {
ensure!(device.is_none(), "duplicated `device` field"); 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" => { "idle" => {
ensure!(idle.is_none(), "duplicated `idle` field"); ensure!(idle.is_none(), "duplicated `idle` field");
...@@ -38,12 +41,15 @@ pub fn app(input: &str) -> Result<App> { ...@@ -38,12 +41,15 @@ pub fn app(input: &str) -> Result<App> {
"resources" => { "resources" => {
ensure!(resources.is_none(), "duplicated `resources` field"); 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" => { "tasks" => {
ensure!(tasks.is_none(), "duplicated `tasks` field"); 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), _ => bail!("unknown field: `{}`", key),
} }
...@@ -71,7 +77,11 @@ fn bool(tt: Option<&TokenTree>) -> Result<bool> { ...@@ -71,7 +77,11 @@ fn bool(tt: Option<&TokenTree>) -> Result<bool> {
} }
/// Parses a delimited token tree /// 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 where
F: FnOnce(&[TokenTree]) -> Result<R>, F: FnOnce(&[TokenTree]) -> Result<R>,
{ {
...@@ -137,9 +147,14 @@ fn idle(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Idle> { ...@@ -137,9 +147,14 @@ fn idle(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Idle> {
path = Some(::parse::path(tts)?); path = Some(::parse::path(tts)?);
} }
"resources" => { "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), _ => bail!("unknown field: `{}`", key),
} }
...@@ -188,7 +203,10 @@ fn resources(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Resources> { ...@@ -188,7 +203,10 @@ fn resources(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Resources> {
let mut tts = tts.iter().peekable(); let mut tts = tts.iter().peekable();
while let Some(tt) = tts.next() { while let Some(tt) = tts.next() {
if let &TokenTree::Token(Token::Ident(ref ident)) = tt { 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()); idents.insert(ident.clone());
...@@ -262,14 +280,16 @@ fn statics(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Statics> { ...@@ -262,14 +280,16 @@ fn statics(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Statics> {
let mut tts = tts.iter(); let mut tts = tts.iter();
while let Some(tt) = tts.next() { while let Some(tt) = tts.next() {
match tt { 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); bail!("expected keyword `static`, found {:?}", tt);
} }
} }
let tt = tts.next(); let tt = tts.next();
let ident = if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { let ident =
if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt {
id id
} else { } else {
bail!("expected Ident, found {:?}", tt); bail!("expected Ident, found {:?}", tt);
...@@ -334,22 +354,33 @@ fn task(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Task> { ...@@ -334,22 +354,33 @@ fn task(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Task> {
"enabled" => { "enabled" => {
ensure!(enabled.is_none(), "duplicated `enabled` field"); 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" => { "path" => {
ensure!(path.is_none(), "duplicated `path` field"); 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" => { "priority" => {
ensure!(priority.is_none(), "duplicated `priority` field"); 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" => { "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), _ => bail!("unknown field: `{}`", key),
} }
...@@ -490,19 +521,48 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> { ...@@ -490,19 +521,48 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
ident ident
); );
let tt = tts.next(); let tt = tts.next();
if let Some(&TokenTree::Token(Token::Colon)) = tt { if let Some(&TokenTree::Token(Token::Colon)) = tt {
} else { } else {
bail!("expected Colon, found {:?}", tt); bail!("expected Colon, found {:?}", tt);
} }
let ty = ::parse::ty(&TokenTree::Token(Token::Gt), &mut tts) let tt = tts.next();
.chain_err(|| format!("parsing `type` for {:?}", ident))?; let meth =
if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt {
id
} else {
bail!("expected Ident, found {:?}", tt);
};
let path = ::parse::path(&mut tts).chain_err(|| "parsing `path`")?; //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(); 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 {
// } else {
// bail!("expected Comma, found {:?}", tt);
// };
ips.insert(ident.clone(), (ty, path)); ips.insert(ident.clone(), (meth.clone(), ty_param, ty_return?));
} }
Ok(ips) Ok(ips)
...@@ -533,11 +593,13 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> { ...@@ -533,11 +593,13 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> {
bail!("expected Colon, found {:?}", tt); bail!("expected Colon, found {:?}", tt);
} }
let ty = ::parse::ty(&TokenTree::Token(Token::Eq), &mut tts) let ty =
::parse::ty(&TokenTree::Token(Token::Eq), &mut tts)
.chain_err(|| format!("parsing `type` for {:?}", ident))?; .chain_err(|| format!("parsing `type` for {:?}", ident))?;
let expr = ::parse::expr(&TokenTree::Token(Token::Lt), &mut tts) let expr =
::parse::expr(&TokenTree::Token(Token::Lt), &mut tts)
.chain_err(|| format!("parsing `type` for {:?}", ident))?; .chain_err(|| format!("parsing `type` for {:?}", ident))?;
...@@ -573,7 +635,10 @@ fn ty(token: &TokenTree, tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ty> { ...@@ -573,7 +635,10 @@ fn ty(token: &TokenTree, tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ty> {
} }
/// Parses `$Expr ` /// 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![]; let mut fragments = vec![];
loop { loop {
if let Some(tt) = tts.next() { if let Some(tt) = tts.next() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment