#![recursion_limit="4096"] extern crate proc_macro; use proc_macro::{TokenStream, TokenTree}; use proc_macro::TokenTree::Group; use std::convert::TryFrom; use litrs::{CharLit, StringLit}; use quote::quote; #[proc_macro] pub fn print_tokens(input: TokenStream) -> TokenStream { println!("{}", input); input } #[proc_macro] pub fn parse_literal(input: TokenStream) -> TokenStream { let mut input_parsed: Vec<TokenTree> = input.clone().into_iter().collect(); if input_parsed.len() != 1 { panic!("expected one token only!"); } match input_parsed.remove(0) { Group(g) => { let mut token_tree: Vec<TokenTree> = g.stream().clone().into_iter().collect(); let token = token_tree.remove(0); let token_copy = token.clone(); let token_copy_copy = token.clone(); match CharLit::try_from(token) { Ok(c) => { let c_val = c.value(); let stream: proc_macro::TokenStream = TokenStream::from(quote!( char(#c_val) )); return stream; }, _ => {} } match StringLit::try_from(token_copy) { Ok(s) => { let v = s.value().to_string(); let crs = s.value().clone().chars().collect::<Vec<char>>().into_iter().rev() .fold(quote!(pure #v), |acc, i| quote!(#i *> #acc)); return TokenStream::from(quote!(parser!(#crs))); }, _ => {} } match token_copy_copy { Group(g) => { let mut token_tree: Vec<TokenTree> = g.stream().clone().into_iter().collect(); let token = token_tree.remove(0); let token_copy = token.clone(); match CharLit::try_from(token) { Ok(c) => { let c_val = c.value(); let stream: proc_macro::TokenStream = TokenStream::from(quote!( char(#c_val) )); return stream; }, _ => {} } match StringLit::try_from(token_copy) { Ok(s) => { let v = s.value().to_string(); let crs = s.value().clone().chars().collect::<Vec<char>>().into_iter().rev() .fold(quote!(pure #v), |acc, i| quote!(#i *> #acc)); return TokenStream::from(quote!(parser!(#crs))); }, _ => {} } }, _ => {} } }, _ => {} } input }