Add polymorphic pass through.
This commit is contained in:
parent
4b59abc989
commit
13e2ae6b0c
@ -8,6 +8,7 @@ use crate::build_fn::struct_build_fn::make_struct_build_fn;
|
|||||||
use crate::build_fn::tree_enum_build_fn::make_enum_build_fn;
|
use crate::build_fn::tree_enum_build_fn::make_enum_build_fn;
|
||||||
use crate::spec::BuildSpec;
|
use crate::spec::BuildSpec;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
use crate::build_fn::polymorphic_pass_through_build_fn::make_polymorphic_pass_through_build_fn;
|
||||||
|
|
||||||
mod leaf_enum_build_fn;
|
mod leaf_enum_build_fn;
|
||||||
mod leaf_struct_build_fn;
|
mod leaf_struct_build_fn;
|
||||||
@ -15,6 +16,7 @@ mod node_production_build_fn;
|
|||||||
mod polymorphic_build_build_fn;
|
mod polymorphic_build_build_fn;
|
||||||
mod polymorphic_enum_build_fn;
|
mod polymorphic_enum_build_fn;
|
||||||
mod polymorphic_enum_loop_build_fn;
|
mod polymorphic_enum_loop_build_fn;
|
||||||
|
mod polymorphic_pass_through_build_fn;
|
||||||
mod polymorphic_type_build_fn;
|
mod polymorphic_type_build_fn;
|
||||||
mod production_build_fn;
|
mod production_build_fn;
|
||||||
mod struct_build_fn;
|
mod struct_build_fn;
|
||||||
@ -36,5 +38,8 @@ pub fn make_build_fn(build_spec: &BuildSpec) -> TokenStream {
|
|||||||
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop_spec) => {
|
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop_spec) => {
|
||||||
make_polymorphic_enum_loop_build_fn(polymorphic_enum_loop_spec)
|
make_polymorphic_enum_loop_build_fn(polymorphic_enum_loop_spec)
|
||||||
}
|
}
|
||||||
|
BuildSpec::PolymorphicPassThrough(polymorphic_pass_through_spec) => {
|
||||||
|
make_polymorphic_pass_through_build_fn(polymorphic_pass_through_spec)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,50 @@
|
|||||||
|
use crate::deserialize::util::{make_build_fn_name, make_build_pair};
|
||||||
|
use crate::spec::polymorphic_pass_through_spec::{PolymorphicPassThroughBuildSpec, PolymorphicPassThroughVariant};
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{format_ident, quote};
|
||||||
|
|
||||||
|
pub fn make_polymorphic_pass_through_build_fn(
|
||||||
|
spec: &PolymorphicPassThroughBuildSpec,
|
||||||
|
) -> TokenStream {
|
||||||
|
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.build_kind());
|
||||||
|
|
||||||
|
let match_arms = spec.variants()
|
||||||
|
.map(|variant| {
|
||||||
|
match variant {
|
||||||
|
PolymorphicPassThroughVariant::Inner { name, kind} => {
|
||||||
|
let rule_ident = format_ident!("{}", kind);
|
||||||
|
let variant_ident = format_ident!("{}", name);
|
||||||
|
let inner_build_fn_ident = format_ident!("{}", make_build_fn_name(kind));
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
Rule::#rule_ident => {
|
||||||
|
#return_type_ident::#variant_ident(
|
||||||
|
#inner_build_fn_ident(inner_pair)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PolymorphicPassThroughVariant::PassThrough { name, kind: _kind } => {
|
||||||
|
let rule_ident = format_ident!("{}", name);
|
||||||
|
let inner_build_fn_ident = format_ident!("{}", make_build_fn_name(name));
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
Rule::#rule_ident => #inner_build_fn_ident(inner_pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
fn #build_fn_ident(#pair_ident: Pair<Rule>) -> #return_type_ident {
|
||||||
|
let inner_pair = #pair_ident.into_inner().next().unwrap();
|
||||||
|
match inner_pair.as_rule() {
|
||||||
|
#(#match_arms,)*
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ mod leaf_enum_spec;
|
|||||||
mod leaf_struct_spec;
|
mod leaf_struct_spec;
|
||||||
mod node_production_spec;
|
mod node_production_spec;
|
||||||
mod polymorphic_enum_loop_spec;
|
mod polymorphic_enum_loop_spec;
|
||||||
|
mod polymorphic_pass_through_spec;
|
||||||
mod polymorphic_type_spec;
|
mod polymorphic_type_spec;
|
||||||
mod production_spec;
|
mod production_spec;
|
||||||
mod struct_spec;
|
mod struct_spec;
|
||||||
@ -18,6 +19,7 @@ use crate::deserialize::struct_spec::deserialize_struct_spec;
|
|||||||
use crate::deserialize::tree_enum_spec::deserialize_tree_enum;
|
use crate::deserialize::tree_enum_spec::deserialize_tree_enum;
|
||||||
use crate::spec::BuildSpec;
|
use crate::spec::BuildSpec;
|
||||||
use yaml_rust2::{Yaml, YamlLoader};
|
use yaml_rust2::{Yaml, YamlLoader};
|
||||||
|
use crate::deserialize::polymorphic_pass_through_spec::deserialize_polymorphic_pass_through;
|
||||||
|
|
||||||
fn deserialize_build_spec(build_spec_name: &str, build_spec: &Yaml) -> BuildSpec {
|
fn deserialize_build_spec(build_spec_name: &str, build_spec: &Yaml) -> BuildSpec {
|
||||||
if build_spec["struct"].is_hash() {
|
if build_spec["struct"].is_hash() {
|
||||||
@ -60,6 +62,11 @@ fn deserialize_build_spec(build_spec_name: &str, build_spec: &Yaml) -> BuildSpec
|
|||||||
build_spec_name,
|
build_spec_name,
|
||||||
&build_spec["polymorphic_enum_loop_build"],
|
&build_spec["polymorphic_enum_loop_build"],
|
||||||
))
|
))
|
||||||
|
} else if build_spec["polymorphic_pass_through"].is_hash() {
|
||||||
|
BuildSpec::PolymorphicPassThrough(deserialize_polymorphic_pass_through(
|
||||||
|
build_spec_name,
|
||||||
|
&build_spec["polymorphic_pass_through"],
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
panic!("Missing or incorrect build type for {}", build_spec_name);
|
panic!("Missing or incorrect build type for {}", build_spec_name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,30 @@
|
|||||||
|
use crate::deserialize::util::unwrap_single_member_hash;
|
||||||
|
use crate::spec::polymorphic_pass_through_spec::{PolymorphicPassThroughBuildSpec, PolymorphicPassThroughVariant};
|
||||||
|
use yaml_rust2::Yaml;
|
||||||
|
|
||||||
|
pub fn deserialize_polymorphic_pass_through(name: &str, props: &Yaml) -> PolymorphicPassThroughBuildSpec {
|
||||||
|
let build_kind = props["build"]["kind"].as_str().unwrap();
|
||||||
|
let variants = props["variants"].as_vec().unwrap()
|
||||||
|
.iter()
|
||||||
|
.map(|variant_yaml| {
|
||||||
|
let (variant_name, variant_props) = unwrap_single_member_hash(variant_yaml);
|
||||||
|
if variant_props["inner"].is_hash() {
|
||||||
|
let inner_kind = variant_props["inner"]["kind"].as_str().unwrap();
|
||||||
|
PolymorphicPassThroughVariant::Inner {
|
||||||
|
name: variant_name,
|
||||||
|
kind: inner_kind.to_string(),
|
||||||
|
}
|
||||||
|
} else if variant_props["pass_through"].is_hash() {
|
||||||
|
let pass_through_kind = variant_props["pass_through"]["kind"].is_hash();
|
||||||
|
PolymorphicPassThroughVariant::PassThrough {
|
||||||
|
name: variant_name,
|
||||||
|
kind: pass_through_kind.to_string(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(Box::new)
|
||||||
|
.collect();
|
||||||
|
PolymorphicPassThroughBuildSpec::new(name, build_kind, variants)
|
||||||
|
}
|
||||||
@ -1,16 +1,18 @@
|
|||||||
use crate::spec::node_production_spec::NodeProductionBuildSpec;
|
use crate::spec::node_production_spec::NodeProductionBuildSpec;
|
||||||
|
use crate::spec::polymorphic_enum_loop_spec::PolymorphicEnumLoopBuildSpec;
|
||||||
use leaf_enum_spec::LeafEnumBuildSpec;
|
use leaf_enum_spec::LeafEnumBuildSpec;
|
||||||
use leaf_struct_spec::LeafStructBuildSpec;
|
use leaf_struct_spec::LeafStructBuildSpec;
|
||||||
use polymorphic_type_spec::PolymorphicTypeBuildSpec;
|
use polymorphic_type_spec::PolymorphicTypeBuildSpec;
|
||||||
use production_spec::ProductionBuildSpec;
|
use production_spec::ProductionBuildSpec;
|
||||||
use struct_spec::StructSpec;
|
use struct_spec::StructSpec;
|
||||||
use tree_enum_spec::TreeEnumBuildSpec;
|
use tree_enum_spec::TreeEnumBuildSpec;
|
||||||
use crate::spec::polymorphic_enum_loop_spec::PolymorphicEnumLoopBuildSpec;
|
use crate::spec::polymorphic_pass_through_spec::PolymorphicPassThroughBuildSpec;
|
||||||
|
|
||||||
pub(crate) mod leaf_enum_spec;
|
pub(crate) mod leaf_enum_spec;
|
||||||
pub(crate) mod leaf_struct_spec;
|
pub(crate) mod leaf_struct_spec;
|
||||||
pub(crate) mod node_production_spec;
|
pub(crate) mod node_production_spec;
|
||||||
pub(crate) mod polymorphic_enum_loop_spec;
|
pub(crate) mod polymorphic_enum_loop_spec;
|
||||||
|
pub(crate) mod polymorphic_pass_through_spec;
|
||||||
pub(crate) mod polymorphic_type_spec;
|
pub(crate) mod polymorphic_type_spec;
|
||||||
pub(crate) mod production_spec;
|
pub(crate) mod production_spec;
|
||||||
pub(crate) mod struct_spec;
|
pub(crate) mod struct_spec;
|
||||||
@ -25,4 +27,5 @@ pub enum BuildSpec {
|
|||||||
NodeProduction(NodeProductionBuildSpec),
|
NodeProduction(NodeProductionBuildSpec),
|
||||||
PolymorphicType(PolymorphicTypeBuildSpec),
|
PolymorphicType(PolymorphicTypeBuildSpec),
|
||||||
PolymorphicEnumLoop(PolymorphicEnumLoopBuildSpec),
|
PolymorphicEnumLoop(PolymorphicEnumLoopBuildSpec),
|
||||||
|
PolymorphicPassThrough(PolymorphicPassThroughBuildSpec)
|
||||||
}
|
}
|
||||||
|
|||||||
36
ast-generator/src/spec/polymorphic_pass_through_spec.rs
Normal file
36
ast-generator/src/spec/polymorphic_pass_through_spec.rs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
pub struct PolymorphicPassThroughBuildSpec {
|
||||||
|
name: String,
|
||||||
|
build_kind: String,
|
||||||
|
variants: Vec<Box<PolymorphicPassThroughVariant>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PolymorphicPassThroughBuildSpec {
|
||||||
|
pub fn new(
|
||||||
|
name: &str,
|
||||||
|
build_kind: &str,
|
||||||
|
variants: Vec<Box<PolymorphicPassThroughVariant>>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
build_kind: build_kind.to_string(),
|
||||||
|
variants,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_kind(&self) -> &str {
|
||||||
|
&self.build_kind
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variants(&self) -> impl Iterator<Item = &PolymorphicPassThroughVariant> {
|
||||||
|
self.variants.iter().map(Box::as_ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum PolymorphicPassThroughVariant {
|
||||||
|
Inner { name: String, kind: String },
|
||||||
|
PassThrough { name: String, kind: String },
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user