diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index cc7543bd1285545d68ee100b9d7f207b74e6d3c0..51e1bacbaae588938d0589c503cf8fadb74945a6 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -50,6 +50,18 @@
                 "kind": "build",
                 "isDefault": true
             }
-        }
+        },
+        {
+            "type": "shell",
+            "label": "cargo run --example app",
+            "command": "cargo run --example app",
+            "problemMatcher": [
+                "$rustc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            }
+        },
     ]
 }
\ No newline at end of file
diff --git a/examples/app.rs b/examples/app.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a5690dd36e35597a57a57eef48859908c4d5e310
--- /dev/null
+++ b/examples/app.rs
@@ -0,0 +1,12 @@
+#![feature(proc_macro)]
+
+extern crate parsetest;
+use parsetest::app;
+
+app!{
+    id1, id2
+}
+
+fn main() {
+    println!("here");
+}
diff --git a/src/lib.rs b/src/lib.rs
index e59aaf4ccc80cceb5ff6a7e9a5d8efe69b877326..b8d51aa7afede22323ad11a2f250264dc3d5f355 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,7 +9,7 @@ extern crate syn;
 use proc_macro::TokenStream;
 use syn::spanned::Spanned;
 use syn::synom::Synom;
-use syn::LitInt;
+use syn::{Ident, LitInt};
 use quote::ToTokens;
 
 use std::convert::From;
@@ -24,7 +24,10 @@ pub fn lit(input: TokenStream) -> TokenStream {
     if !(10 <= value && value < 100) {
         v.span()
             .unstable()
-            .error(format!("expected literal 10 <= x < 100, got {}", value,))
+            .error(format!(
+                "expected literal 10 <= x < 100, got {}",
+                value,
+            ))
             .emit();
     }
     From::from(v.into_tokens())
@@ -40,7 +43,10 @@ pub fn lite(input: TokenStream) -> TokenStream {
             if !(10 <= value && value < 100) {
                 v.span()
                     .unstable()
-                    .error(format!("expected literal 10 <= x < 100, got {}", value,))
+                    .error(format!(
+                        "expected literal 10 <= x < 100, got {}",
+                        value,
+                    ))
                     .emit();
             }
             From::from(v.into_tokens())
@@ -55,6 +61,89 @@ pub fn lite(input: TokenStream) -> TokenStream {
     }
 }
 
+use syn::Path;
+
+enum AppKeys {
+    Device,
+    Resources,
+    Interrupts,
+    Tasks,
+    Idle,
+    Init,
+}
+
+fn to_app_keys(id: Ident) -> Option<AppKeys> {
+    match id.as_ref() {
+        "device" => Some(AppKeys::Device),
+        _ => None,
+    }
+}
+
+// struct KeyVal {
+
+// }
+
+// impl Synom for KeyVal {
+//     named!(parse -> Self, do_parse!(
+//         val: syn!(Punctuadet) >> (KeyVal {  })
+
+//          field: syn!(Ident) >>
+//        _colon: punct!(:) >>
+// +           switch!(value!(field.as_ref()),
+//                 "path" => map!(syn!(Path), |path| {
+// +                        parsed_init.path = Some(path);
+// +                    }) |
+// +                    "resources" => map!(parse_resource_ident, |res| {
+// +                        parsed_init.resources = Some(res);
+// +                    }) |
+// +                    _ => call!(|_| {
+// +                        field.span.unstable().error(format!("Unknown field `{}`", field)).emit();
+// +                        panic!("Unknown field `{}`", field);
+// +                    })
+// +                ) >>
+// +                _comma: syn!(Token![,]) >>
+// +                (())
+//     ));
+// }
+
+use syn::punctuated::Punctuated;
+struct AppK {}
+
+struct KeyVal {
+    kv: Punctuated<Ident, Token![,]>,
+}
+
+impl Synom for KeyVal {
+    named!(parse -> Self, do_parse!(
+        kv: call!(Punctuated::parse_terminated_nonempty) >> 
+        (KeyVal { kv })
+    ));
+}
+
+#[proc_macro]
+pub fn app(input: TokenStream) -> TokenStream {
+    println!("-- app --");
+    let k: KeyVal = syn::parse(input).unwrap();
+    for k in k.kv.into_iter() {
+        println!("{:?}", k.as_ref());
+    }
+    //  {
+    //     Ok(app) => {
+    //         let tokens = quote!();
+    //         tokens.into()
+    //     }
+    //     Err(err) => {
+    //         let desc = err.description();
+    //         let tokens = quote! {
+    //             compile_error!(#desc)
+    //         };
+    //         tokens.into()
+    //     }
+    // }
+    let tokens = quote!();
+    tokens.into()
+}
+
 // named!(parse -> LitInt, do_parse!(
 //         val: syn!(LitInt) >> (val)
 //     ));
@@ -85,30 +174,33 @@ pub fn lite(input: TokenStream) -> TokenStream {
 //     }
 // }
 
-/// MyLit
-struct MyLit {
-    val: LitInt,
-}
+// /// MyLit
+// struct MyLit {
+//     val: LitInt,
+// }
 
-impl Synom for MyLit {
-    named!(parse -> Self, do_parse!(
-        val: syn!(LitInt) >> (MyLit { val })
-    ));
-}
+// impl Synom for MyLit {
+//     named!(parse -> Self, do_parse!(
+//         val: syn!(LitInt) >> (MyLit { val })
+//     ));
+// }
 
-#[proc_macro]
-pub fn mylit(input: TokenStream) -> TokenStream {
-    let v: MyLit = syn::parse(input).unwrap();
-    let value = v.val.value();
-    if !(10 <= value && value < 100) {
-        v.val
-            .span()
-            .unstable()
-            .error(format!("expected literal 10 <= x < 100, got {}", value,))
-            .emit();
-    }
-    From::from(v.val.into_tokens())
-}
+// #[proc_macro]
+// pub fn mylit(input: TokenStream) -> TokenStream {
+//     let v: MyLit = syn::parse(input).unwrap();
+//     let value = v.val.value();
+//     if !(10 <= value && value < 100) {
+//         v.val
+//             .span()
+//             .unstable()
+//             .error(format!(
+//                 "expected literal 10 <= x < 100, got {}",
+//                 value,
+//             ))
+//             .emit();
+//     }
+//     From::from(v.val.into_tokens())
+// }
 
 // /// MyLitP
 // struct MyLitP {