diff --git a/ast-generator/src/struct_build_fn.rs b/ast-generator/src/struct_build_fn.rs index bfbebc4..619f77f 100644 --- a/ast-generator/src/struct_build_fn.rs +++ b/ast-generator/src/struct_build_fn.rs @@ -10,19 +10,21 @@ fn make_var_name(s: &str) -> String { fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream { let child_ident = format_ident!("{}", vec_child.name()); - let child_type_ident = match vec_child.build() { + match vec_child.build() { VecChildToBuild::Node(node_child) => { - format_ident!("{}", node_child.build()) + let child_type_ident = format_ident!("{}", node_child.build()); + quote! { + let mut #child_ident: Vec> = vec![] + } }, - VecChildToBuild::String => format_ident!("{}", "String") - }; - quote! { - let mut #child_ident: Vec> = vec![] + VecChildToBuild::String => quote! { + let mut #child_ident: Vec = vec![] + } } } -fn make_node_child_holder(node_child: &NodeChildToBuild) -> TokenStream { - let child_ident = format_ident!("{}", make_var_name(node_child.build())); +fn make_node_child_holder(name: &str, node_child: &NodeChildToBuild) -> TokenStream { + let child_ident = format_ident!("{}", name); let child_type_ident = format_ident!("{}", node_child.build()); quote! { let mut #child_ident: Option> = None @@ -42,7 +44,7 @@ fn make_child_holder(child_spec: &StructChildSpec) -> Option { StructChildSpec::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)), StructChildSpec::MemberChild(member_child) => match member_child.build() { MemberChildToBuild::Node(node_child) => { - Some(make_node_child_holder(node_child)) + Some(make_node_child_holder(member_child.name(), node_child)) } MemberChildToBuild::Boolean(boolean_child) => { Some(make_boolean_child_holder(boolean_child)) @@ -53,21 +55,24 @@ 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()); - let build_fn_ident = match vec_child.build() { + match vec_child.build() { VecChildToBuild::Node(vec_node_child) => { - format_ident!("{}", make_build_fn_name(vec_node_child.build())) + 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 => { - format_ident!("{}", make_build_fn_name(vec_child.rule())) + let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_child.rule())); + quote! { + #child_name_ident.push(#build_fn_ident(inner_pair)) + } } - }; - quote! { - #child_name_ident.push(Box::new(#build_fn_ident(inner_pair))) } } -fn make_node_member_child_match_action(node_child: &NodeChildToBuild) -> TokenStream { - let child_name_ident = format_ident!("{}", make_var_name(node_child.build())); +fn make_node_member_child_match_action(name: &str, node_child: &NodeChildToBuild) -> TokenStream { + let child_name_ident = format_ident!("{}", name); let build_fn_ident = format_ident!("{}", make_build_fn_name(node_child.build())); quote! { #child_name_ident = Some(Box::new(#build_fn_ident(inner_pair))) @@ -87,9 +92,9 @@ fn make_match_action(child_spec: &StructChildSpec) -> TokenStream { StructChildSpec::VecChild(vec_child) => { make_vec_child_match_action(vec_child) } - StructChildSpec::MemberChild(single_child) => match single_child.build() { + StructChildSpec::MemberChild(member_child) => match member_child.build() { MemberChildToBuild::Node(node_child) => { - make_node_member_child_match_action(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) diff --git a/ast-generator/src/type_gen.rs b/ast-generator/src/type_gen.rs index 3a479d4..4ec62db 100644 --- a/ast-generator/src/type_gen.rs +++ b/ast-generator/src/type_gen.rs @@ -1,5 +1,8 @@ -use convert_case::{Case, Casing}; -use crate::spec::{BooleanChildToBuild, BuildSpec, EnumBuildSpec, EnumRuleChildKind, LeafEnumBuildSpec, LeafStructBuildSpec, LeafStructMemberKind, MemberChildToBuild, NodeChildToBuild, StructBuildSpec, StructChildSpec, VecChild, VecChildToBuild}; +use crate::spec::{ + BooleanChildToBuild, BuildSpec, EnumBuildSpec, EnumRuleChildKind, LeafEnumBuildSpec, + LeafStructBuildSpec, LeafStructMemberKind, MemberChildToBuild, NodeChildToBuild, + StructBuildSpec, StructChildSpec, VecChild, VecChildToBuild, +}; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; @@ -12,7 +15,7 @@ fn make_enum_type(build_spec: &EnumBuildSpec) -> TokenStream { let child_type_ident = match enum_rule_child.kind() { EnumRuleChildKind::Node(node_child) => { format_ident!("{}", node_child.build()) - }, + } EnumRuleChildKind::Int => format_ident!("i32"), EnumRuleChildKind::Long => format_ident!("i64"), EnumRuleChildKind::Double => format_ident!("f64"), @@ -61,11 +64,12 @@ fn handle_vec_child( vec_child: &VecChild, member_names: &mut Vec, annotated_members: &mut Vec, + member_args: &mut Vec, accessors: &mut Vec, ) { let (child_ident, child_ident_mut) = ( format_ident!("{}", vec_child.name()), - format_ident!("{}", vec_child.name()), + format_ident!("{}_mut", vec_child.name()), ); let child_type_ident = match vec_child.build() { VecChildToBuild::Node(vec_node_child) => format_ident!("{}", vec_node_child.build()), @@ -73,39 +77,73 @@ fn handle_vec_child( }; member_names.push(child_ident.clone()); - annotated_members.push(quote! { - #child_ident: Vec> - }); - accessors.push(quote! { - pub fn #child_ident(&self) -> impl Iterator { - self.#child_ident.iter().map(Box::as_ref) - } - pub fn #child_ident_mut(&mut self) -> impl Iterator { - self.#child_ident.iter_mut().map(Box::as_mut) + match vec_child.build() { + VecChildToBuild::Node(_) => { + annotated_members.push(quote! { + #child_ident: Vec> + }); + member_args.push(quote! { + #child_ident: Vec> + }); } - }); + VecChildToBuild::String => { + annotated_members.push(quote! { + #child_ident: Vec + }); + member_args.push(quote! { + #child_ident: Vec + }) + } + } + + match vec_child.build() { + VecChildToBuild::Node(_) => { + accessors.push(quote! { + pub fn #child_ident(&self) -> impl Iterator { + self.#child_ident.iter().map(Box::as_ref) + } + + pub fn #child_ident_mut(&mut self) -> impl Iterator { + self.#child_ident.iter_mut().map(Box::as_mut) + } + }); + } + VecChildToBuild::String => accessors.push(quote! { + pub fn #child_ident(&self) -> impl Iterator { + self.#child_ident.iter().map(String::as_str) + } + }), + } } fn handle_node_child( + name: &str, node_child: &NodeChildToBuild, member_names: &mut Vec, annotated_members: &mut Vec, + member_args: &mut Vec, accessors: &mut Vec, ) { - let child_ident = format_ident!("{}", node_child.build().to_case(Case::Snake)); - let child_ident_mut = format_ident!("{}_mut", child_ident); + let child_ident = format_ident!("{}", name); + let child_ident_mut = format_ident!("{}_mut", name); let child_type_ident = format_ident!("{}", node_child.build()); - + member_names.push(child_ident.clone()); - + if node_child.optional() { annotated_members.push(quote! { #child_ident: Option> }); + member_args.push(quote! { + #child_ident: Option> + }); } else { annotated_members.push(quote! { #child_ident: Box<#child_type_ident> + }); + member_args.push(quote! { + #child_ident: Box<#child_type_ident> }) } if node_child.optional() { @@ -125,7 +163,7 @@ fn handle_node_child( None } } - }) + }); } else { accessors.push(quote! { pub fn #child_ident(&self) -> &#child_type_ident { @@ -143,6 +181,7 @@ fn handle_boolean_child( single_boolean_child: &BooleanChildToBuild, member_names: &mut Vec, annotated_members: &mut Vec, + member_args: &mut Vec, accessors: &mut Vec, ) { let child_ident = format_ident!("{}", single_boolean_child.name()); @@ -150,16 +189,20 @@ fn handle_boolean_child( annotated_members.push(quote! { #child_ident: bool }); + member_args.push(quote! { + #child_ident: bool + }); accessors.push(quote! { pub fn #child_ident(&self) -> bool { self.#child_ident } - }) + }); } fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream { let mut member_names: Vec = vec![]; let mut annotated_members: Vec = vec![]; + let mut member_args: Vec = vec![]; let mut accessors: Vec = vec![]; for child_spec in build_spec.children() { @@ -170,6 +213,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream { vec_child, &mut member_names, &mut annotated_members, + &mut member_args, &mut accessors, ); } @@ -177,9 +221,11 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream { match member_child.build() { MemberChildToBuild::Node(node_child) => { handle_node_child( + member_child.name(), node_child, &mut member_names, &mut annotated_members, + &mut member_args, &mut accessors, ); } @@ -188,6 +234,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream { boolean_child, &mut member_names, &mut annotated_members, + &mut member_args, &mut accessors, ); } @@ -231,9 +278,30 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream { }) .collect::>(); - let member_names = build_spec + 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_child| format_ident!("{}", leaf_struct_child.name())) + .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 @@ -258,9 +326,9 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream { } impl #type_ident { - pub fn new(#(#annotated_members),*) -> Self { + pub fn new(#(#member_args),*) -> Self { Self { - #(#member_names),* + #(#initializers),* } } @@ -272,11 +340,13 @@ fn make_leaf_struct_type(build_spec: &LeafStructBuildSpec) -> TokenStream { pub fn make_type(build_spec: &BuildSpec) -> Option { match build_spec { BuildSpec::Enum(enum_build_spec) => Some(make_enum_type(enum_build_spec)), - BuildSpec::LeafEnum(leaf_enum_build_spec) => Some(make_leaf_enum_type(leaf_enum_build_spec)), + BuildSpec::LeafEnum(leaf_enum_build_spec) => { + Some(make_leaf_enum_type(leaf_enum_build_spec)) + } BuildSpec::Struct(struct_build_spec) => Some(make_struct_type(struct_build_spec)), BuildSpec::LeafStruct(leaf_struct_build_spec) => { Some(make_leaf_struct_type(leaf_struct_build_spec)) - }, - BuildSpec::Production(production_build_spec) => None + } + BuildSpec::Production(_) => None, } } diff --git a/src/std_core/mod.rs b/src/std_core/mod.rs index 15228d6..5361186 100644 --- a/src/std_core/mod.rs +++ b/src/std_core/mod.rs @@ -1,14 +1,14 @@ -use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol}; -use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; - -pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { - symbol_table.insert_function_symbol( - FunctionSymbol::new("std::core::println", "println", true, true, None) - .with_parameters(vec![ParameterSymbol::new("msg", None)]), - )?; - symbol_table.insert_function_symbol( - FunctionSymbol::new("std::core::print", "print", true, true, None) - .with_parameters(vec![ParameterSymbol::new("msg", None)]), - )?; - Ok(()) -} +// use crate::name_analysis::symbol::{FunctionSymbol, ParameterSymbol}; +// use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable}; +// +// pub fn add_std_core_symbols(symbol_table: &mut SymbolTable) -> Result<(), SymbolInsertError> { +// symbol_table.insert_function_symbol( +// FunctionSymbol::new("std::core::println", "println", true, true, None) +// .with_parameters(vec![ParameterSymbol::new("msg", None)]), +// )?; +// symbol_table.insert_function_symbol( +// FunctionSymbol::new("std::core::print", "print", true, true, None) +// .with_parameters(vec![ParameterSymbol::new("msg", None)]), +// )?; +// Ok(()) +// }