From 4d2e76338a11c4492a083472b1368e8ce81c3283 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Mon, 22 Sep 2025 20:56:24 -0500 Subject: [PATCH] Refactor build fn for struct nodes. --- ast-generator/src/build_fn/mod.rs | 16 +-- ast-generator/src/build_fn/struct_build_fn.rs | 125 +++++++++--------- ast-generator/src/deserialize/struct_spec.rs | 17 ++- 3 files changed, 86 insertions(+), 72 deletions(-) diff --git a/ast-generator/src/build_fn/mod.rs b/ast-generator/src/build_fn/mod.rs index 8b08734..50fc834 100644 --- a/ast-generator/src/build_fn/mod.rs +++ b/ast-generator/src/build_fn/mod.rs @@ -1,8 +1,8 @@ -pub(crate) mod enum_build_fn; -pub(crate) mod leaf_enum_build_fn; -pub(crate) mod leaf_struct_build_fn; -pub(crate) mod polymorphic_build_build_fn; -pub(crate) mod polymorphic_build_fn; -pub(crate) mod polymorphic_enum_build_fn; -pub(crate) mod production_build_fn; -pub(crate) mod struct_build_fn; +pub mod enum_build_fn; +pub mod leaf_enum_build_fn; +pub mod leaf_struct_build_fn; +pub mod polymorphic_build_build_fn; +pub mod polymorphic_build_fn; +pub mod polymorphic_enum_build_fn; +pub mod production_build_fn; +pub mod struct_build_fn; diff --git a/ast-generator/src/build_fn/struct_build_fn.rs b/ast-generator/src/build_fn/struct_build_fn.rs index 63957b2..92ee6b5 100644 --- a/ast-generator/src/build_fn/struct_build_fn.rs +++ b/ast-generator/src/build_fn/struct_build_fn.rs @@ -1,32 +1,28 @@ -use crate::spec::{ - BooleanChildToBuild, MemberChildToBuild, NodeChildToBuild, StructBuildSpec, StructChildSpec, - VecChild, VecChildToBuild, +use crate::deserialize::util::{make_build_fn_name, make_build_pair}; +use crate::spec::struct_spec::{ + MemberChildBuild, NodeMemberBuild, StructChild, StructSpec, VecChild, VecChildBuild, }; -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_var_name(s: &str) -> String { - s.to_case(Case::Snake) -} - fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { let child_ident = format_ident!("{}", vec_child.name()); match vec_child.build() { - VecChildToBuild::Node(node_child) => { - let child_type_ident = format_ident!("{}", node_child.build()); + VecChildBuild::String(_) => { quote! { - let mut #child_ident: Vec> = vec![] + let mut #child_ident: Vec = vec![] + } + } + VecChildBuild::Node(node_build) => { + let child_type_ident = format_ident!("{}", node_build.kind()); + quote! { + let mut #child_ident: Vec> = vec![] } } - VecChildToBuild::String => quote! { - let mut #child_ident: Vec = vec![] - }, } } -fn make_node_child_holder(name: &str, node_child: &NodeChildToBuild) -> TokenStream { +fn make_node_child_holder(name: &str, node_child: &NodeMemberBuild) -> TokenStream { let child_ident = format_ident!("{}", name); let child_type_ident = format_ident!("{}", node_child.kind()); quote! { @@ -34,24 +30,22 @@ fn make_node_child_holder(name: &str, node_child: &NodeChildToBuild) -> TokenStr } } -fn make_boolean_child_holder(boolean_child: &BooleanChildToBuild) -> TokenStream { - let child_ident = format_ident!("{}", boolean_child.name()); +fn make_boolean_child_holder(name: &str) -> TokenStream { + let child_ident = format_ident!("{}", name); quote! { let mut #child_ident: bool = false } } -fn make_child_holder(child_spec: &StructChildSpec) -> Option { +fn make_child_holder(child_spec: &StructChild) -> Option { match child_spec { - StructChildSpec::SkipChild(_) => None, - StructChildSpec::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)), - StructChildSpec::MemberChild(member_child) => match member_child.build() { - MemberChildToBuild::Node(node_child) => { + StructChild::SkipChild(_) => None, + StructChild::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)), + StructChild::MemberChild(member_child) => match member_child.build() { + MemberChildBuild::Node(node_child) => { Some(make_node_child_holder(member_child.name(), node_child)) } - MemberChildToBuild::Boolean(boolean_child) => { - Some(make_boolean_child_holder(boolean_child)) - } + MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())), }, } } @@ -59,56 +53,56 @@ fn make_child_holder(child_spec: &StructChildSpec) -> Option { fn make_vec_child_match_action(vec_child: &VecChild) -> TokenStream { let child_name_ident = format_ident!("{}", vec_child.name()); match vec_child.build() { - VecChildToBuild::Node(vec_node_child) => { - let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_node_child.build())); - quote! { - #child_name_ident.push(Box::new(#build_fn_ident(inner_pair))) - } - } - VecChildToBuild::String => { - let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_child.rule())); + VecChildBuild::String(string_build) => { + let build_fn_ident = format_ident!("{}", string_build.with()); quote! { #child_name_ident.push(#build_fn_ident(inner_pair)) } } + VecChildBuild::Node(node_build) => { + let build_fn_ident = format_ident!("{}", node_build.with()); + quote! { + #child_name_ident.push(Box::new(#build_fn_ident(inner_pair))) + } + } } } -fn make_node_member_child_match_action(name: &str, node_child: &NodeChildToBuild) -> TokenStream { +fn make_node_member_child_match_action(name: &str, node_child: &NodeMemberBuild) -> TokenStream { let child_name_ident = format_ident!("{}", name); - let build_fn_ident = format_ident!("{}", make_build_fn_name(node_child.kind())); + let build_fn_ident = format_ident!("{}", node_child.with()); quote! { #child_name_ident = Some(Box::new(#build_fn_ident(inner_pair))) } } -fn make_boolean_member_child_match_action(boolean_child: &BooleanChildToBuild) -> TokenStream { - let child_name_ident = format_ident!("{}", make_var_name(boolean_child.name())); +fn make_boolean_member_child_match_action(name: &str) -> TokenStream { + let child_name_ident = format_ident!("{}", name); quote! { #child_name_ident = true } } -fn make_match_action(child_spec: &StructChildSpec) -> TokenStream { +fn make_match_action(child_spec: &StructChild) -> TokenStream { match child_spec { - StructChildSpec::SkipChild(_) => quote! {}, - StructChildSpec::VecChild(vec_child) => make_vec_child_match_action(vec_child), - StructChildSpec::MemberChild(member_child) => match member_child.build() { - MemberChildToBuild::Node(node_child) => { + StructChild::SkipChild(_) => quote! {}, + StructChild::VecChild(vec_child) => make_vec_child_match_action(vec_child), + StructChild::MemberChild(member_child) => match member_child.build() { + MemberChildBuild::Node(node_child) => { make_node_member_child_match_action(member_child.name(), node_child) } - MemberChildToBuild::Boolean(boolean_child) => { - make_boolean_member_child_match_action(boolean_child) + MemberChildBuild::Boolean(_) => { + make_boolean_member_child_match_action(member_child.name()) } }, } } -fn make_rule_matcher(child_spec: &StructChildSpec) -> TokenStream { +fn make_rule_matcher(child_spec: &StructChild) -> TokenStream { let rule_ident = match child_spec { - StructChildSpec::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()), - StructChildSpec::VecChild(vec_child) => format_ident!("{}", vec_child.rule()), - StructChildSpec::MemberChild(single_child) => format_ident!("{}", single_child.rule()), + StructChild::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()), + StructChild::VecChild(vec_child) => format_ident!("{}", vec_child.rule()), + StructChild::MemberChild(single_child) => format_ident!("{}", single_child.rule()), }; let action = make_match_action(child_spec); @@ -124,9 +118,13 @@ fn make_vec_child_arg(vec_child: &VecChild) -> TokenStream { quote! { #child_ident } } -fn make_node_member_child_arg(name: &str, node_child: &NodeChildToBuild) -> TokenStream { +fn make_node_member_child_arg( + name: &str, + optional: bool, + node_child: &NodeMemberBuild, +) -> TokenStream { let child_ident = format_ident!("{}", name); - if node_child.optional() { + if optional { quote! { #child_ident } } else if let Some(or_else) = node_child.or_else() { let child_type_ident = format_ident!("{}", node_child.kind()); @@ -139,28 +137,29 @@ fn make_node_member_child_arg(name: &str, node_child: &NodeChildToBuild) -> Toke } } -fn make_boolean_member_child_arg(boolean_child: &BooleanChildToBuild) -> TokenStream { - let child_ident = format_ident!("{}", boolean_child.name()); +fn make_boolean_member_child_arg(name: &str) -> TokenStream { + let child_ident = format_ident!("{}", name); quote! { #child_ident } } -fn make_child_arg(child_spec: &StructChildSpec) -> Option { +fn make_child_arg(child_spec: &StructChild) -> Option { match child_spec { - StructChildSpec::SkipChild(_) => None, - StructChildSpec::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)), - StructChildSpec::MemberChild(member_child) => match member_child.build() { - MemberChildToBuild::Node(single_type_child) => Some(make_node_member_child_arg( + StructChild::SkipChild(_) => None, + StructChild::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)), + StructChild::MemberChild(member_child) => match member_child.build() { + MemberChildBuild::Node(node_member_build) => Some(make_node_member_child_arg( member_child.name(), - single_type_child, + member_child.optional(), + node_member_build, )), - MemberChildToBuild::Boolean(boolean_child) => { - Some(make_boolean_member_child_arg(boolean_child)) + MemberChildBuild::Boolean(_) => { + Some(make_boolean_member_child_arg(member_child.name())) } }, } } -fn make_return_value_stream(build_spec: &StructBuildSpec) -> TokenStream { +fn make_return_value_stream(build_spec: &StructSpec) -> TokenStream { let type_ident = format_ident!("{}", build_spec.build()); let child_args = build_spec .children() @@ -176,7 +175,7 @@ fn make_return_value_stream(build_spec: &StructBuildSpec) -> TokenStream { } } -pub fn make_struct_build_fn(build_spec: &StructBuildSpec) -> TokenStream { +pub fn make_struct_build_fn(build_spec: &StructSpec) -> TokenStream { let build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.build())); let pair_ident = format_ident!("{}", make_build_pair(build_spec.build())); let return_type_ident = format_ident!("{}", build_spec.build()); diff --git a/ast-generator/src/deserialize/struct_spec.rs b/ast-generator/src/deserialize/struct_spec.rs index e03aee5..2939273 100644 --- a/ast-generator/src/deserialize/struct_spec.rs +++ b/ast-generator/src/deserialize/struct_spec.rs @@ -14,7 +14,22 @@ fn deserialize_vec_child(child_name: &str, props: &Yaml) -> StructChild { let rule = props["rule"].as_str().unwrap(); let kind = props["kind"].as_str() .unwrap_or(rule); - StructChild::VecChild(VecChild::new(child_name, rule, kind)) + if kind == "string" { + let build = VecChildBuild::String(VecChildStringBuild::new( + &make_build_fn_name(rule) + )); + StructChild::VecChild(VecChild::new( + child_name, + rule, + Box::new(build), + )) + } else { + let build = VecChildBuild::Node(VecChildNodeBuild::new( + rule, + &make_build_fn_name(rule) + )); + StructChild::VecChild(VecChild::new(child_name, rule, Box::new(build))) + } } fn deserialize_member_build(child_name: &str, rule: &str, props: &Yaml) -> MemberChildBuild {