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

hw port

parent 381deb0f
No related branches found
No related tags found
No related merge requests found
...@@ -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),
} }
...@@ -499,7 +530,8 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> { ...@@ -499,7 +530,8 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
let mut ty_arg = None; let mut ty_arg = None;
let mut ty_ret = syn::parse_type(&"()")?; let mut ty_ret = syn::parse_type(&"()")?;
let mut op_sync = None; let mut op_sync = None;
let _ = ::parse::delimited(&mut tts, DelimToken::Brace, |tts| { let _ =
::parse::delimited(&mut tts, DelimToken::Brace, |tts| {
fields(&tts, |key, mut tts| { fields(&tts, |key, mut tts| {
match key.as_ref() { match key.as_ref() {
"sig" => { "sig" => {
...@@ -509,20 +541,33 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> { ...@@ -509,20 +541,33 @@ fn ips(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ips> {
} else { } else {
bail!("expected `fn` Ident, found {:?}", tt); bail!("expected `fn` Ident, found {:?}", tt);
} }
ty_arg = Some(::parse::delimited(&mut tts, DelimToken::Paren, |tts| { ty_arg = Some(::parse::delimited(
Ok(syn::parse_type(&format!("({})", quote!(#(#tts)*)))?) &mut tts,
})?); DelimToken::Paren,
|tts| {
Ok(syn::parse_type(
&format!("({})", quote!(#(#tts)*)),
)?)
},
)?);
let tt = tts.peek().cloned(); let tt = tts.peek().cloned();
let ty_ret: Result<Ty> = match tt { ty_ret =
match tt {
Some(&TokenTree::Token(Token::Comma)) => Ok( Some(&TokenTree::Token(Token::Comma)) => Ok(
syn::parse_type(&"()")?, syn::parse_type(&"()")?,
), ),
Some(&TokenTree::Token(Token::RArrow)) => { Some(&TokenTree::Token(Token::RArrow)) => {
tts.next();
::parse::ty(&TokenTree::Token(Token::Comma), &mut tts) ::parse::ty(&TokenTree::Token(Token::Comma), &mut tts)
} }
_ => bail!("expected `-> Type,' or `,` found {:?}", tt), _ => {
}; bail!(
"expected `-> Type,' or `,` found {:?}",
tt
)
}
}?;
} }
"sync" => { "sync" => {
...@@ -576,7 +621,11 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> { ...@@ -576,7 +621,11 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> {
let tt = tts.next(); let tt = tts.next();
if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt { if let Some(&TokenTree::Token(Token::Ident(ref id))) = tt {
ensure!(id.as_ref() == "fn", "expected `fn` Ident, found {:?}", tt); ensure!(
id.as_ref() == "fn",
"expected `fn` Ident, found {:?}",
tt
);
} else { } else {
bail!("expected `fn` Ident, found {:?}", tt); bail!("expected `fn` Ident, found {:?}", tt);
} }
...@@ -596,7 +645,9 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> { ...@@ -596,7 +645,9 @@ fn ops(tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ops> {
let tt = tts.peek().cloned(); let tt = tts.peek().cloned();
let ty_ret: Result<Ty> = match tt { let ty_ret: Result<Ty> = match tt {
Some(&TokenTree::Token(Token::Comma)) => Ok(syn::parse_type(&"()")?), Some(&TokenTree::Token(Token::Comma)) => Ok(syn::parse_type(
&"()",
)?),
Some(&TokenTree::Token(Token::RArrow)) => { Some(&TokenTree::Token(Token::RArrow)) => {
tts.next(); tts.next();
::parse::ty(&TokenTree::Token(Token::Comma), &mut tts) ::parse::ty(&TokenTree::Token(Token::Comma), &mut tts)
...@@ -639,7 +690,10 @@ fn ty(token: &TokenTree, tts: &mut Peekable<Iter<TokenTree>>) -> Result<Ty> { ...@@ -639,7 +690,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