Skip to content
Snippets Groups Projects
Select Git revision
  • 50712777ee590cbfb711496daa41c49f83075f96
  • master default protected
2 results

exception.rs

Blame
  • lib.rs 7.74 KiB
    #![feature(proc_macro)]
    
    extern crate proc_macro;
    extern crate proc_macro2 as pm2;
    #[macro_use]
    extern crate quote;
    #[macro_use]
    extern crate syn;
    
    use proc_macro::TokenStream;
    use syn::spanned::Spanned;
    use syn::synom::Synom;
    use syn::{Ident, LitInt};
    use quote::ToTokens;
    
    use std::convert::From;
    use std::error::Error;
    
    /// Procedural macro `lit`
    /// Parsing a `LitInt` with compile time range checking
    #[proc_macro]
    pub fn lit(input: TokenStream) -> TokenStream {
        let v: LitInt = syn::parse(input).unwrap();
        let value = v.value();
        if !(10 <= value && value < 100) {
            v.span()
                .unstable()
                .error(format!("expected literal 10 <= x < 100, got {}", value,))
                .emit();
        }
        From::from(v.into_tokens())
    }
    
    /// Procedural macro `lite`
    /// Parsing a `LitInt` with compile time range checking
    #[proc_macro]
    pub fn lite(input: TokenStream) -> TokenStream {
        match syn::parse::<LitInt>(input) {
            Ok(v) => {
                let value = v.value();
                if !(10 <= value && value < 100) {
                    v.span()
                        .unstable()
                        .error(format!("expected literal 10 <= x < 100, got {}", value,))
                        .emit();
                }
                From::from(v.into_tokens())
            }
            Err(err) => {
                let desc = err.description();
                let tokens = quote! {
                    compile_error!(#desc)
                };
                return tokens.into();
            }
        }
    }
    
    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 KeyVal {
        key: Ident,
        val: pm2::TokenStream,
    }
    
    impl Synom for KeyVal {
        named!(parse -> Self, do_parse!(
            key: call!(Ident::parse) >> 
            val: call!(pm2::TokenStream::parse) >> (KeyVal { key, val })
        ));
    }
    
    struct KeyVals {
        keyvals: Punctuated<KeyVal, Token![,]>,
    }
    
    impl Synom for KeyVals {
        named!(parse -> Self, do_parse!(
            keyvals: call!(Punctuated::parse_terminated_nonempty) >> 
            (KeyVals { keyvals })
        ));
    }
    
    #[proc_macro]
    pub fn app(input: TokenStream) -> TokenStream {
        println!("-- app --");
        let k: KeyVals = syn::parse(input).unwrap();
        for k in k.keyvals.into_iter() {
            println!("{:?}", k.key.as_ref());
            println!("{:?}", k.val);
        }
        //  {
        //     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)
    //     ));
    
    // /// Procedural macro `litep`
    // /// Parsing a `(LitInt)` into a `LitInt` with compile time range checking
    // #[proc_macro]
    // pub fn litep(input: TokenStream) -> TokenStream {
    //     let v = do_parse!(val: parens!(call!(LitInt::parse)) >> (MyLitP { val: val.1 }));
    //     match v(input) {
    //         Ok(v) => {
    //             let value = v.value();
    //             if !(10 <= value && value < 100) {
    //                 v.span()
    //                     .unstable()
    //                     .error(format!("expected literal 10 <= x < 100, got {}", value,))
    //                     .emit();
    //             }
    //             From::from(v.into_tokens())
    //         }
    //         Err(err) => {
    //             let desc = err.description();
    //             let tokens = quote! {
    //                 compile_error!(#desc)
    //             };
    //             return tokens.into();
    //         }
    //     }
    // }
    
    // /// MyLit
    // struct MyLit {
    //     val: LitInt,
    // }
    
    // 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())
    // }
    
    // /// MyLitP
    // struct MyLitP {
    //     val: LitInt,
    // }
    
    // impl Synom for MyLitP {
    //     named!(parse -> Self, do_parse!(
    //         val: parens!(call!(LitInt::parse)) >> (MyLitP { val: val.1 })
    //     ));
    // }
    
    // #[proc_macro]
    // pub fn mylitp(input: TokenStream) -> TokenStream {
    //     match syn::parse::<MyLitP>(input) {
    //         Ok(v) => {
    //             let value: u32 = v.val.value() as u32;
    //             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())
    //         }
    //         Err(err) => {
    //             let desc = err.description();
    //             let tokens = quote! {
    //                 compile_error!(#desc)
    //             };
    //             return tokens.into();
    //         }
    //     }
    // }
    
    // // /// MyLits
    // // struct MyLits {
    // //     val: LitInt,
    // //     valp: LitInt,
    // // }
    
    // // impl Synom for MyLits {
    
    // //     named!(parse -> Self, do_parse!(
    // //         val: syn!
    // //         valp: parens!(call!(LitInt::parse)) >> (MyLitP { val: val.1 })
    // //     ));
    // // }
    
    // // #[proc_macro]
    // // pub fn mylitp(input: TokenStream) -> TokenStream {
    // //     match syn::parse::<MyLitP>(input) {
    // //         Ok(v) => {
    // //             let value: u32 = v.val.value() as u32;
    // //             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())
    // //         }
    // //         Err(err) => {
    // //             //let desc = format!("could not parse {:?}", err);
    // //             let desc = err.description();
    // //             // println!(
    // //             //     "here -----------------------------------------desc {:?}",
    // //             //     desc
    // //             // );
    // //             let tokens = quote! {
    // //                 compile_error!(#desc)
    // //             };
    
    // //             return tokens.into();
    // //         }
    // //     }
    // // }