Try generating named functions via proc macros
This commit is contained in:
+53
-1
@@ -1,8 +1,39 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
Ident, Token,
|
||||
parse::{Parse, ParseStream},
|
||||
parse_macro_input,
|
||||
punctuated::Punctuated,
|
||||
};
|
||||
|
||||
struct Grammar {
|
||||
rules: Punctuated<Rule, Token![;]>,
|
||||
}
|
||||
|
||||
struct Rule {
|
||||
name: Ident,
|
||||
}
|
||||
|
||||
impl Parse for Grammar {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
Ok(Grammar {
|
||||
rules: Punctuated::parse_terminated(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for Rule {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let result = Self {
|
||||
name: input.parse()?,
|
||||
};
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn grammar(ts: TokenStream) -> TokenStream {
|
||||
pub fn grammar_old(ts: TokenStream) -> TokenStream {
|
||||
let token = ts.into_iter().next().expect("must have at least one token");
|
||||
let result = match token {
|
||||
proc_macro::TokenTree::Literal(literal) => {
|
||||
@@ -25,3 +56,24 @@ pub fn grammar(ts: TokenStream) -> TokenStream {
|
||||
|
||||
quote! { println!("Hello, world! {:?}", #result); }.into()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn grammar(ts: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(ts as Grammar);
|
||||
let fns: Vec<_> = input
|
||||
.rules
|
||||
.iter()
|
||||
.map(|r| {
|
||||
let fn_name = &r.name;
|
||||
quote! {
|
||||
fn #fn_name() -> String {
|
||||
"I'm a generated function!".into()
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
quote! {
|
||||
#(#fns)*
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user