diff --git a/ast-generator/src/build_fn/mod.rs b/ast-generator/src/build_fn/mod.rs index af47179..fe71df2 100644 --- a/ast-generator/src/build_fn/mod.rs +++ b/ast-generator/src/build_fn/mod.rs @@ -2,19 +2,17 @@ use crate::build_fn::leaf_enum_build_fn::make_leaf_enum_build_fn; use crate::build_fn::leaf_struct_build_fn::make_leaf_struct_build_fn; use crate::build_fn::node_production_build_fn::make_node_production_build_fn; use crate::build_fn::polymorphic_enum_loop_build_fn::make_polymorphic_enum_loop_build_fn; +use crate::build_fn::polymorphic_pass_through_build_fn::make_polymorphic_pass_through_build_fn; use crate::build_fn::polymorphic_type_build_fn::make_polymorphic_type_build_fn; use crate::build_fn::production_build_fn::make_production_build_fn; use crate::build_fn::struct_build_fn::make_struct_build_fn; use crate::build_fn::tree_enum_build_fn::make_enum_build_fn; use crate::spec::BuildSpec; use proc_macro2::TokenStream; -use crate::build_fn::polymorphic_pass_through_build_fn::make_polymorphic_pass_through_build_fn; mod leaf_enum_build_fn; mod leaf_struct_build_fn; mod node_production_build_fn; -mod polymorphic_build_build_fn; -mod polymorphic_enum_build_fn; mod polymorphic_enum_loop_build_fn; mod polymorphic_pass_through_build_fn; mod polymorphic_type_build_fn; diff --git a/ast-generator/src/build_fn/polymorphic_build_build_fn.rs b/ast-generator/src/build_fn/polymorphic_build_build_fn.rs deleted file mode 100644 index 6d75639..0000000 --- a/ast-generator/src/build_fn/polymorphic_build_build_fn.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::spec::{ - AlternativeAction, AlternativeBuild, AlternativeBuildChild, AlternativeChild, AlternativeTest, - PolymorphicBuildBuildSpec, -}; -use crate::util::{make_build_fn_name, make_build_pair}; -use convert_case::{Case, Casing}; -use proc_macro2::TokenStream; -use quote::{format_ident, quote}; - -fn make_build_child(build_child: &AlternativeBuildChild) -> TokenStream { - let rule_ident = format_ident!("{}", build_child.rule()); - let child_ident = format_ident!("{}", build_child.name()); - let child_build_fn_ident = format_ident!("{}", make_build_fn_name(build_child.rule())); - - quote! { - Rule::#rule_ident => { - #child_ident = Some(#child_build_fn_ident(inner_pair)); - } - } -} - -fn make_build_action( - spec: &PolymorphicBuildBuildSpec, - alternative_build: &AlternativeBuild, -) -> TokenStream { - let enum_type_ident = format_ident!("{}", spec.return_type()); - let enum_variant_ident = format_ident!("{}", alternative_build.enum_variant()); - - let child_holders = alternative_build - .children() - .map(|child| match child { - AlternativeChild::Skip => None, - AlternativeChild::Build(build_child) => { - let child_ident = format_ident!("{}", build_child.name()); - let child_type_ident = format_ident!("{}", build_child.kind()); - Some(quote! { - let mut #child_ident: Option<#child_type_ident> = None - }) - } - }) - .filter(Option::is_some) - .map(Option::unwrap) - .collect::>(); - - let pair_ident = format_ident!("{}", make_build_pair(spec.name())); - - let rule_matchers = alternative_build - .children() - .map(|child| match child { - AlternativeChild::Skip => None, - AlternativeChild::Build(build_child) => Some(make_build_child(build_child)), - }) - .filter(Option::is_some) - .map(Option::unwrap) - .collect::>(); - - let built_ident = format_ident!("{}", spec.name().to_case(Case::Snake)); - let inner_type_ident = format_ident!("{}", spec.name()); - let child_args = alternative_build - .children() - .map(|child| match child { - AlternativeChild::Skip => None, - AlternativeChild::Build(child_build) => { - let child_ident = format_ident!("{}", child_build.name()); - Some(quote! { - Box::new(#child_ident.unwrap()) - }) - } - }) - .filter(Option::is_some) - .map(Option::unwrap) - .collect::>(); - - quote! { - #(#child_holders;)* - - for inner_pair in #pair_ident.into_inner() { - match inner_pair.as_rule() { - #(#rule_matchers),* - _ => unreachable!() - } - } - - let #built_ident = #inner_type_ident::new(#(#child_args),*); - - #enum_type_ident::#enum_variant_ident(#built_ident) - } -} - -pub fn make_polymorphic_build_build_fn(spec: &PolymorphicBuildBuildSpec) -> TokenStream { - let build_fn_ident = format_ident!("{}", make_build_fn_name(spec.name())); - let pair_ident = format_ident!("{}", make_build_pair(spec.name())); - let return_type_ident = format_ident!("{}", spec.return_type()); - - let alternatives = spec - .alternatives() - .map(|alternative| { - let count_to_match: usize = match alternative.test() { - AlternativeTest::NumberOfPairs(count) => count.clone().try_into().unwrap(), - }; - let action = match alternative.action() { - AlternativeAction::ReturnBuild(kind) => { - let inner_build_fn_ident = format_ident!("{}", make_build_fn_name(kind)); - quote! { - let inner_pair = #pair_ident.into_inner().next().unwrap(); - #inner_build_fn_ident(inner_pair) - } - } - AlternativeAction::Build(alternative_build) => { - make_build_action(spec, alternative_build) - } - }; - quote! { - #count_to_match => { - #action - } - } - }) - .collect::>(); - - quote! { - fn #build_fn_ident(#pair_ident: Pair) -> #return_type_ident { - let count = #pair_ident.clone().into_inner().count(); - match count { - #(#alternatives,)* - _ => unreachable!() - } - } - } -} diff --git a/ast-generator/src/build_fn/polymorphic_enum_build_fn.rs b/ast-generator/src/build_fn/polymorphic_enum_build_fn.rs deleted file mode 100644 index 7d45b28..0000000 --- a/ast-generator/src/build_fn/polymorphic_enum_build_fn.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::spec::{PolymorphicEnumBuildSpec, PolymorphicEnumRule}; -use crate::util::{make_build_fn_name, make_build_pair}; -use proc_macro2::TokenStream; -use quote::{format_ident, quote}; - -pub fn make_polymorphic_enum_build_fn(spec: &PolymorphicEnumBuildSpec) -> TokenStream { - let build_fn_ident = format_ident!("{}", make_build_fn_name(spec.name())); - let pair_ident = format_ident!("{}", make_build_pair(spec.name())); - let return_type_ident = format_ident!("{}", spec.return_type()); - - let match_arms = spec.rules() - .map(|rule| { - match rule { - PolymorphicEnumRule::Wrap(name_and_kind) => { - let rule_ident = format_ident!("{}", name_and_kind.name()); - let enum_variant_ident = format_ident!("{}", name_and_kind.kind()); - let rule_build_fn = format_ident!("{}", make_build_fn_name(name_and_kind.name())); - quote! { - Rule::#rule_ident => #return_type_ident::#enum_variant_ident(#rule_build_fn(inner_pair)) - } - }, - PolymorphicEnumRule::ReturnBuild(name_and_kind) => { - let rule_ident = format_ident!("{}", name_and_kind.name()); - let rule_build_fn = format_ident!("{}", make_build_fn_name(name_and_kind.kind())); - quote! { - Rule::#rule_ident => #rule_build_fn(inner_pair) - } - } - } - }) - .collect::>(); - - quote! { - fn #build_fn_ident(#pair_ident: Pair) -> #return_type_ident { - let inner_pair = #pair_ident.into_inner().next().unwrap(); - match inner_pair.as_rule() { - #(#match_arms,)* - _ => unreachable!() - } - } - } -}