From ae4d120d587da5438f3eddb402912dd432435a4f Mon Sep 17 00:00:00 2001
From: Per Lindgren <per.lindgren@ltu.se>
Date: Sun, 13 Aug 2017 00:26:28 +0200
Subject: [PATCH] jap version

---
 src/parse.rs | 203 +++++++++++++++++++++++++++------------------------
 1 file changed, 109 insertions(+), 94 deletions(-)

diff --git a/src/parse.rs b/src/parse.rs
index b1bce23..deac900 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() {
-- 
GitLab