Compare commits
8 Commits
0d2db659ca
...
41673a68f8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41673a68f8 | ||
|
|
86331ee9b0 | ||
|
|
4eb48cc1a2 | ||
|
|
3159f119bc | ||
|
|
5a3403cc28 | ||
|
|
39e9c2ddd5 | ||
|
|
12c565d0e1 | ||
|
|
8a6e4277a7 |
@ -1,10 +1,10 @@
|
||||
use crate::deserialize::util::make_build_pair;
|
||||
use crate::deserialize::util::{make_build_fn_name, make_build_pair};
|
||||
use crate::spec::node_production_spec::NodeProductionBuildSpec;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
pub fn make_node_production_build_fn(spec: &NodeProductionBuildSpec) -> TokenStream {
|
||||
let build_fn_ident = format_ident!("{}", spec.with());
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(spec.name()));
|
||||
let pair_ident = format_ident!("{}", make_build_pair(spec.name()));
|
||||
let return_type_ident = format_ident!("{}", spec.kind());
|
||||
let inner_build_fn_ident = format_ident!("{}", spec.with());
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
use crate::deserialize::util::{make_build_fn_name, make_build_pair};
|
||||
use crate::spec::polymorphic_enum_loop_spec::{
|
||||
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule,
|
||||
PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopRuleBuildChild,
|
||||
PolymorphicEnumLoopRuleChildOnEach, PolymorphicEnumLoopRulePassThrough,
|
||||
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuild,
|
||||
PolymorphicEnumLoopRuleBuildChild, PolymorphicEnumLoopRuleChildOnEach,
|
||||
PolymorphicEnumLoopRulePassThrough,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
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 {
|
||||
let child_build_fn_ident = format_ident!("{}", make_build_fn_name(child.rule()));
|
||||
quote! {
|
||||
#child_build_fn_ident(inner_pair)
|
||||
Box::new(#child_build_fn_ident(inner_pair))
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ fn make_build(
|
||||
build: &PolymorphicEnumLoopRuleBuild,
|
||||
) -> TokenStream {
|
||||
let rule_ident = format_ident!("{}", build.name());
|
||||
let variant_type_ident = format_ident!("{}", build.name());
|
||||
let variant_type_ident = format_ident!("{}", spec.name());
|
||||
let return_type_ident = format_ident!("{}", spec.kind());
|
||||
let variant_ident = format_ident!("{}", build.variant());
|
||||
|
||||
@ -39,11 +39,9 @@ fn make_build(
|
||||
PolymorphicEnumLoopRuleBuildChild::OnEach(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.map(|child| {
|
||||
match child {
|
||||
.map(|child| match child {
|
||||
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => on_each,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
@ -53,7 +51,7 @@ fn make_build(
|
||||
.children()
|
||||
.map(|child| match child {
|
||||
PolymorphicEnumLoopRuleBuildChild::UseCurrent(_) => {
|
||||
quote! { result.unwrap() }
|
||||
quote! { Box::new(result.unwrap()) }
|
||||
}
|
||||
PolymorphicEnumLoopRuleBuildChild::OnEach(_) => quote! { on_each_child },
|
||||
})
|
||||
@ -68,7 +66,10 @@ fn make_build(
|
||||
}
|
||||
}
|
||||
|
||||
fn make_match_arm(spec: &PolymorphicEnumLoopBuildSpec, rule: &PolymorphicEnumLoopRule) -> TokenStream {
|
||||
fn make_match_arm(
|
||||
spec: &PolymorphicEnumLoopBuildSpec,
|
||||
rule: &PolymorphicEnumLoopRule,
|
||||
) -> TokenStream {
|
||||
match rule {
|
||||
PolymorphicEnumLoopRule::PassThrough(pass_through) => make_pass_through(pass_through),
|
||||
PolymorphicEnumLoopRule::Build(build) => make_build(spec, build),
|
||||
@ -80,6 +81,12 @@ pub fn make_polymorphic_enum_loop_build_fn(spec: &PolymorphicEnumLoopBuildSpec)
|
||||
let pair_ident = format_ident!("{}", make_build_pair(spec.name()));
|
||||
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
|
||||
.rules()
|
||||
.map(|rule| make_match_arm(spec, rule))
|
||||
@ -88,10 +95,10 @@ pub fn make_polymorphic_enum_loop_build_fn(spec: &PolymorphicEnumLoopBuildSpec)
|
||||
quote! {
|
||||
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
|
||||
let mut result: Option<#return_type_ident> = None;
|
||||
for inner_pair in #pair_ident.into_inner() {
|
||||
for inner_pair in #iter_expr {
|
||||
match inner_pair.as_rule() {
|
||||
#(#match_arms,)*
|
||||
_ => unreachable!()
|
||||
_ => unreachable!("Unexpected parse rule: {:?} (inner pair: {:#?}", inner_pair.as_rule(), inner_pair),
|
||||
}
|
||||
}
|
||||
result.unwrap()
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::deserialize::util::{make_build_fn_name, unwrap_single_member_hash};
|
||||
use crate::deserialize::util::{get_as_bool, make_build_fn_name, unwrap_single_member_hash};
|
||||
use crate::spec::polymorphic_enum_loop_spec::{
|
||||
PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopChildUseCurrent, PolymorphicEnumLoopRule,
|
||||
PolymorphicEnumLoopRuleBuild, PolymorphicEnumLoopRuleBuildChild,
|
||||
@ -62,6 +62,8 @@ fn deserialize_rule(rule_name: &str, props: &Yaml) -> PolymorphicEnumLoopRule {
|
||||
|
||||
pub fn deserialize_polymorphic_enum_loop(name: &str, props: &Yaml) -> PolymorphicEnumLoopBuildSpec {
|
||||
let kind = props["kind"].as_str().unwrap();
|
||||
let reverse = get_as_bool(&props["reverse"]);
|
||||
|
||||
let rules = props["rules"]
|
||||
.as_vec()
|
||||
.unwrap()
|
||||
@ -73,5 +75,5 @@ pub fn deserialize_polymorphic_enum_loop(name: &str, props: &Yaml) -> Polymorphi
|
||||
.map(Box::new)
|
||||
.collect();
|
||||
|
||||
PolymorphicEnumLoopBuildSpec::new(name, kind, rules)
|
||||
PolymorphicEnumLoopBuildSpec::new(name, kind, reverse, rules)
|
||||
}
|
||||
|
||||
@ -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 with = node_props["with"]
|
||||
.as_str()
|
||||
.map(ToString::to_string)
|
||||
.map(|with| make_build_fn_name(with))
|
||||
.unwrap_or_else(|| make_build_fn_name(kind));
|
||||
|
||||
let or_else = if get_as_bool(&node_props["or_else_default"]) {
|
||||
|
||||
@ -6,7 +6,7 @@ mod type_gen;
|
||||
|
||||
use crate::build_fn::make_build_fn;
|
||||
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 proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
@ -117,24 +117,27 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
||||
}
|
||||
|
||||
fn generate_pretty_print_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
||||
// let impls = build_specs
|
||||
// .iter()
|
||||
// .map(|build_spec| {
|
||||
// let stream = make_pretty_print_impl(build_spec);
|
||||
// debug_built_spec(build_spec, &stream);
|
||||
// stream
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
//
|
||||
// let combined = quote! {
|
||||
// use crate::ast::node::*;
|
||||
// #(#impls)*
|
||||
// };
|
||||
// AstGeneratedFile {
|
||||
// name: String::from("pretty_print.rs"),
|
||||
// contents: token_stream_to_string(combined),
|
||||
// }
|
||||
todo!()
|
||||
let impls = build_specs
|
||||
.iter()
|
||||
.map(|build_spec| {
|
||||
let maybe_stream = make_pretty_print_impl(build_spec);
|
||||
if let Some(stream) = &maybe_stream {
|
||||
debug_built_spec(build_spec, &stream);
|
||||
}
|
||||
maybe_stream
|
||||
})
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let combined = quote! {
|
||||
use crate::ast::node::*;
|
||||
#(#impls)*
|
||||
};
|
||||
AstGeneratedFile {
|
||||
name: String::from("pretty_print.rs"),
|
||||
contents: token_stream_to_string(combined),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_build_specs(yaml: &str) -> Vec<BuildSpec> {
|
||||
@ -145,6 +148,6 @@ pub fn generate_files(build_specs: &[BuildSpec]) -> Vec<AstGeneratedFile> {
|
||||
vec![
|
||||
generate_build_file(build_specs),
|
||||
generate_node_file(build_specs),
|
||||
// generate_pretty_print_file(build_specs),
|
||||
generate_pretty_print_file(build_specs),
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,260 +1,265 @@
|
||||
// use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
|
||||
// use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind};
|
||||
// use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
|
||||
// use crate::spec::production_spec::ProductionBuildSpec;
|
||||
// use crate::spec::struct_spec::StructSpec;
|
||||
// use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
|
||||
// use crate::spec::{
|
||||
// AlternativeChild, BuildSpec, MemberChildToBuild, PolymorphicBuildBuildSpec,
|
||||
// PolymorphicEnumBuildSpec, StructChildSpec, VecChildToBuild,
|
||||
// };
|
||||
// use convert_case::{Case, Casing};
|
||||
// use proc_macro2::TokenStream;
|
||||
// use quote::{format_ident, quote};
|
||||
//
|
||||
// fn make_production_p2_impl(_spec: &ProductionBuildSpec) -> TokenStream {
|
||||
// quote! {}
|
||||
// }
|
||||
//
|
||||
// fn make_polymorphic_enum_p2_impl(_spec: &PolymorphicEnumBuildSpec) -> TokenStream {
|
||||
// quote! {}
|
||||
// }
|
||||
//
|
||||
// fn make_polymorphic_build_p2_impl(spec: &PolymorphicBuildBuildSpec) -> TokenStream {
|
||||
// let (_, build) = spec.primary_alternative();
|
||||
// let type_ident = format_ident!("{}", spec.name());
|
||||
// let name_str = spec.name();
|
||||
//
|
||||
// let child_statements = build
|
||||
// .children()
|
||||
// .map(|child| match child {
|
||||
// AlternativeChild::Skip => None,
|
||||
// AlternativeChild::Build(build) => {
|
||||
// let child_ident = format_ident!("{}", build.name());
|
||||
// Some(quote! {
|
||||
// self.#child_ident().pretty_print(writer)?
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// .filter(Option::is_some)
|
||||
// .map(Option::unwrap)
|
||||
// .collect::<Vec<TokenStream>>();
|
||||
//
|
||||
// quote! {
|
||||
// impl PrettyPrint for #type_ident {
|
||||
// fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
// 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
|
||||
// .variants()
|
||||
// .map(|member| {
|
||||
// let enum_member_ident = format_ident!("{}", member.name());
|
||||
// let inner_name = format_ident!("{}", member.inner_kind().to_case(Case::Snake));
|
||||
// quote! {
|
||||
// #type_ident::#enum_member_ident(#inner_name) => #inner_name.pretty_print(writer)
|
||||
// }
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
//
|
||||
// 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| {
|
||||
// let enum_variant_ident = format_ident!("{}", rule.rule());
|
||||
// let name_str = rule.rule();
|
||||
// quote! {
|
||||
// #type_ident::#enum_variant_ident => writer.writeln_indented(#name_str)
|
||||
// }
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
//
|
||||
// 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: &TreeEnumBuildSpec) -> TokenStream {
|
||||
// let type_ident = format_ident!("{}", spec.build());
|
||||
// let type_str = spec.build();
|
||||
//
|
||||
// let child_matchers = spec
|
||||
// .rules()
|
||||
// .map(|rule| {
|
||||
// let enum_variant_ident = format_ident!("{}", rule.rule());
|
||||
// if let Some(child) = rule.child() {
|
||||
// match child.kind() {
|
||||
// EnumRuleChildKind::Node(node_child) => {
|
||||
// let child_name_ident =
|
||||
// format_ident!("{}", node_child.build().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();
|
||||
// Some(quote! {
|
||||
// #type_ident::#enum_variant_ident => writer.writeln_indented(#variant_str)?
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// .filter(Option::is_some)
|
||||
// .map(Option::unwrap)
|
||||
// .collect::<Vec<_>>();
|
||||
//
|
||||
// quote! {
|
||||
// impl PrettyPrint for #type_ident {
|
||||
// fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
// writer.writeln_indented(#type_str)?;
|
||||
// writer.increase_indent();
|
||||
// match self {
|
||||
// #(#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() {
|
||||
// LeafStructMemberKind::String => Some("{}"),
|
||||
// })
|
||||
// .filter(Option::is_some)
|
||||
// .map(Option::unwrap)
|
||||
// .collect::<Vec<_>>()
|
||||
// .join(", ");
|
||||
//
|
||||
// let format_string = format!("{}({})", leaf_struct_build_spec.build(), member_formatters);
|
||||
//
|
||||
// let members = leaf_struct_build_spec
|
||||
// .members()
|
||||
// .map(|member| {
|
||||
// let member_ident = format_ident!("{}", member.name());
|
||||
// quote! {
|
||||
// self.#member_ident()
|
||||
// }
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
//
|
||||
// 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 {
|
||||
// StructChildSpec::SkipChild(_) => None,
|
||||
// StructChildSpec::VecChild(vec_child) => match vec_child.build() {
|
||||
// VecChildToBuild::Node(_) => {
|
||||
// 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) => {
|
||||
// let child_ident = format_ident!("{}", member_child.name());
|
||||
// if node_member_child.optional() {
|
||||
// Some(quote! {
|
||||
// if let Some(child) = self.#child_ident() {
|
||||
// child.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! {
|
||||
// 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());
|
||||
// let type_string = struct_build_spec.build();
|
||||
//
|
||||
// quote! {
|
||||
// impl PrettyPrint for #type_ident {
|
||||
// fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
// 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),
|
||||
// BuildSpec::LeafEnum(leaf_enum) => make_leaf_enum_p2_impl(leaf_enum),
|
||||
// BuildSpec::PolymorphicType(polymorphic) => make_polymorphic_type_p2_impl(polymorphic),
|
||||
// BuildSpec::PolymorphicBuild(polymorphic_build) => {
|
||||
// make_polymorphic_build_p2_impl(polymorphic_build)
|
||||
// }
|
||||
// BuildSpec::PolymorphicEnum(polymorphic_enum) => {
|
||||
// make_polymorphic_enum_p2_impl(polymorphic_enum)
|
||||
// }
|
||||
// BuildSpec::Production(production) => make_production_p2_impl(production),
|
||||
// }
|
||||
// }
|
||||
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
|
||||
use crate::spec::leaf_struct_spec::{LeafStructBuildSpec, LeafStructMemberKind};
|
||||
use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
|
||||
use crate::spec::struct_spec::{MemberChildBuild, StructChild, StructSpec, VecChildBuild};
|
||||
use crate::spec::tree_enum_spec::{EnumRuleChildKind, TreeEnumBuildSpec};
|
||||
use crate::spec::BuildSpec;
|
||||
use convert_case::{Case, Casing};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use crate::spec::polymorphic_enum_loop_spec::{PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild};
|
||||
|
||||
fn make_polymorphic_enum_loop_p2_impl(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream {
|
||||
let type_ident = format_ident!("{}", spec.name());
|
||||
let type_string = 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 child_print_statements = build.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! {
|
||||
self.#child_ident().pretty_print(writer)?;
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
impl PrettyPrint for #type_ident {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(#type_string)?;
|
||||
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()
|
||||
.map(|member| {
|
||||
let enum_member_ident = format_ident!("{}", member.name());
|
||||
let inner_name = format_ident!("{}", member.inner_kind().to_case(Case::Snake));
|
||||
quote! {
|
||||
#type_ident::#enum_member_ident(#inner_name) => #inner_name.pretty_print(writer)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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| {
|
||||
let enum_variant_ident = format_ident!("{}", rule);
|
||||
let name_str = rule;
|
||||
quote! {
|
||||
#type_ident::#enum_variant_ident => writer.writeln_indented(#name_str)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
impl PrettyPrint for #type_ident {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
match self {
|
||||
#(#child_matchers,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_tree_enum_p2_impl(spec: &TreeEnumBuildSpec) -> TokenStream {
|
||||
let type_ident = format_ident!("{}", spec.build());
|
||||
let type_str = spec.build();
|
||||
|
||||
let child_matchers = spec
|
||||
.rules()
|
||||
.map(|rule| {
|
||||
let enum_variant_ident = format_ident!("{}", rule.rule());
|
||||
if let Some(child) = rule.child() {
|
||||
match child.kind() {
|
||||
EnumRuleChildKind::Node(node_child) => {
|
||||
let child_name_ident =
|
||||
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();
|
||||
Some(quote! {
|
||||
#type_ident::#enum_variant_ident => writer.writeln_indented(#variant_str)?
|
||||
})
|
||||
}
|
||||
})
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
impl PrettyPrint for #type_ident {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(#type_str)?;
|
||||
writer.increase_indent();
|
||||
match self {
|
||||
#(#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() {
|
||||
LeafStructMemberKind::String => Some("{}"),
|
||||
})
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
||||
let format_string = format!("{}({})", leaf_struct_build_spec.build(), member_formatters);
|
||||
|
||||
let members = leaf_struct_build_spec
|
||||
.members()
|
||||
.map(|member| {
|
||||
let member_ident = format_ident!("{}", member.name());
|
||||
quote! {
|
||||
self.#member_ident()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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 {
|
||||
StructChild::SkipChild(_) => None,
|
||||
StructChild::VecChild(vec_child) => match vec_child.build() {
|
||||
VecChildBuild::Node(_) => {
|
||||
let child_ident = format_ident!("{}", vec_child.name());
|
||||
Some(quote! {
|
||||
for child in self.#child_ident() {
|
||||
child.pretty_print(writer)?;
|
||||
}
|
||||
})
|
||||
}
|
||||
VecChildBuild::String(_) => None,
|
||||
},
|
||||
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildBuild::Node(_) => {
|
||||
let child_ident = format_ident!("{}", member_child.name());
|
||||
if member_child.optional() {
|
||||
Some(quote! {
|
||||
if let Some(child) = self.#child_ident() {
|
||||
child.pretty_print(writer)?;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Some(quote! {
|
||||
self.#child_ident().pretty_print(writer)?;
|
||||
})
|
||||
}
|
||||
}
|
||||
MemberChildBuild::Boolean(_) => {
|
||||
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<_>>();
|
||||
|
||||
let type_ident = format_ident!("{}", struct_build_spec.build());
|
||||
let type_string = struct_build_spec.build();
|
||||
|
||||
quote! {
|
||||
impl PrettyPrint for #type_ident {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(#type_string)?;
|
||||
writer.increase_indent();
|
||||
#(#child_print_statements)*
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_pretty_print_impl(build_spec: &BuildSpec) -> Option<TokenStream> {
|
||||
match build_spec {
|
||||
BuildSpec::Struct(struct_spec) => Some(make_struct_p2_impl(struct_spec)),
|
||||
BuildSpec::LeafStruct(leaf_struct) => Some(make_leaf_struct_p2_impl(leaf_struct)),
|
||||
BuildSpec::Enum(enum_spec) => Some(make_tree_enum_p2_impl(enum_spec)),
|
||||
BuildSpec::LeafEnum(leaf_enum) => Some(make_leaf_enum_p2_impl(leaf_enum)),
|
||||
BuildSpec::Production(_) => None,
|
||||
BuildSpec::NodeProduction(_) => None,
|
||||
BuildSpec::PolymorphicType(polymorphic_type) => {
|
||||
Some(make_polymorphic_type_p2_impl(polymorphic_type))
|
||||
}
|
||||
BuildSpec::PolymorphicPassThrough(_) => None,
|
||||
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => {
|
||||
Some(make_polymorphic_enum_loop_p2_impl(polymorphic_enum_loop))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
pub struct PolymorphicEnumLoopBuildSpec {
|
||||
name: String,
|
||||
kind: String,
|
||||
reverse: bool,
|
||||
rules: Vec<Box<PolymorphicEnumLoopRule>>,
|
||||
}
|
||||
|
||||
impl PolymorphicEnumLoopBuildSpec {
|
||||
pub fn new(name: &str, kind: &str, rules: Vec<Box<PolymorphicEnumLoopRule>>) -> Self {
|
||||
pub fn new(name: &str, kind: &str, reverse: bool, rules: Vec<Box<PolymorphicEnumLoopRule>>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
kind: kind.to_string(),
|
||||
reverse,
|
||||
rules,
|
||||
}
|
||||
}
|
||||
@ -21,6 +23,10 @@ impl PolymorphicEnumLoopBuildSpec {
|
||||
&self.kind
|
||||
}
|
||||
|
||||
pub fn reverse(&self) -> bool {
|
||||
self.reverse
|
||||
}
|
||||
|
||||
pub fn rules(&self) -> impl Iterator<Item = &PolymorphicEnumLoopRule> {
|
||||
self.rules.iter().map(Box::as_ref)
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
mod enum_type;
|
||||
mod leaf_enum_type;
|
||||
mod leaf_struct_type;
|
||||
mod polymorphic_enum_loop_type;
|
||||
mod polymorphic_type_type;
|
||||
mod struct_type;
|
||||
|
||||
@ -11,6 +12,7 @@ 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::struct_type::make_struct_type;
|
||||
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> {
|
||||
match build_spec {
|
||||
@ -27,7 +29,9 @@ pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
|
||||
BuildSpec::PolymorphicType(polymorphic_build_spec) => {
|
||||
Some(make_polymorphic_type_type(polymorphic_build_spec))
|
||||
}
|
||||
BuildSpec::PolymorphicEnumLoop(_) => None,
|
||||
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop_spec) => {
|
||||
Some(make_polymorphic_enum_loop_type(polymorphic_enum_loop_spec))
|
||||
},
|
||||
BuildSpec::PolymorphicPassThrough(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
96
ast-generator/src/type_gen/polymorphic_enum_loop_type.rs
Normal file
96
ast-generator/src/type_gen/polymorphic_enum_loop_type.rs
Normal file
@ -0,0 +1,96 @@
|
||||
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)*
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
use crate::spec::struct_spec::{MemberChild, MemberChildBuild, StructChild, StructSpec, VecChild, VecChildBuild};
|
||||
use crate::spec::struct_spec::{
|
||||
MemberChild, MemberChildBuild, StructChild, StructSpec, VecChild, VecChildBuild,
|
||||
};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
@ -11,7 +13,7 @@ fn make_vec_child_accessors(vec_child: &VecChild) -> TokenStream {
|
||||
self.#child_ident.iter().map(String::as_str)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
VecChildBuild::Node(vec_child_node_build) => {
|
||||
let child_type_ident = format_ident!("{}", vec_child_node_build.kind());
|
||||
let child_ident_mut = format_ident!("{}_mut", vec_child.name());
|
||||
@ -21,8 +23,8 @@ fn make_vec_child_accessors(vec_child: &VecChild) -> TokenStream {
|
||||
self.#child_ident.iter().map(Box::as_ref)
|
||||
}
|
||||
|
||||
pub fn #child_ident_mut(&mut self) -> impl Iterator<Item = &mut child_type_ident> {
|
||||
self.#child_ident.iter().map(Box::as_mut)
|
||||
pub fn #child_ident_mut(&mut self) -> impl Iterator<Item = &mut #child_type_ident> {
|
||||
self.#child_ident.iter_mut().map(Box::as_mut)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,24 +81,16 @@ fn make_member_child_accessors(member_child: &MemberChild) -> TokenStream {
|
||||
fn make_accessors(child: &StructChild) -> Option<TokenStream> {
|
||||
match child {
|
||||
StructChild::SkipChild(_) => None,
|
||||
StructChild::VecChild(vec_child) => {
|
||||
Some(make_vec_child_accessors(vec_child))
|
||||
}
|
||||
StructChild::MemberChild(member_child) => {
|
||||
Some(make_member_child_accessors(member_child))
|
||||
}
|
||||
StructChild::VecChild(vec_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> {
|
||||
match child {
|
||||
StructChild::SkipChild(_) => None,
|
||||
StructChild::VecChild(vec_child) => {
|
||||
Some(format_ident!("{}", vec_child.name()))
|
||||
},
|
||||
StructChild::MemberChild(member_child) => {
|
||||
Some(format_ident!("{}", member_child.name()))
|
||||
}
|
||||
StructChild::VecChild(vec_child) => Some(format_ident!("{}", vec_child.name())),
|
||||
StructChild::MemberChild(member_child) => Some(format_ident!("{}", member_child.name())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,7 +101,7 @@ fn make_vec_child_annotated_member(vec_child: &VecChild) -> TokenStream {
|
||||
VecChildBuild::Node(vec_child_node_build) => {
|
||||
let type_ident = format_ident!("{}", vec_child_node_build.kind());
|
||||
quote! { Box<#type_ident> }
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
@ -119,8 +113,8 @@ fn make_member_child_type_ident(member_child: &MemberChild) -> TokenStream {
|
||||
match member_child.build() {
|
||||
MemberChildBuild::Node(node_member_build) => {
|
||||
let type_ident = format_ident!("{}", node_member_build.kind());
|
||||
quote! { #type_ident }
|
||||
},
|
||||
quote! { Box<#type_ident> }
|
||||
}
|
||||
MemberChildBuild::Boolean(_) => {
|
||||
quote! { bool }
|
||||
}
|
||||
@ -133,7 +127,7 @@ fn make_member_child_annotated_member(member_child: &MemberChild) -> TokenStream
|
||||
let type_stream = if member_child.optional() {
|
||||
quote! { Option<#type_ident> }
|
||||
} else {
|
||||
type_ident
|
||||
quote! { #type_ident }
|
||||
};
|
||||
|
||||
quote! {
|
||||
@ -145,32 +139,31 @@ fn make_annotated_member(child: &StructChild) -> Option<TokenStream> {
|
||||
match child {
|
||||
StructChild::SkipChild(_) => None,
|
||||
StructChild::VecChild(vec_child) => Some(make_vec_child_annotated_member(vec_child)),
|
||||
StructChild::MemberChild(member_child) => Some(make_member_child_annotated_member(member_child)),
|
||||
StructChild::MemberChild(member_child) => {
|
||||
Some(make_member_child_annotated_member(member_child))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_struct_type(build_spec: &StructSpec) -> TokenStream {
|
||||
let type_ident = format_ident!("{}", build_spec.build());
|
||||
let annotated_members = build_spec.children()
|
||||
.map(|child| {
|
||||
make_annotated_member(child)
|
||||
})
|
||||
let annotated_members = build_spec
|
||||
.children()
|
||||
.map(|child| make_annotated_member(child))
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let member_names = build_spec.children()
|
||||
.map(|child| {
|
||||
make_member_ident(child)
|
||||
})
|
||||
let member_names = build_spec
|
||||
.children()
|
||||
.map(|child| make_member_ident(child))
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let accessors = build_spec.children()
|
||||
.map(|child| {
|
||||
make_accessors(child)
|
||||
})
|
||||
let accessors = build_spec
|
||||
.children()
|
||||
.map(|child| make_accessors(child))
|
||||
.filter(Option::is_some)
|
||||
.map(Option::unwrap)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@ -342,6 +342,8 @@ $defs:
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
reverse:
|
||||
type: boolean
|
||||
rules:
|
||||
type: array
|
||||
items:
|
||||
|
||||
@ -863,6 +863,10 @@ ComparisonRhs:
|
||||
- expression:
|
||||
member:
|
||||
rule: ShiftExpression
|
||||
build:
|
||||
node:
|
||||
kind: Expression
|
||||
with: ShiftExpression
|
||||
ComparisonOperator:
|
||||
leaf_enum:
|
||||
rules:
|
||||
@ -899,6 +903,10 @@ ShiftRhs:
|
||||
- expression:
|
||||
member:
|
||||
rule: AdditiveExpression
|
||||
build:
|
||||
node:
|
||||
kind: Expression
|
||||
with: AdditiveExpression
|
||||
ShiftOperator:
|
||||
leaf_enum:
|
||||
rules:
|
||||
@ -911,6 +919,7 @@ AdditiveExpression:
|
||||
- MultiplicativeExpression:
|
||||
pass_through:
|
||||
kind: Expression
|
||||
with: MultiplicativeExpression
|
||||
- AdditiveRhs:
|
||||
build:
|
||||
variant: Additive
|
||||
@ -930,6 +939,10 @@ AdditiveRhs:
|
||||
- expression:
|
||||
member:
|
||||
rule: MultiplicativeExpression
|
||||
build:
|
||||
node:
|
||||
kind: Expression
|
||||
with: MultiplicativeExpression
|
||||
AdditiveOperator:
|
||||
leaf_enum:
|
||||
rules:
|
||||
@ -942,6 +955,7 @@ MultiplicativeExpression:
|
||||
- PrefixExpression:
|
||||
pass_through:
|
||||
kind: Expression
|
||||
with: PrefixExpression
|
||||
- MultiplicativeRhs:
|
||||
build:
|
||||
variant: Multiplicative
|
||||
@ -961,6 +975,10 @@ MultiplicativeRhs:
|
||||
- expression:
|
||||
member:
|
||||
rule: PrefixExpression
|
||||
build:
|
||||
node:
|
||||
kind: Expression
|
||||
with: PrefixExpression
|
||||
MultiplicativeOperator:
|
||||
leaf_enum:
|
||||
rules:
|
||||
@ -970,17 +988,18 @@ MultiplicativeOperator:
|
||||
PrefixExpression:
|
||||
polymorphic_enum_loop_build:
|
||||
kind: Expression
|
||||
reverse: true
|
||||
rules:
|
||||
- PrefixOperator:
|
||||
build:
|
||||
variant: Prefix
|
||||
children:
|
||||
- operator:
|
||||
on_each:
|
||||
rule: PrefixOperator
|
||||
- expression:
|
||||
use_current:
|
||||
kind: Expression
|
||||
- expression:
|
||||
on_each:
|
||||
rule: SuffixExpression
|
||||
- SuffixExpression:
|
||||
pass_through:
|
||||
kind: Expression
|
||||
@ -1008,7 +1027,7 @@ SuffixExpression:
|
||||
kind: Expression
|
||||
- operator:
|
||||
on_each:
|
||||
rule: SuffixExpression
|
||||
rule: SuffixOperator
|
||||
SuffixOperator:
|
||||
tree_enum:
|
||||
rules:
|
||||
@ -1041,7 +1060,7 @@ PrimaryExpression:
|
||||
- Closure:
|
||||
inner:
|
||||
kind: Closure
|
||||
- ListExpression:
|
||||
- List:
|
||||
inner:
|
||||
kind: ListExpression
|
||||
- ParenthesizedExpression:
|
||||
@ -1052,9 +1071,9 @@ ListExpression:
|
||||
children:
|
||||
- expression_list
|
||||
ParenthesizedExpression:
|
||||
struct:
|
||||
children:
|
||||
- expression
|
||||
node_production:
|
||||
kind: Expression
|
||||
with: Expression
|
||||
|
||||
# Calls
|
||||
Call:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user