From 7a7eda97e3eaf074d1d06b04340fe376bd88b91f Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Tue, 23 Sep 2025 18:08:36 -0500 Subject: [PATCH] Clean up other type gen. --- ast-generator/src/type_gen/enum_type.rs | 37 +++++++++ ast-generator/src/type_gen/leaf_enum_type.rs | 22 ++++++ .../src/type_gen/leaf_struct_type.rs | 78 +++++++++++++++++++ .../src/type_gen/polymorphic_type_type.rs | 22 ++++++ 4 files changed, 159 insertions(+) create mode 100644 ast-generator/src/type_gen/enum_type.rs create mode 100644 ast-generator/src/type_gen/leaf_enum_type.rs create mode 100644 ast-generator/src/type_gen/leaf_struct_type.rs create mode 100644 ast-generator/src/type_gen/polymorphic_type_type.rs diff --git a/ast-generator/src/type_gen/enum_type.rs b/ast-generator/src/type_gen/enum_type.rs new file mode 100644 index 0000000..d2dc2c6 --- /dev/null +++ b/ast-generator/src/type_gen/enum_type.rs @@ -0,0 +1,37 @@ +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec}; + +pub fn make_enum_type(build_spec: &TreeEnumBuildSpec) -> TokenStream { + let children: Vec = build_spec + .rules() + .map(|enum_rule| { + let member_name_ident = format_ident!("{}", enum_rule.rule()); + if let Some(enum_rule_child) = enum_rule.child() { + let child_type_ident = match enum_rule_child.kind() { + EnumRuleChildKind::Node(node_child) => { + format_ident!("{}", node_child.node_kind()) + } + EnumRuleChildKind::Int(_) => format_ident!("i32"), + EnumRuleChildKind::Long(_) => format_ident!("i64"), + EnumRuleChildKind::Double(_) => format_ident!("f64"), + EnumRuleChildKind::String(_) => format_ident!("String"), + EnumRuleChildKind::Boolean(_) => format_ident!("bool"), + }; + quote! { + #member_name_ident(#child_type_ident) + } + } else { + quote! { + #member_name_ident + } + } + }) + .collect(); + let type_name_ident = format_ident!("{}", build_spec.build()); + quote! { + pub enum #type_name_ident { + #(#children),* + } + } +} \ No newline at end of file diff --git a/ast-generator/src/type_gen/leaf_enum_type.rs b/ast-generator/src/type_gen/leaf_enum_type.rs new file mode 100644 index 0000000..2f95d7f --- /dev/null +++ b/ast-generator/src/type_gen/leaf_enum_type.rs @@ -0,0 +1,22 @@ +use crate::spec::leaf_enum_spec::LeafEnumBuildSpec; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +pub fn make_leaf_enum_type(build_spec: &LeafEnumBuildSpec) -> TokenStream { + let type_name_ident = format_ident!("{}", build_spec.build()); + let children = build_spec + .rules() + .map(|leaf_enum_rule| { + let rule_name_ident = format_ident!("{}", leaf_enum_rule); + quote! { + #rule_name_ident + } + }) + .collect::>(); + + quote! { + pub enum #type_name_ident { + #(#children),* + } + } +} diff --git a/ast-generator/src/type_gen/leaf_struct_type.rs b/ast-generator/src/type_gen/leaf_struct_type.rs new file mode 100644 index 0000000..0756fe3 --- /dev/null +++ b/ast-generator/src/type_gen/leaf_struct_type.rs @@ -0,0 +1,78 @@ +use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind}; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +pub fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream { + let type_ident = format_ident!("{}", build_spec.build()); + + let annotated_members = build_spec + .members() + .map(|member| { + let name_ident = format_ident!("{}", member.name()); + let type_ident = match member.kind() { + LeafStructMemberKind::String => format_ident!("{}", "String"), + }; + quote! { + #name_ident: #type_ident + } + }) + .collect::>(); + + let member_args = build_spec.members().map(|member| { + let name_ident = format_ident!("{}", member.name()); + let type_stream = match member.kind() { + LeafStructMemberKind::String => { + quote! { &str } + } + }; + quote! { + #name_ident: #type_stream + } + }); + + let initializers = build_spec + .members() + .map(|leaf_struct_member| { + let member_ident = format_ident!("{}", leaf_struct_member.name()); + match leaf_struct_member.kind() { + LeafStructMemberKind::String => { + quote! { + #member_ident: #member_ident.to_string() + } + } + } + }) + .collect::>(); + + let accessors = build_spec + .members() + .map(|member| { + let name_ident = format_ident!("{}", member.name()); + match member.kind() { + LeafStructMemberKind::String => { + quote! { + pub fn #name_ident(&self) -> &str { + &self.#name_ident + } + } + } + } + }) + .collect::>(); + + quote! { + pub struct #type_ident { + #(#annotated_members),* + } + + impl #type_ident { + pub fn new(#(#member_args),*) -> Self { + Self { + #(#initializers),* + } + } + + #(#accessors)* + } + } +} diff --git a/ast-generator/src/type_gen/polymorphic_type_type.rs b/ast-generator/src/type_gen/polymorphic_type_type.rs new file mode 100644 index 0000000..f58ea87 --- /dev/null +++ b/ast-generator/src/type_gen/polymorphic_type_type.rs @@ -0,0 +1,22 @@ +use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; + +pub fn make_polymorphic_type_type(build_spec: &PolymorphicTypeBuildSpec) -> TokenStream { + let members = build_spec + .variants() + .map(|enum_member| { + let member_ident = format_ident!("{}", enum_member.name()); + let inner_type_ident = format_ident!("{}", enum_member.inner_kind()); + quote! { + #member_ident(#inner_type_ident) + } + }) + .collect::>(); + let type_name_ident = format_ident!("{}", build_spec.name()); + quote! { + pub enum #type_name_ident { + #(#members),* + } + } +}