Finish AstNode impls.

This commit is contained in:
Jesse Brault 2025-09-29 08:53:05 -05:00
parent df8e2279dc
commit dd0bee1c91
5 changed files with 150 additions and 13 deletions

View File

@ -1,6 +1,50 @@
use crate::spec::tree_enum_spec::TreeEnumBuildSpec; use convert_case::{Case, Casing};
use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream { pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream {
todo!() let type_ident = format_ident!("{}", enum_spec.build());
let match_arms = enum_spec
.rules()
.map(|rule| {
let rule_ident = format_ident!("{}", rule.rule());
match rule.child() {
Some(child) => {
match child.kind() {
EnumRuleChildKind::Node(node_child) => {
let child_ident = format_ident!("{}", node_child.node_kind().to_case(Case::Snake));
quote! {
#type_ident::#rule_ident(#child_ident) => vec![
#child_ident.as_node_ref()
]
}
}
_ => quote! {
#type_ident::#rule_ident => vec![]
}
}
},
None => {
quote! {
#type_ident::#rule_ident => vec![]
}
}
}
})
.collect::<Vec<_>>();
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
match self {
#(#match_arms,)*
}
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -1,6 +1,18 @@
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec; use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream { pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream {
todo!() let type_ident = format_ident!("{}", spec.build());
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
vec![]
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
} }

View File

@ -1,6 +1,18 @@
use proc_macro2::TokenStream;
use crate::spec::leaf_struct_spec::LeafStructBuildSpec; use crate::spec::leaf_struct_spec::LeafStructBuildSpec;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream { pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream {
todo!() let type_ident = format_ident!("{}", spec.build());
} quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
vec![]
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
}

View File

@ -1,6 +1,49 @@
use crate::spec::polymorphic_enum_loop_spec::{
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild,
};
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use crate::spec::polymorphic_enum_loop_spec::PolymorphicEnumLoopBuildSpec; use quote::{format_ident, quote};
pub fn make_polymorphic_enum_loop_ast_node_impl(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream { pub fn make_polymorphic_enum_loop_ast_node_impl(
todo!() spec: &PolymorphicEnumLoopBuildSpec,
} ) -> TokenStream {
let type_ident = format_ident!("{}", spec.name());
let build_rule = spec
.rules()
.filter_map(|rule| match rule {
PolymorphicEnumLoopRule::PassThrough(_) => None,
PolymorphicEnumLoopRule::Build(build_rule) => Some(build_rule),
})
.next()
.unwrap();
let child_adders = build_rule
.children()
.map(|child| {
let child_ident = match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
format_ident!("{}", use_current.name())
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
format_ident!("{}", on_each.name())
}
};
quote! {
children.push(self.#child_ident().as_node_ref())
}
})
.collect::<Vec<_>>();
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
let mut children: Vec<AstNodeRef> = vec![];
#(#child_adders;)*
children
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
}

View File

@ -1,6 +1,32 @@
use proc_macro2::TokenStream;
use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec; use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream { pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream {
todo!() let type_ident = format_ident!("{}", spec.name());
} let match_arms = spec
.variants()
.map(|variant| {
let variant_ident = format_ident!("{}", variant.name());
let child_ident = format_ident!("{}", variant.inner_kind().to_case(Case::Snake));
quote! {
#type_ident::#variant_ident(#child_ident) => vec![#child_ident]
}
})
.collect::<Vec<_>>();
quote! {
impl AstNode for #type_ident {
fn children(&self) -> Vec<AstNodeRef> {
match self {
#(#match_arms,)*
}
}
fn as_node_ref(&self) -> AstNodeRef {
AstNodeRef::#type_ident(&self)
}
}
}
}