From 9d1c8e72300338bc2e5068f0e9699af386caf8ce Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Thu, 1 Apr 2021 11:55:57 -0600 Subject: ideally, but clearly not actually, implement NFA-to-DFA --- bird-machine-macros/src/lib.rs | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'bird-machine-macros/src/lib.rs') diff --git a/bird-machine-macros/src/lib.rs b/bird-machine-macros/src/lib.rs index 628ee91..c6df41c 100644 --- a/bird-machine-macros/src/lib.rs +++ b/bird-machine-macros/src/lib.rs @@ -1,9 +1,11 @@ extern crate proc_macro; use proc_macro::TokenStream; +use proc_macro2::Ident; +use quote::{format_ident, quote, ToTokens}; use syn::{parse_macro_input, DeriveInput, LitStr}; -use quote::{quote, ToTokens}; +mod dfa; mod nfa; #[proc_macro_attribute] @@ -14,13 +16,14 @@ pub fn bird_machine(args: TokenStream, input: TokenStream) -> TokenStream { let input_type_name = &input.ident; let input_lifetimes: Vec<_> = input.generics.lifetimes().collect(); let lifetime = match input_lifetimes.as_slice() { - [] => quote!{ 'unrestricted }, - [lt] => quote!{ #lt }, + [] => quote! { 'unrestricted }, + [lt] => quote! { #lt }, _ => panic!("multiple lifetime generics, what is this, pls to halp"), }; - let machine = build_machine(&input_regex); - dbg!(&machine); + let machine_fn = format_ident!("bird_machine_for_{}", input_type_name); + let machine = build_machine(&input_regex, &machine_fn); + eprintln!("{}", &machine); let (_, ty_generics, where_clause) = input.generics.split_for_impl(); @@ -59,7 +62,7 @@ pub fn bird_machine(args: TokenStream, input: TokenStream) -> TokenStream { }; let is_match = quote! { fn is_match(text: &#lifetime str) -> bool { - todo!() + #machine_fn(text) } }; let is_match_at = quote! { @@ -162,18 +165,21 @@ pub fn bird_machine(args: TokenStream, input: TokenStream) -> TokenStream { tokens.into() } -fn build_machine(regex: &LitStr) -> proc_macro2::TokenStream { +fn build_machine(regex: &LitStr, fn_name: &Ident) -> proc_macro2::TokenStream { let regex_text = regex.value(); - let regex_ir = regex_syntax::Parser::new() - .parse(®ex_text); + let regex_ir = regex_syntax::Parser::new().parse(®ex_text); let regex_ir = match regex_ir { Ok(x) => x, - Err(err ) => panic!("error compiling regex {}: {}", regex.to_token_stream(), err), + Err(err) => panic!("error compiling regex {}: {}", regex.to_token_stream(), err), }; - dbg!(®ex_ir); - // shout out to all the professors who've taught me how to do this - let mut built_nfa = nfa::NFA::default(); + let built_nfa = nfa::NFA::from(®ex_ir); + dbg!("built the NFA"); + let dfa = dfa::DFA::from(built_nfa); - todo!() + quote! { + fn #fn_name(input: &str) -> bool { + #dfa + } + } } -- cgit v1.2.3