Compare commits

..

No commits in common. "41673a68f89e34f5a17a0ac310e407a157f7b672" and "0d2db659cac210e4d1610263dffd58a7fd453e1a" have entirely different histories.

12 changed files with 354 additions and 491 deletions

View File

@ -1,10 +1,10 @@
use crate::deserialize::util::{make_build_fn_name, make_build_pair}; use crate::deserialize::util::make_build_pair;
use crate::spec::node_production_spec::NodeProductionBuildSpec; use crate::spec::node_production_spec::NodeProductionBuildSpec;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
pub fn make_node_production_build_fn(spec: &NodeProductionBuildSpec) -> TokenStream { pub fn make_node_production_build_fn(spec: &NodeProductionBuildSpec) -> TokenStream {
let build_fn_ident = format_ident!("{}", make_build_fn_name(spec.name())); let build_fn_ident = format_ident!("{}", spec.with());
let pair_ident = format_ident!("{}", make_build_pair(spec.name())); let pair_ident = format_ident!("{}", make_build_pair(spec.name()));
let return_type_ident = format_ident!("{}", spec.kind()); let return_type_ident = format_ident!("{}", spec.kind());
let inner_build_fn_ident = format_ident!("{}", spec.with()); let inner_build_fn_ident = format_ident!("{}", spec.with());

View File

@ -1,8 +1,8 @@
use crate::deserialize::util::{make_build_fn_name, make_build_pair}; use crate::deserialize::util::{make_build_fn_name, make_build_pair};
use crate::spec::polymorphic_enum_loop_spec::{ use crate::spec::polymorphic_enum_loop_spec::{
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule,
PolymorphicEnumLoopRuleBuildChild, PolymorphicEnumLoopRuleChildOnEach, PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopRuleBuildChild,
PolymorphicEnumLoopRulePassThrough, PolymorphicEnumLoopRuleChildOnEach, PolymorphicEnumLoopRulePassThrough,
}; };
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
@ -20,7 +20,7 @@ fn make_pass_through(pass_through: &PolymorphicEnumLoopRulePassThrough) -> Token
fn make_on_each_child_build(child: &PolymorphicEnumLoopRuleChildOnEach) -> TokenStream { fn make_on_each_child_build(child: &PolymorphicEnumLoopRuleChildOnEach) -> TokenStream {
let child_build_fn_ident = format_ident!("{}", make_build_fn_name(child.rule())); let child_build_fn_ident = format_ident!("{}", make_build_fn_name(child.rule()));
quote! { quote! {
Box::new(#child_build_fn_ident(inner_pair)) #child_build_fn_ident(inner_pair)
} }
} }
@ -29,7 +29,7 @@ fn make_build(
build: &PolymorphicEnumLoopRuleBuild, build: &PolymorphicEnumLoopRuleBuild,
) -> TokenStream { ) -> TokenStream {
let rule_ident = format_ident!("{}", build.name()); let rule_ident = format_ident!("{}", build.name());
let variant_type_ident = format_ident!("{}", spec.name()); let variant_type_ident = format_ident!("{}", build.name());
let return_type_ident = format_ident!("{}", spec.kind()); let return_type_ident = format_ident!("{}", spec.kind());
let variant_ident = format_ident!("{}", build.variant()); let variant_ident = format_ident!("{}", build.variant());
@ -39,9 +39,11 @@ fn make_build(
PolymorphicEnumLoopRuleBuildChild::OnEach(_) => true, PolymorphicEnumLoopRuleBuildChild::OnEach(_) => true,
_ => false, _ => false,
}) })
.map(|child| match child { .map(|child| {
match child {
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => on_each, PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => on_each,
_ => unreachable!(), _ => unreachable!(),
}
}) })
.unwrap(); .unwrap();
@ -51,7 +53,7 @@ fn make_build(
.children() .children()
.map(|child| match child { .map(|child| match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(_) => { PolymorphicEnumLoopRuleBuildChild::UseCurrent(_) => {
quote! { Box::new(result.unwrap()) } quote! { result.unwrap() }
} }
PolymorphicEnumLoopRuleBuildChild::OnEach(_) => quote! { on_each_child }, PolymorphicEnumLoopRuleBuildChild::OnEach(_) => quote! { on_each_child },
}) })
@ -66,10 +68,7 @@ fn make_build(
} }
} }
fn make_match_arm( fn make_match_arm(spec: &PolymorphicEnumLoopBuildSpec, rule: &PolymorphicEnumLoopRule) -> TokenStream {
spec: &PolymorphicEnumLoopBuildSpec,
rule: &PolymorphicEnumLoopRule,
) -> TokenStream {
match rule { match rule {
PolymorphicEnumLoopRule::PassThrough(pass_through) => make_pass_through(pass_through), PolymorphicEnumLoopRule::PassThrough(pass_through) => make_pass_through(pass_through),
PolymorphicEnumLoopRule::Build(build) => make_build(spec, build), PolymorphicEnumLoopRule::Build(build) => make_build(spec, build),
@ -81,12 +80,6 @@ pub fn make_polymorphic_enum_loop_build_fn(spec: &PolymorphicEnumLoopBuildSpec)
let pair_ident = format_ident!("{}", make_build_pair(spec.name())); let pair_ident = format_ident!("{}", make_build_pair(spec.name()));
let return_type_ident = format_ident!("{}", spec.kind()); let return_type_ident = format_ident!("{}", spec.kind());
let iter_expr = if spec.reverse() {
quote! { #pair_ident.into_inner().rev() }
} else {
quote! { #pair_ident.into_inner() }
};
let match_arms = spec let match_arms = spec
.rules() .rules()
.map(|rule| make_match_arm(spec, rule)) .map(|rule| make_match_arm(spec, rule))
@ -95,10 +88,10 @@ pub fn make_polymorphic_enum_loop_build_fn(spec: &PolymorphicEnumLoopBuildSpec)
quote! { quote! {
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident { fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
let mut result: Option<#return_type_ident> = None; let mut result: Option<#return_type_ident> = None;
for inner_pair in #iter_expr { for inner_pair in #pair_ident.into_inner() {
match inner_pair.as_rule() { match inner_pair.as_rule() {
#(#match_arms,)* #(#match_arms,)*
_ => unreachable!("Unexpected parse rule: {:?} (inner pair: {:#?}", inner_pair.as_rule(), inner_pair), _ => unreachable!()
} }
} }
result.unwrap() result.unwrap()

View File

@ -1,4 +1,4 @@
use crate::deserialize::util::{get_as_bool, make_build_fn_name, unwrap_single_member_hash}; use crate::deserialize::util::{make_build_fn_name, unwrap_single_member_hash};
use crate::spec::polymorphic_enum_loop_spec::{ use crate::spec::polymorphic_enum_loop_spec::{
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopChildUseCurrent, PolymorphicEnumLoopRule, PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopChildUseCurrent, PolymorphicEnumLoopRule,
PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopRuleBuildChild, PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopRuleBuildChild,
@ -62,8 +62,6 @@ fn deserialize_rule(rule_name: &str, props: &Yaml) -> PolymorphicEnumLoopRule {
pub fn deserialize_polymorphic_enum_loop(name: &str, props: &Yaml) -> PolymorphicEnumLoopBuildSpec { pub fn deserialize_polymorphic_enum_loop(name: &str, props: &Yaml) -> PolymorphicEnumLoopBuildSpec {
let kind = props["kind"].as_str().unwrap(); let kind = props["kind"].as_str().unwrap();
let reverse = get_as_bool(&props["reverse"]);
let rules = props["rules"] let rules = props["rules"]
.as_vec() .as_vec()
.unwrap() .unwrap()
@ -75,5 +73,5 @@ pub fn deserialize_polymorphic_enum_loop(name: &str, props: &Yaml) -> Polymorphi
.map(Box::new) .map(Box::new)
.collect(); .collect();
PolymorphicEnumLoopBuildSpec::new(name, kind, reverse, rules) PolymorphicEnumLoopBuildSpec::new(name, kind, rules)
} }

View File

@ -38,7 +38,7 @@ fn deserialize_member_build(child_name: &str, rule: &str, props: &Yaml) -> Membe
let kind = node_props["kind"].as_str().unwrap_or(rule); let kind = node_props["kind"].as_str().unwrap_or(rule);
let with = node_props["with"] let with = node_props["with"]
.as_str() .as_str()
.map(|with| make_build_fn_name(with)) .map(ToString::to_string)
.unwrap_or_else(|| make_build_fn_name(kind)); .unwrap_or_else(|| make_build_fn_name(kind));
let or_else = if get_as_bool(&node_props["or_else_default"]) { let or_else = if get_as_bool(&node_props["or_else_default"]) {

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;
@ -117,27 +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 maybe_stream = make_pretty_print_impl(build_spec); // let stream = make_pretty_print_impl(build_spec);
if let Some(stream) = &maybe_stream { // debug_built_spec(build_spec, &stream);
debug_built_spec(build_spec, &stream); // stream
} // })
maybe_stream // .collect::<Vec<_>>();
}) //
.filter(Option::is_some) // let combined = quote! {
.map(Option::unwrap) // use crate::ast::node::*;
.collect::<Vec<_>>(); // #(#impls)*
// };
let combined = quote! { // AstGeneratedFile {
use crate::ast::node::*; // name: String::from("pretty_print.rs"),
#(#impls)* // contents: token_stream_to_string(combined),
}; // }
AstGeneratedFile { todo!()
name: String::from("pretty_print.rs"),
contents: token_stream_to_string(combined),
}
} }
pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> { pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> {
@ -148,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,265 +1,260 @@
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec; // use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind}; // use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind};
use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec; // use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
use crate::spec::struct_spec::{MemberChildBuild, StructChild, StructSpec, VecChildBuild}; // use crate::spec::production_spec::ProductionBuildSpec;
use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec}; // use crate::spec::struct_spec::StructSpec;
use crate::spec::BuildSpec; // 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,
use crate::spec::polymorphic_enum_loop_spec::{PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild}; // };
// use convert_case::{Case, Casing};
fn make_polymorphic_enum_loop_p2_impl(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream { // use proc_macro2::TokenStream;
let type_ident = format_ident!("{}", spec.name()); // use quote::{format_ident, quote};
let type_string = spec.name(); //
// fn make_production_p2_impl(_spec: &ProductionBuildSpec) -> TokenStream {
let build = spec.rules() // quote! {}
.find(|rule| { // }
match rule { //
PolymorphicEnumLoopRule::Build(_) => true, // fn make_polymorphic_enum_p2_impl(_spec: &PolymorphicEnumBuildSpec) -> TokenStream {
_ => false // quote! {}
} // }
}) //
.map(|rule| { // fn make_polymorphic_build_p2_impl(spec: &PolymorphicBuildBuildSpec) -> TokenStream {
match rule { // let (_, build) = spec.primary_alternative();
PolymorphicEnumLoopRule::Build(build) => build, // let type_ident = format_ident!("{}", spec.name());
_ => unreachable!() // let name_str = spec.name();
} //
}) // let child_statements = build
.unwrap(); // .children()
// .map(|child| match child {
let child_print_statements = build.children() // AlternativeChild::Skip => None,
.map(|child| { // AlternativeChild::Build(build) => {
let child_ident = match child { // let child_ident = format_ident!("{}", build.name());
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => { // Some(quote! {
format_ident!("{}", use_current.name()) // self.#child_ident().pretty_print(writer)?
} // })
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => { // }
format_ident!("{}", on_each.name()) // })
} // .filter(Option::is_some)
}; // .map(Option::unwrap)
quote! { // .collect::<Vec<TokenStream>>();
self.#child_ident().pretty_print(writer)?; //
} // quote! {
}) // impl PrettyPrint for #type_ident {
.collect::<Vec<_>>(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
// writer.writeln_indented(#name_str);
quote! { // writer.increase_indent();
impl PrettyPrint for #type_ident { // #(#child_statements;)*
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // writer.decrease_indent();
writer.writeln_indented(#type_string)?; // Ok(())
writer.increase_indent(); // }
#(#child_print_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
// .variants()
fn make_polymorphic_type_p2_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream { // .map(|member| {
let type_ident = format_ident!("{}", spec.name()); // let enum_member_ident = format_ident!("{}", member.name());
let child_matchers = spec // let inner_name = format_ident!("{}", member.inner_kind().to_case(Case::Snake));
.variants() // quote! {
.map(|member| { // #type_ident::#enum_member_ident(#inner_name) => #inner_name.pretty_print(writer)
let enum_member_ident = format_ident!("{}", member.name()); // }
let inner_name = format_ident!("{}", member.inner_kind().to_case(Case::Snake)); // })
quote! { // .collect::<Vec<_>>();
#type_ident::#enum_member_ident(#inner_name) => #inner_name.pretty_print(writer) //
} // quote! {
}) // impl PrettyPrint for #type_ident {
.collect::<Vec<_>>(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
// match self {
quote! { // #(#child_matchers,)*
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()
fn make_leaf_enum_p2_impl(spec: &LeafEnumBuildSpec) -> TokenStream { // .map(|rule| {
let type_ident = format_ident!("{}", spec.build()); // let enum_variant_ident = format_ident!("{}", rule.rule());
let child_matchers = spec // let name_str = rule.rule();
.rules() // quote! {
.map(|rule| { // #type_ident::#enum_variant_ident => writer.writeln_indented(#name_str)
let enum_variant_ident = format_ident!("{}", rule); // }
let name_str = rule; // })
quote! { // .collect::<Vec<_>>();
#type_ident::#enum_variant_ident => writer.writeln_indented(#name_str) //
} // quote! {
}) // impl PrettyPrint for #type_ident {
.collect::<Vec<_>>(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
// match self {
quote! { // #(#child_matchers,)*
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: &TreeEnumBuildSpec) -> TokenStream {
} // let type_ident = format_ident!("{}", spec.build());
} // let type_str = spec.build();
//
fn make_tree_enum_p2_impl(spec: &TreeEnumBuildSpec) -> TokenStream { // let child_matchers = spec
let type_ident = format_ident!("{}", spec.build()); // .rules()
let type_str = spec.build(); // .map(|rule| {
// let enum_variant_ident = format_ident!("{}", rule.rule());
let child_matchers = spec // if let Some(child) = rule.child() {
.rules() // match child.kind() {
.map(|rule| { // EnumRuleChildKind::Node(node_child) => {
let enum_variant_ident = format_ident!("{}", rule.rule()); // let child_name_ident =
if let Some(child) = rule.child() { // format_ident!("{}", node_child.build().to_case(Case::Snake));
match child.kind() { // Some(quote! {
EnumRuleChildKind::Node(node_child) => { // #type_ident::#enum_variant_ident(#child_name_ident) => {
let child_name_ident = // #child_name_ident.pretty_print(writer)?;
format_ident!("{}", node_child.node_kind().to_case(Case::Snake)); // }
Some(quote! { // })
#type_ident::#enum_variant_ident(#child_name_ident) => { // }
#child_name_ident.pretty_print(writer)?; // _ => None,
} // }
}) // } else {
} // let variant_str = rule.rule();
_ => None, // Some(quote! {
} // #type_ident::#enum_variant_ident => writer.writeln_indented(#variant_str)?
} else { // })
let variant_str = rule.rule(); // }
Some(quote! { // })
#type_ident::#enum_variant_ident => writer.writeln_indented(#variant_str)? // .filter(Option::is_some)
}) // .map(Option::unwrap)
} // .collect::<Vec<_>>();
}) //
.filter(Option::is_some) // quote! {
.map(Option::unwrap) // impl PrettyPrint for #type_ident {
.collect::<Vec<_>>(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
// writer.writeln_indented(#type_str)?;
quote! { // writer.increase_indent();
impl PrettyPrint for #type_ident { // match self {
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // #(#child_matchers,)*
writer.writeln_indented(#type_str)?; // _ => {}
writer.increase_indent(); // }
match self { // writer.decrease_indent();
#(#child_matchers,)* // Ok(())
_ => {} // }
} // }
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()
fn make_leaf_struct_p2_impl(leaf_struct_build_spec: &LeafStructBuildSpec) -> TokenStream { // .map(|member| match member.kind() {
let type_ident = format_ident!("{}", leaf_struct_build_spec.build()); // LeafStructMemberKind::String => Some("{}"),
let member_formatters = leaf_struct_build_spec // })
.members() // .filter(Option::is_some)
.map(|member| match member.kind() { // .map(Option::unwrap)
LeafStructMemberKind::String => Some("{}"), // .collect::<Vec<_>>()
}) // .join(", ");
.filter(Option::is_some) //
.map(Option::unwrap) // let format_string = format!("{}({})", leaf_struct_build_spec.build(), member_formatters);
.collect::<Vec<_>>() //
.join(", "); // let members = leaf_struct_build_spec
// .members()
let format_string = format!("{}({})", leaf_struct_build_spec.build(), member_formatters); // .map(|member| {
// let member_ident = format_ident!("{}", member.name());
let members = leaf_struct_build_spec // quote! {
.members() // self.#member_ident()
.map(|member| { // }
let member_ident = format_ident!("{}", member.name()); // })
quote! { // .collect::<Vec<_>>();
self.#member_ident() //
} // quote! {
}) // impl PrettyPrint for #type_ident {
.collect::<Vec<_>>(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
// 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: &StructSpec) -> TokenStream {
} // let child_print_statements = struct_build_spec
} // .children()
// .map(|child| match child {
fn make_struct_p2_impl(struct_build_spec: &StructSpec) -> TokenStream { // StructChildSpec::SkipChild(_) => None,
let child_print_statements = struct_build_spec // StructChildSpec::VecChild(vec_child) => match vec_child.build() {
.children() // VecChildToBuild::Node(_) => {
.map(|child| match child { // let child_ident = format_ident!("{}", vec_child.name());
StructChild::SkipChild(_) => None, // Some(quote! {
StructChild::VecChild(vec_child) => match vec_child.build() { // for child in self.#child_ident() {
VecChildBuild::Node(_) => { // child.pretty_print(writer)?;
let child_ident = format_ident!("{}", vec_child.name()); // }
Some(quote! { // })
for child in self.#child_ident() { // }
child.pretty_print(writer)?; // VecChildToBuild::String => None,
} // },
}) // StructChildSpec::MemberChild(member_child) => match member_child.build() {
} // MemberChildToBuild::Node(node_member_child) => {
VecChildBuild::String(_) => None, // let child_ident = format_ident!("{}", member_child.name());
}, // if node_member_child.optional() {
StructChild::MemberChild(member_child) => match member_child.build() { // Some(quote! {
MemberChildBuild::Node(_) => { // if let Some(child) = self.#child_ident() {
let child_ident = format_ident!("{}", member_child.name()); // child.pretty_print(writer)?;
if member_child.optional() { // }
Some(quote! { // })
if let Some(child) = self.#child_ident() { // } else {
child.pretty_print(writer)?; // Some(quote! {
} // self.#child_ident().pretty_print(writer)?;
}) // })
} else { // }
Some(quote! { // }
self.#child_ident().pretty_print(writer)?; // MemberChildToBuild::Boolean(boolean_member_child) => {
}) // let format_string = format!("{}({})", boolean_member_child.name(), "{}");
} // let child_ident = format_ident!("{}", boolean_member_child.name());
} // Some(quote! {
MemberChildBuild::Boolean(_) => { // writer.writeln_indented(&format!(#format_string, self.#child_ident()))?;
let format_string = format!("{}({})", member_child.name(), "{}"); // })
let child_ident = format_ident!("{}", member_child.name()); // }
Some(quote! { // },
writer.writeln_indented(&format!(#format_string, self.#child_ident()))?; // })
}) // .filter(Option::is_some)
} // .map(Option::unwrap)
}, // .collect::<Vec<_>>();
}) //
.filter(Option::is_some) // let type_ident = format_ident!("{}", struct_build_spec.build());
.map(Option::unwrap) // let type_string = struct_build_spec.build();
.collect::<Vec<_>>(); //
// quote! {
let type_ident = format_ident!("{}", struct_build_spec.build()); // impl PrettyPrint for #type_ident {
let type_string = struct_build_spec.build(); // fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
// writer.writeln_indented(#type_string)?;
quote! { // writer.increase_indent();
impl PrettyPrint for #type_ident { // #(#child_print_statements)*
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { // writer.decrease_indent();
writer.writeln_indented(#type_string)?; // Ok(())
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),
pub fn make_pretty_print_impl(build_spec: &BuildSpec) -> Option<TokenStream> { // BuildSpec::Enum(enum_spec) => make_enum_p2_impl(enum_spec),
match build_spec { // BuildSpec::LeafEnum(leaf_enum) => make_leaf_enum_p2_impl(leaf_enum),
BuildSpec::Struct(struct_spec) => Some(make_struct_p2_impl(struct_spec)), // BuildSpec::PolymorphicType(polymorphic) => make_polymorphic_type_p2_impl(polymorphic),
BuildSpec::LeafStruct(leaf_struct) => Some(make_leaf_struct_p2_impl(leaf_struct)), // BuildSpec::PolymorphicBuild(polymorphic_build) => {
BuildSpec::Enum(enum_spec) => Some(make_tree_enum_p2_impl(enum_spec)), // make_polymorphic_build_p2_impl(polymorphic_build)
BuildSpec::LeafEnum(leaf_enum) => Some(make_leaf_enum_p2_impl(leaf_enum)), // }
BuildSpec::Production(_) => None, // BuildSpec::PolymorphicEnum(polymorphic_enum) => {
BuildSpec::NodeProduction(_) => None, // make_polymorphic_enum_p2_impl(polymorphic_enum)
BuildSpec::PolymorphicType(polymorphic_type) => { // }
Some(make_polymorphic_type_p2_impl(polymorphic_type)) // BuildSpec::Production(production) => make_production_p2_impl(production),
} // }
BuildSpec::PolymorphicPassThrough(_) => None, // }
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => {
Some(make_polymorphic_enum_loop_p2_impl(polymorphic_enum_loop))
},
}
}

View File

@ -1,16 +1,14 @@
pub struct PolymorphicEnumLoopBuildSpec { pub struct PolymorphicEnumLoopBuildSpec {
name: String, name: String,
kind: String, kind: String,
reverse: bool,
rules: Vec<Box<PolymorphicEnumLoopRule>>, rules: Vec<Box<PolymorphicEnumLoopRule>>,
} }
impl PolymorphicEnumLoopBuildSpec { impl PolymorphicEnumLoopBuildSpec {
pub fn new(name: &str, kind: &str, reverse: bool, rules: Vec<Box<PolymorphicEnumLoopRule>>) -> Self { pub fn new(name: &str, kind: &str, rules: Vec<Box<PolymorphicEnumLoopRule>>) -> Self {
Self { Self {
name: name.to_string(), name: name.to_string(),
kind: kind.to_string(), kind: kind.to_string(),
reverse,
rules, rules,
} }
} }
@ -23,10 +21,6 @@ impl PolymorphicEnumLoopBuildSpec {
&self.kind &self.kind
} }
pub fn reverse(&self) -> bool {
self.reverse
}
pub fn rules(&self) -> impl Iterator<Item = &PolymorphicEnumLoopRule> { pub fn rules(&self) -> impl Iterator<Item = &PolymorphicEnumLoopRule> {
self.rules.iter().map(Box::as_ref) self.rules.iter().map(Box::as_ref)
} }

View File

@ -1,7 +1,6 @@
mod enum_type; mod enum_type;
mod leaf_enum_type; mod leaf_enum_type;
mod leaf_struct_type; mod leaf_struct_type;
mod polymorphic_enum_loop_type;
mod polymorphic_type_type; mod polymorphic_type_type;
mod struct_type; mod struct_type;
@ -12,7 +11,6 @@ use crate::type_gen::leaf_struct_type::make_leaf_struct_type;
use crate::type_gen::polymorphic_type_type::make_polymorphic_type_type; use crate::type_gen::polymorphic_type_type::make_polymorphic_type_type;
use crate::type_gen::struct_type::make_struct_type; use crate::type_gen::struct_type::make_struct_type;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use crate::type_gen::polymorphic_enum_loop_type::make_polymorphic_enum_loop_type;
pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> { pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
match build_spec { match build_spec {
@ -29,9 +27,7 @@ pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
BuildSpec::PolymorphicType(polymorphic_build_spec) => { BuildSpec::PolymorphicType(polymorphic_build_spec) => {
Some(make_polymorphic_type_type(polymorphic_build_spec)) Some(make_polymorphic_type_type(polymorphic_build_spec))
} }
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop_spec) => { BuildSpec::PolymorphicEnumLoop(_) => None,
Some(make_polymorphic_enum_loop_type(polymorphic_enum_loop_spec))
},
BuildSpec::PolymorphicPassThrough(_) => None, BuildSpec::PolymorphicPassThrough(_) => None,
} }
} }

View File

@ -1,96 +0,0 @@
use crate::spec::polymorphic_enum_loop_spec::{PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_polymorphic_enum_loop_type(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.name());
let build = spec.rules()
.find(|rule| {
match rule {
PolymorphicEnumLoopRule::Build(_) => true,
_ => false
}
})
.map(|rule| {
match rule {
PolymorphicEnumLoopRule::Build(build) => build,
_ => unreachable!()
}
})
.unwrap();
let annotated_members = build.children()
.map(|child| {
match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
let child_ident = format_ident!("{}", use_current.name());
let child_type_ident = format_ident!("{}", use_current.kind());
quote! {
#child_ident: Box<#child_type_ident>
}
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
let child_ident = format_ident!("{}", on_each.name());
let child_type_ident = format_ident!("{}", on_each.rule());
quote! {
#child_ident: Box<#child_type_ident>
}
}
}
})
.collect::<Vec<_>>();
let member_names = build.children()
.map(|child| {
match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
format_ident!("{}", use_current.name())
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
format_ident!("{}", on_each.name())
}
}
})
.collect::<Vec<_>>();
let accessors = build.children()
.map(|child| {
let (child_ident, child_type_ident) = match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
(format_ident!("{}", use_current.name()), format_ident!("{}", use_current.kind()))
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
(format_ident!("{}", on_each.name()), format_ident!("{}", on_each.rule()))
}
};
let child_mut_ident = format_ident!("{}_mut", child_ident);
quote! {
pub fn #child_ident(&self) -> &#child_type_ident {
self.#child_ident.as_ref()
}
pub fn #child_mut_ident(&mut self) -> &mut #child_type_ident {
self.#child_ident.as_mut()
}
}
})
.collect::<Vec<_>>();
quote! {
pub struct #type_ident {
#(#annotated_members),*
}
impl #type_ident {
pub fn new(#(#annotated_members),*) -> Self {
Self {
#(#member_names),*
}
}
#(#accessors)*
}
}
}

View File

@ -1,6 +1,4 @@
use crate::spec::struct_spec::{ use crate::spec::struct_spec::{MemberChild, MemberChildBuild, StructChild, StructSpec, VecChild, VecChildBuild};
MemberChild, MemberChildBuild, StructChild, StructSpec, VecChild, VecChildBuild,
};
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote}; use quote::{format_ident, quote};
@ -13,7 +11,7 @@ fn make_vec_child_accessors(vec_child: &VecChild) -> TokenStream {
self.#child_ident.iter().map(String::as_str) self.#child_ident.iter().map(String::as_str)
} }
} }
} },
VecChildBuild::Node(vec_child_node_build) => { VecChildBuild::Node(vec_child_node_build) => {
let child_type_ident = format_ident!("{}", vec_child_node_build.kind()); let child_type_ident = format_ident!("{}", vec_child_node_build.kind());
let child_ident_mut = format_ident!("{}_mut", vec_child.name()); let child_ident_mut = format_ident!("{}_mut", vec_child.name());
@ -23,8 +21,8 @@ fn make_vec_child_accessors(vec_child: &VecChild) -> TokenStream {
self.#child_ident.iter().map(Box::as_ref) self.#child_ident.iter().map(Box::as_ref)
} }
pub fn #child_ident_mut(&mut self) -> impl Iterator<Item = &mut #child_type_ident> { pub fn #child_ident_mut(&mut self) -> impl Iterator<Item = &mut child_type_ident> {
self.#child_ident.iter_mut().map(Box::as_mut) self.#child_ident.iter().map(Box::as_mut)
} }
} }
} }
@ -81,16 +79,24 @@ fn make_member_child_accessors(member_child: &MemberChild) -> TokenStream {
fn make_accessors(child: &StructChild) -> Option<TokenStream> { fn make_accessors(child: &StructChild) -> Option<TokenStream> {
match child { match child {
StructChild::SkipChild(_) => None, StructChild::SkipChild(_) => None,
StructChild::VecChild(vec_child) => Some(make_vec_child_accessors(vec_child)), StructChild::VecChild(vec_child) => {
StructChild::MemberChild(member_child) => Some(make_member_child_accessors(member_child)), Some(make_vec_child_accessors(vec_child))
}
StructChild::MemberChild(member_child) => {
Some(make_member_child_accessors(member_child))
}
} }
} }
fn make_member_ident(child: &StructChild) -> Option<Ident> { fn make_member_ident(child: &StructChild) -> Option<Ident> {
match child { match child {
StructChild::SkipChild(_) => None, StructChild::SkipChild(_) => None,
StructChild::VecChild(vec_child) => Some(format_ident!("{}", vec_child.name())), StructChild::VecChild(vec_child) => {
StructChild::MemberChild(member_child) => Some(format_ident!("{}", member_child.name())), Some(format_ident!("{}", vec_child.name()))
},
StructChild::MemberChild(member_child) => {
Some(format_ident!("{}", member_child.name()))
}
} }
} }
@ -101,7 +107,7 @@ fn make_vec_child_annotated_member(vec_child: &VecChild) -> TokenStream {
VecChildBuild::Node(vec_child_node_build) => { VecChildBuild::Node(vec_child_node_build) => {
let type_ident = format_ident!("{}", vec_child_node_build.kind()); let type_ident = format_ident!("{}", vec_child_node_build.kind());
quote! { Box<#type_ident> } quote! { Box<#type_ident> }
} },
}; };
quote! { quote! {
@ -113,8 +119,8 @@ fn make_member_child_type_ident(member_child: &MemberChild) -> TokenStream {
match member_child.build() { match member_child.build() {
MemberChildBuild::Node(node_member_build) => { MemberChildBuild::Node(node_member_build) => {
let type_ident = format_ident!("{}", node_member_build.kind()); let type_ident = format_ident!("{}", node_member_build.kind());
quote! { Box<#type_ident> } quote! { #type_ident }
} },
MemberChildBuild::Boolean(_) => { MemberChildBuild::Boolean(_) => {
quote! { bool } quote! { bool }
} }
@ -127,7 +133,7 @@ fn make_member_child_annotated_member(member_child: &MemberChild) -> TokenStream
let type_stream = if member_child.optional() { let type_stream = if member_child.optional() {
quote! { Option<#type_ident> } quote! { Option<#type_ident> }
} else { } else {
quote! { #type_ident } type_ident
}; };
quote! { quote! {
@ -139,31 +145,32 @@ fn make_annotated_member(child: &StructChild) -> Option<TokenStream> {
match child { match child {
StructChild::SkipChild(_) => None, StructChild::SkipChild(_) => None,
StructChild::VecChild(vec_child) => Some(make_vec_child_annotated_member(vec_child)), StructChild::VecChild(vec_child) => Some(make_vec_child_annotated_member(vec_child)),
StructChild::MemberChild(member_child) => { StructChild::MemberChild(member_child) => Some(make_member_child_annotated_member(member_child)),
Some(make_member_child_annotated_member(member_child))
}
} }
} }
pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream { pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream {
let type_ident = format_ident!("{}", build_spec.build()); let type_ident = format_ident!("{}", build_spec.build());
let annotated_members = build_spec let annotated_members = build_spec.children()
.children() .map(|child| {
.map(|child| make_annotated_member(child)) make_annotated_member(child)
})
.filter(Option::is_some) .filter(Option::is_some)
.map(Option::unwrap) .map(Option::unwrap)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let member_names = build_spec let member_names = build_spec.children()
.children() .map(|child| {
.map(|child| make_member_ident(child)) make_member_ident(child)
})
.filter(Option::is_some) .filter(Option::is_some)
.map(Option::unwrap) .map(Option::unwrap)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let accessors = build_spec let accessors = build_spec.children()
.children() .map(|child| {
.map(|child| make_accessors(child)) make_accessors(child)
})
.filter(Option::is_some) .filter(Option::is_some)
.map(Option::unwrap) .map(Option::unwrap)
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View File

@ -342,8 +342,6 @@ $defs:
properties: properties:
kind: kind:
type: string type: string
reverse:
type: boolean
rules: rules:
type: array type: array
items: items:

View File

@ -863,10 +863,6 @@ ComparisonRhs:
- expression: - expression:
member: member:
rule: ShiftExpression rule: ShiftExpression
build:
node:
kind: Expression
with: ShiftExpression
ComparisonOperator: ComparisonOperator:
leaf_enum: leaf_enum:
rules: rules:
@ -903,10 +899,6 @@ ShiftRhs:
- expression: - expression:
member: member:
rule: AdditiveExpression rule: AdditiveExpression
build:
node:
kind: Expression
with: AdditiveExpression
ShiftOperator: ShiftOperator:
leaf_enum: leaf_enum:
rules: rules:
@ -919,7 +911,6 @@ AdditiveExpression:
- MultiplicativeExpression: - MultiplicativeExpression:
pass_through: pass_through:
kind: Expression kind: Expression
with: MultiplicativeExpression
- AdditiveRhs: - AdditiveRhs:
build: build:
variant: Additive variant: Additive
@ -939,10 +930,6 @@ AdditiveRhs:
- expression: - expression:
member: member:
rule: MultiplicativeExpression rule: MultiplicativeExpression
build:
node:
kind: Expression
with: MultiplicativeExpression
AdditiveOperator: AdditiveOperator:
leaf_enum: leaf_enum:
rules: rules:
@ -955,7 +942,6 @@ MultiplicativeExpression:
- PrefixExpression: - PrefixExpression:
pass_through: pass_through:
kind: Expression kind: Expression
with: PrefixExpression
- MultiplicativeRhs: - MultiplicativeRhs:
build: build:
variant: Multiplicative variant: Multiplicative
@ -975,10 +961,6 @@ MultiplicativeRhs:
- expression: - expression:
member: member:
rule: PrefixExpression rule: PrefixExpression
build:
node:
kind: Expression
with: PrefixExpression
MultiplicativeOperator: MultiplicativeOperator:
leaf_enum: leaf_enum:
rules: rules:
@ -988,18 +970,17 @@ MultiplicativeOperator:
PrefixExpression: PrefixExpression:
polymorphic_enum_loop_build: polymorphic_enum_loop_build:
kind: Expression kind: Expression
reverse: true
rules: rules:
- PrefixOperator: - PrefixOperator:
build: build:
variant: Prefix variant: Prefix
children: children:
- operator: - operator:
on_each:
rule: PrefixOperator
- expression:
use_current: use_current:
kind: Expression kind: Expression
- expression:
on_each:
rule: SuffixExpression
- SuffixExpression: - SuffixExpression:
pass_through: pass_through:
kind: Expression kind: Expression
@ -1027,7 +1008,7 @@ SuffixExpression:
kind: Expression kind: Expression
- operator: - operator:
on_each: on_each:
rule: SuffixOperator rule: SuffixExpression
SuffixOperator: SuffixOperator:
tree_enum: tree_enum:
rules: rules:
@ -1060,7 +1041,7 @@ PrimaryExpression:
- Closure: - Closure:
inner: inner:
kind: Closure kind: Closure
- List: - ListExpression:
inner: inner:
kind: ListExpression kind: ListExpression
- ParenthesizedExpression: - ParenthesizedExpression:
@ -1071,9 +1052,9 @@ ListExpression:
children: children:
- expression_list - expression_list
ParenthesizedExpression: ParenthesizedExpression:
node_production: struct:
kind: Expression children:
with: Expression - expression
# Calls # Calls
Call: Call: