schala/schala-lang/codegen/src/lib.rs

55 lines
1.4 KiB
Rust
Raw Normal View History

#![feature(box_patterns)]
#![recursion_limit="128"]
2018-10-17 15:29:32 -07:00
extern crate proc_macro;
#[macro_use]
extern crate quote;
#[macro_use]
2018-10-17 15:29:32 -07:00
extern crate syn;
use self::proc_macro::TokenStream;
use self::syn::fold::Fold;
struct RecursiveDescentFn {
}
impl Fold for RecursiveDescentFn {
fn fold_item_fn(&mut self, mut i: syn::ItemFn) -> syn::ItemFn {
let box block = i.block;
let ref ident = i.ident;
let new_block: syn::Block = parse_quote! {
{
let next_token = self.peek_with_token_offset();
let record = ParseRecord {
production_name: stringify!(#ident).to_string(),
next_token: format!("{}", next_token.to_string_with_metadata()),
level: self.parse_level,
};
self.parse_level += 1;
self.parse_record.push(record);
let result = { #block };
if self.parse_level != 0 {
self.parse_level -= 1;
}
match result {
Err(ParseError { token: None, msg }) =>
Err(ParseError { token: Some(next_token), msg }),
_ => result
}
}
};
i.block = Box::new(new_block);
i
}
}
2018-10-17 15:29:32 -07:00
#[proc_macro_attribute]
pub fn recursive_descent_method(attr: TokenStream, item: TokenStream) -> TokenStream {
let input: syn::ItemFn = parse_macro_input!(item as syn::ItemFn);
let mut folder = RecursiveDescentFn {};
let output = folder.fold_item_fn(input);
TokenStream::from(quote!(#output))
2018-10-17 15:29:32 -07:00
}