WIP cargo build no more compile errors.

This commit is contained in:
Jesse Brault 2025-09-23 18:11:53 -05:00
parent 7a7eda97e3
commit c73bb50d6f
4 changed files with 292 additions and 281 deletions

View File

@ -40,7 +40,10 @@ fn deserialize_build(name: &str, props: &Yaml) -> PolymorphicEnumLoopRuleBuild {
fn deserialize_pass_through(name: &str, props: &Yaml) -> PolymorphicEnumLoopRulePassThrough { fn deserialize_pass_through(name: &str, props: &Yaml) -> PolymorphicEnumLoopRulePassThrough {
let kind = props["kind"].as_str().unwrap(); let kind = props["kind"].as_str().unwrap();
let with = make_build_fn_name(props["with"].as_str().unwrap()); let with = make_build_fn_name(
props["with"].as_str()
.unwrap_or(kind)
);
PolymorphicEnumLoopRulePassThrough::new(name, kind, &with) PolymorphicEnumLoopRulePassThrough::new(name, kind, &with)
} }

View File

@ -6,7 +6,7 @@ mod type_gen;
use crate::build_fn::make_build_fn; use crate::build_fn::make_build_fn;
use crate::deserialize::deserialize_yaml_spec; use crate::deserialize::deserialize_yaml_spec;
use crate::pretty_print::make_pretty_print_impl; // use crate::pretty_print::make_pretty_print_impl;
use crate::type_gen::make_type; use crate::type_gen::make_type;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
@ -35,7 +35,10 @@ fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) {
println!("Production Spec - name: {}", production_build_spec.name()); println!("Production Spec - name: {}", production_build_spec.name());
} }
BuildSpec::NodeProduction(node_production_build_spec) => { BuildSpec::NodeProduction(node_production_build_spec) => {
println!("Node Production Spec - name: {}", node_production_build_spec.name()); println!(
"Node Production Spec - name: {}",
node_production_build_spec.name()
);
} }
BuildSpec::PolymorphicType(polymorphic_build_spec) => { BuildSpec::PolymorphicType(polymorphic_build_spec) => {
println!( println!(
@ -80,7 +83,7 @@ fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
build_fn build_fn
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let combined = quote! { let combined = quote! {
//noinspection RsUnusedImport //noinspection RsUnusedImport
use crate::parser::Rule; use crate::parser::Rule;
@ -91,7 +94,7 @@ fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
#(#build_fns)* #(#build_fns)*
}; };
AstGeneratedFile { AstGeneratedFile {
name: String::from("build.rs"), name: String::from("build.rs"),
contents: token_stream_to_string(combined), contents: token_stream_to_string(combined),
@ -114,23 +117,24 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
} }
fn generate_pretty_print_file(build_specs: &[BuildSpec]) -> AstGeneratedFile { fn generate_pretty_print_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
let impls = build_specs // let impls = build_specs
.iter() // .iter()
.map(|build_spec| { // .map(|build_spec| {
let stream = make_pretty_print_impl(build_spec); // let stream = make_pretty_print_impl(build_spec);
debug_built_spec(build_spec, &stream); // debug_built_spec(build_spec, &stream);
stream // stream
}) // })
.collect::<Vec<_>>(); // .collect::<Vec<_>>();
//
let combined = quote! { // let combined = quote! {
use crate::ast::node::*; // use crate::ast::node::*;
#(#impls)* // #(#impls)*
}; // };
AstGeneratedFile { // AstGeneratedFile {
name: String::from("pretty_print.rs"), // name: String::from("pretty_print.rs"),
contents: token_stream_to_string(combined), // contents: token_stream_to_string(combined),
} // }
todo!()
} }
pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> { pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> {
@ -141,6 +145,6 @@ pub fn generate_files(build_specs: &[BuildSpec]) -> Vec<AstGeneratedFile> {
vec![ vec![
generate_build_file(build_specs), generate_build_file(build_specs),
generate_node_file(build_specs), generate_node_file(build_specs),
generate_pretty_print_file(build_specs), // generate_pretty_print_file(build_specs),
] ]
} }

View File

@ -1,256 +1,260 @@
use crate::spec::{ // use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
AlternativeChild, BuildSpec, EnumBuildSpec, EnumRuleChildKind, LeafEnumBuildSpec, // use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind};
LeafStructBuildSpec, LeafStructMemberKind, MemberChildToBuild, PolymorphicBuildBuildSpec, // use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
PolymorphicEnumBuildSpec, PolymorphicTypeBuildSpec, ProductionBuildSpec, StructBuildSpec, // use crate::spec::production_spec::ProductionBuildSpec;
StructChildSpec, VecChildToBuild, // use crate::spec::struct_spec::StructSpec;
}; // use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
use convert_case::{Case, Casing}; // use crate::spec::{
use proc_macro2::TokenStream; // AlternativeChild, BuildSpec, MemberChildToBuild, PolymorphicBuildBuildSpec,
use quote::{format_ident, quote}; // PolymorphicEnumBuildSpec, StructChildSpec, VecChildToBuild,
// };
fn make_production_p2_impl(_spec: &ProductionBuildSpec) -> TokenStream { // use convert_case::{Case, Casing};
quote! {} // use proc_macro2::TokenStream;
} // use quote::{format_ident, quote};
//
fn make_polymorphic_enum_p2_impl(_spec: &PolymorphicEnumBuildSpec) -> TokenStream { // fn make_production_p2_impl(_spec: &ProductionBuildSpec) -> TokenStream {
quote! {} // quote! {}
} // }
//
fn make_polymorphic_build_p2_impl(spec: &PolymorphicBuildBuildSpec) -> TokenStream { // fn make_polymorphic_enum_p2_impl(_spec: &PolymorphicEnumBuildSpec) -> TokenStream {
let (_, build) = spec.primary_alternative(); // quote! {}
let type_ident = format_ident!("{}", spec.name()); // }
let name_str = spec.name(); //
// fn make_polymorphic_build_p2_impl(spec: &PolymorphicBuildBuildSpec) -> TokenStream {
let child_statements = build // let (_, build) = spec.primary_alternative();
.children() // let type_ident = format_ident!("{}", spec.name());
.map(|child| match child { // let name_str = spec.name();
AlternativeChild::Skip => None, //
AlternativeChild::Build(build) => { // let child_statements = build
let child_ident = format_ident!("{}", build.name()); // .children()
Some(quote! { // .map(|child| match child {
self.#child_ident().pretty_print(writer)? // AlternativeChild::Skip => None,
}) // AlternativeChild::Build(build) => {
} // let child_ident = format_ident!("{}", build.name());
}) // Some(quote! {
.filter(Option::is_some) // self.#child_ident().pretty_print(writer)?
.map(Option::unwrap) // })
.collect::<Vec<TokenStream>>(); // }
// })
quote! { // .filter(Option::is_some)
impl PrettyPrint for #type_ident { // .map(Option::unwrap)
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // .collect::<Vec<TokenStream>>();
writer.writeln_indented(#name_str); //
writer.increase_indent(); // quote! {
#(#child_statements;)* // impl PrettyPrint for #type_ident {
writer.decrease_indent(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
Ok(()) // writer.writeln_indented(#name_str);
} // writer.increase_indent();
} // #(#child_statements;)*
} // writer.decrease_indent();
} // Ok(())
// }
fn make_polymorphic_type_p2_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream { // }
let type_ident = format_ident!("{}", spec.name()); // }
let child_matchers = spec // }
.enum_members() //
.map(|member| { // fn make_polymorphic_type_p2_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream {
let enum_member_ident = format_ident!("{}", member.name()); // let type_ident = format_ident!("{}", spec.name());
let inner_name = format_ident!("{}", member.inner_kind().to_case(Case::Snake)); // let child_matchers = spec
quote! { // .variants()
#type_ident::#enum_member_ident(#inner_name) => #inner_name.pretty_print(writer) // .map(|member| {
} // let enum_member_ident = format_ident!("{}", member.name());
}) // let inner_name = format_ident!("{}", member.inner_kind().to_case(Case::Snake));
.collect::<Vec<_>>(); // quote! {
// #type_ident::#enum_member_ident(#inner_name) => #inner_name.pretty_print(writer)
quote! { // }
impl PrettyPrint for #type_ident { // })
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // .collect::<Vec<_>>();
match self { //
#(#child_matchers,)* // quote! {
} // impl PrettyPrint for #type_ident {
} // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
} // match self {
} // #(#child_matchers,)*
} // }
// }
fn make_leaf_enum_p2_impl(spec: &LeafEnumBuildSpec) -> TokenStream { // }
let type_ident = format_ident!("{}", spec.build()); // }
let child_matchers = spec // }
.rules() //
.map(|rule| { // fn make_leaf_enum_p2_impl(spec: &LeafEnumBuildSpec) -> TokenStream {
let enum_variant_ident = format_ident!("{}", rule.rule()); // let type_ident = format_ident!("{}", spec.build());
let name_str = rule.rule(); // let child_matchers = spec
quote! { // .rules()
#type_ident::#enum_variant_ident => writer.writeln_indented(#name_str) // .map(|rule| {
} // let enum_variant_ident = format_ident!("{}", rule.rule());
}) // let name_str = rule.rule();
.collect::<Vec<_>>(); // quote! {
// #type_ident::#enum_variant_ident => writer.writeln_indented(#name_str)
quote! { // }
impl PrettyPrint for #type_ident { // })
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // .collect::<Vec<_>>();
match self { //
#(#child_matchers,)* // quote! {
} // impl PrettyPrint for #type_ident {
} // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
} // match self {
} // #(#child_matchers,)*
} // }
// }
fn make_enum_p2_impl(spec: &EnumBuildSpec) -> TokenStream { // }
let type_ident = format_ident!("{}", spec.build()); // }
let type_str = spec.build(); // }
//
let child_matchers = spec // fn make_enum_p2_impl(spec: &TreeEnumBuildSpec) -> TokenStream {
.rules() // let type_ident = format_ident!("{}", spec.build());
.map(|rule| { // let type_str = spec.build();
let enum_variant_ident = format_ident!("{}", rule.rule()); //
if let Some(child) = rule.child() { // let child_matchers = spec
match child.kind() { // .rules()
EnumRuleChildKind::Node(node_child) => { // .map(|rule| {
let child_name_ident = // let enum_variant_ident = format_ident!("{}", rule.rule());
format_ident!("{}", node_child.build().to_case(Case::Snake)); // if let Some(child) = rule.child() {
Some(quote! { // match child.kind() {
#type_ident::#enum_variant_ident(#child_name_ident) => { // EnumRuleChildKind::Node(node_child) => {
#child_name_ident.pretty_print(writer)?; // let child_name_ident =
} // format_ident!("{}", node_child.build().to_case(Case::Snake));
}) // Some(quote! {
} // #type_ident::#enum_variant_ident(#child_name_ident) => {
_ => None, // #child_name_ident.pretty_print(writer)?;
} // }
} else { // })
let variant_str = rule.rule(); // }
Some(quote! { // _ => None,
#type_ident::#enum_variant_ident => writer.writeln_indented(#variant_str)? // }
}) // } else {
} // let variant_str = rule.rule();
}) // Some(quote! {
.filter(Option::is_some) // #type_ident::#enum_variant_ident => writer.writeln_indented(#variant_str)?
.map(Option::unwrap) // })
.collect::<Vec<_>>(); // }
// })
quote! { // .filter(Option::is_some)
impl PrettyPrint for #type_ident { // .map(Option::unwrap)
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // .collect::<Vec<_>>();
writer.writeln_indented(#type_str)?; //
writer.increase_indent(); // quote! {
match self { // impl PrettyPrint for #type_ident {
#(#child_matchers,)* // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
_ => {} // writer.writeln_indented(#type_str)?;
} // writer.increase_indent();
writer.decrease_indent(); // match self {
Ok(()) // #(#child_matchers,)*
} // _ => {}
} // }
} // writer.decrease_indent();
} // Ok(())
// }
fn make_leaf_struct_p2_impl(leaf_struct_build_spec: &LeafStructBuildSpec) -> TokenStream { // }
let type_ident = format_ident!("{}", leaf_struct_build_spec.build()); // }
let member_formatters = leaf_struct_build_spec // }
.members() //
.map(|member| match member.kind() { // fn make_leaf_struct_p2_impl(leaf_struct_build_spec: &LeafStructBuildSpec) -> TokenStream {
LeafStructMemberKind::String => Some("{}"), // let type_ident = format_ident!("{}", leaf_struct_build_spec.build());
}) // let member_formatters = leaf_struct_build_spec
.filter(Option::is_some) // .members()
.map(Option::unwrap) // .map(|member| match member.kind() {
.collect::<Vec<_>>() // LeafStructMemberKind::String => Some("{}"),
.join(", "); // })
// .filter(Option::is_some)
let format_string = format!("{}({})", leaf_struct_build_spec.build(), member_formatters); // .map(Option::unwrap)
// .collect::<Vec<_>>()
let members = leaf_struct_build_spec // .join(", ");
.members() //
.map(|member| { // let format_string = format!("{}({})", leaf_struct_build_spec.build(), member_formatters);
let member_ident = format_ident!("{}", member.name()); //
quote! { // let members = leaf_struct_build_spec
self.#member_ident() // .members()
} // .map(|member| {
}) // let member_ident = format_ident!("{}", member.name());
.collect::<Vec<_>>(); // quote! {
// self.#member_ident()
quote! { // }
impl PrettyPrint for #type_ident { // })
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // .collect::<Vec<_>>();
writer.writeln_indented(&format!(#format_string, #(#members),*)) //
} // quote! {
} // impl PrettyPrint for #type_ident {
} // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
} // writer.writeln_indented(&format!(#format_string, #(#members),*))
// }
fn make_struct_p2_impl(struct_build_spec: &StructBuildSpec) -> TokenStream { // }
let child_print_statements = struct_build_spec // }
.children() // }
.map(|child| match child { //
StructChildSpec::SkipChild(_) => None, // fn make_struct_p2_impl(struct_build_spec: &StructSpec) -> TokenStream {
StructChildSpec::VecChild(vec_child) => match vec_child.build() { // let child_print_statements = struct_build_spec
VecChildToBuild::Node(_) => { // .children()
let child_ident = format_ident!("{}", vec_child.name()); // .map(|child| match child {
Some(quote! { // StructChildSpec::SkipChild(_) => None,
for child in self.#child_ident() { // StructChildSpec::VecChild(vec_child) => match vec_child.build() {
child.pretty_print(writer)?; // VecChildToBuild::Node(_) => {
} // let child_ident = format_ident!("{}", vec_child.name());
}) // Some(quote! {
} // for child in self.#child_ident() {
VecChildToBuild::String => None, // child.pretty_print(writer)?;
}, // }
StructChildSpec::MemberChild(member_child) => match member_child.build() { // })
MemberChildToBuild::Node(node_member_child) => { // }
let child_ident = format_ident!("{}", member_child.name()); // VecChildToBuild::String => None,
if node_member_child.optional() { // },
Some(quote! { // StructChildSpec::MemberChild(member_child) => match member_child.build() {
if let Some(child) = self.#child_ident() { // MemberChildToBuild::Node(node_member_child) => {
child.pretty_print(writer)?; // let child_ident = format_ident!("{}", member_child.name());
} // if node_member_child.optional() {
}) // Some(quote! {
} else { // if let Some(child) = self.#child_ident() {
Some(quote! { // child.pretty_print(writer)?;
self.#child_ident().pretty_print(writer)?; // }
}) // })
} // } else {
} // Some(quote! {
MemberChildToBuild::Boolean(boolean_member_child) => { // self.#child_ident().pretty_print(writer)?;
let format_string = format!("{}({})", boolean_member_child.name(), "{}"); // })
let child_ident = format_ident!("{}", boolean_member_child.name()); // }
Some(quote! { // }
writer.writeln_indented(&format!(#format_string, self.#child_ident()))?; // MemberChildToBuild::Boolean(boolean_member_child) => {
}) // let format_string = format!("{}({})", boolean_member_child.name(), "{}");
} // let child_ident = format_ident!("{}", boolean_member_child.name());
}, // Some(quote! {
}) // writer.writeln_indented(&format!(#format_string, self.#child_ident()))?;
.filter(Option::is_some) // })
.map(Option::unwrap) // }
.collect::<Vec<_>>(); // },
// })
let type_ident = format_ident!("{}", struct_build_spec.build()); // .filter(Option::is_some)
let type_string = struct_build_spec.build(); // .map(Option::unwrap)
// .collect::<Vec<_>>();
quote! { //
impl PrettyPrint for #type_ident { // let type_ident = format_ident!("{}", struct_build_spec.build());
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // let type_string = struct_build_spec.build();
writer.writeln_indented(#type_string)?; //
writer.increase_indent(); // quote! {
#(#child_print_statements)* // impl PrettyPrint for #type_ident {
writer.decrease_indent(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
Ok(()) // writer.writeln_indented(#type_string)?;
} // writer.increase_indent();
} // #(#child_print_statements)*
} // writer.decrease_indent();
} // Ok(())
// }
pub fn make_pretty_print_impl(build_spec: &BuildSpec) -> TokenStream { // }
match build_spec { // }
BuildSpec::Struct(struct_spec) => make_struct_p2_impl(struct_spec), // }
BuildSpec::LeafStruct(leaf_struct) => make_leaf_struct_p2_impl(leaf_struct), //
BuildSpec::Enum(enum_spec) => make_enum_p2_impl(enum_spec), // pub fn make_pretty_print_impl(build_spec: &BuildSpec) -> TokenStream {
BuildSpec::LeafEnum(leaf_enum) => make_leaf_enum_p2_impl(leaf_enum), // match build_spec {
BuildSpec::Polymorphic(polymorphic) => make_polymorphic_type_p2_impl(polymorphic), // BuildSpec::Struct(struct_spec) => make_struct_p2_impl(struct_spec),
BuildSpec::PolymorphicBuild(polymorphic_build) => { // BuildSpec::LeafStruct(leaf_struct) => make_leaf_struct_p2_impl(leaf_struct),
make_polymorphic_build_p2_impl(polymorphic_build) // BuildSpec::Enum(enum_spec) => make_enum_p2_impl(enum_spec),
} // BuildSpec::LeafEnum(leaf_enum) => make_leaf_enum_p2_impl(leaf_enum),
BuildSpec::PolymorphicEnum(polymorphic_enum) => { // BuildSpec::PolymorphicType(polymorphic) => make_polymorphic_type_p2_impl(polymorphic),
make_polymorphic_enum_p2_impl(polymorphic_enum) // BuildSpec::PolymorphicBuild(polymorphic_build) => {
} // make_polymorphic_build_p2_impl(polymorphic_build)
BuildSpec::Production(production) => make_production_p2_impl(production), // }
} // BuildSpec::PolymorphicEnum(polymorphic_enum) => {
} // make_polymorphic_enum_p2_impl(polymorphic_enum)
// }
// BuildSpec::Production(production) => make_production_p2_impl(production),
// }
// }

View File

@ -1,4 +1,4 @@
use ast_generator::{deserialize, generate_files}; use ast_generator::{get_build_specs, generate_files};
use cst_test_generator::generate_test_files; use cst_test_generator::generate_test_files;
use std::env; use std::env;
use std::fs; use std::fs;
@ -19,7 +19,7 @@ fn generate_ast_files(out_dir: &Path) -> io::Result<()> {
fs::create_dir_all(&gen_ast_dir)?; fs::create_dir_all(&gen_ast_dir)?;
let ast_yaml = include_str!("src/parser/ast.yaml"); let ast_yaml = include_str!("src/parser/ast.yaml");
let build_specs = deserialize::deserialize_yaml_spec(ast_yaml); let build_specs = get_build_specs(ast_yaml);
let generated_files = generate_files(&build_specs); let generated_files = generate_files(&build_specs);
for generated_file in &generated_files { for generated_file in &generated_files {
let path = gen_ast_dir.join(&generated_file.name); let path = gen_ast_dir.join(&generated_file.name);