tests for secondary parsers

This commit is contained in:
Breval Ferrari 2024-10-13 01:46:33 -04:00
parent b2b8546f20
commit 0465fb2e4c
No known key found for this signature in database
GPG key ID: 6FED68D87C479A59
6 changed files with 244 additions and 60 deletions

View file

@ -2,13 +2,7 @@ extern crate proc_macro;
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Fields, Ident};
#[proc_macro_derive(ModifierParser)]
pub fn modifier_parser(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
impl_modifier_parser(ast)
}
use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Ident};
#[proc_macro_derive(SlopeModifierParser)]
pub fn slope_modifier_parser(input: TokenStream) -> TokenStream {
@ -22,44 +16,6 @@ pub fn quick_modifier_parser(input: TokenStream) -> TokenStream {
impl_quick_modifier_parser(ast)
}
fn impl_modifier_parser(ast: DeriveInput) -> TokenStream {
let name = &ast.ident;
if let Data::Enum(DataEnum { variants, .. }) = ast.data {
let match_arms = variants.iter().map(|variant| {
let variant_name = &variant.ident;
let variant_type = if let Fields::Unnamed(ref fields) = variant.fields {
&fields.unnamed[0].ty
} else {
panic!("Expected unnamed fields in enum variants");
};
let const_name =
Ident::new(&variant.ident.to_string().to_uppercase(), Span::call_site());
quote! {
nom::combinator::map(
nom::sequence::preceded(
nom::character::complete::char(#name::#const_name),
nom::character::complete::#variant_type
),
#name::#variant_name
)
}
});
quote! {
impl lex::lexer::Parse for #name {
fn parse(input: &str) -> nom::IResult<&str, #name> {
nom::branch::alt((
#(#match_arms),*
))(input)
}
}
}
.into()
} else {
panic!("this macro only works on enums")
}
}
fn impl_slope_modifier_parser(ast: DeriveInput) -> TokenStream {
let name = &ast.ident;
if let Data::Enum(DataEnum { variants, .. }) = ast.data {
@ -98,11 +54,11 @@ fn impl_quick_modifier_parser(ast: DeriveInput) -> TokenStream {
nom::branch::alt(
(
nom::combinator::value(
lex::MORE,
lex::UP,
nom::character::complete::char(#name::#const_name.0)
),
nom::combinator::value(
lex::LESS,
lex::DOWN,
nom::character::complete::char(#name::#const_name.1)
)
)