diff --git a/examples/ex1.rs b/examples/ex1.rs index e85065a0ceb187a023d3217b84d540cb55b48971..cb65f1f22c1d82f9152ec56210f1484d21937ee1 100644 --- a/examples/ex1.rs +++ b/examples/ex1.rs @@ -1,14 +1,20 @@ #![feature(proc_macro)] extern crate parsetest; -use parsetest::mylit; +use parsetest::{mylit, mylitp}; fn main() { println!("here"); - let v = mylit!(99); - println!("v {}", v); + // let v = mylit!(99); + // println!("v {}", v); + + // let v = mylit!(102); + // println!("v {}", v); - let v = mylit!(102); + let v = mylitp!((99)); println!("v {}", v); + + // let v = mylitp!(9o9); + // println!("v {}", v); } diff --git a/src/lib.rs b/src/lib.rs index 66d0fe2dc726cdff226334710a6c88572965487a..0594a343410903eae8bbe6d74f98dfc73a116763 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,13 +7,14 @@ extern crate quote; extern crate syn; use proc_macro::TokenStream; -use syn::punctuated::Punctuated; +// use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::synom::Synom; -use syn::{Expr, ExprArray, Ident, LitInt}; +use syn::LitInt; use quote::ToTokens; use std::convert::From; +use std::error::Error; /// MyLit struct MyLit { @@ -39,3 +40,50 @@ pub fn mylit(input: TokenStream) -> TokenStream { } From::from(v.val.into_tokens()) } + +/// MyLit +struct MyLitP { + val: LitInt, +} + +impl Synom for MyLitP { + named!(parse -> Self, do_parse!( + val: call!(LitInt::parse) >> (MyLitP { val }) + )); +} + +#[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(); + } + } +} + +//panic!("here {}", err), +//let desc = syn::synom::Synom::description(err);