WIP ast node ref enum and AstNode impls.
This commit is contained in:
parent
6e37e3a5dd
commit
df8e2279dc
6
ast-generator/src/ast_node/enum_ast_node.rs
Normal file
6
ast-generator/src/ast_node/enum_ast_node.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use crate::spec::tree_enum_spec::TreeEnumBuildSpec;
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
|
||||||
|
pub fn make_enum_ast_node_impl(enum_spec: &TreeEnumBuildSpec) -> TokenStream {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
6
ast-generator/src/ast_node/leaf_enum_ast_node.rs
Normal file
6
ast-generator/src/ast_node/leaf_enum_ast_node.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use crate::spec::leaf_enum_spec::LeafEnumBuildSpec;
|
||||||
|
|
||||||
|
pub fn make_leaf_enum_ast_node_impl(spec: &LeafEnumBuildSpec) -> TokenStream {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
6
ast-generator/src/ast_node/leaf_struct_ast_node.rs
Normal file
6
ast-generator/src/ast_node/leaf_struct_ast_node.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use crate::spec::leaf_struct_spec::LeafStructBuildSpec;
|
||||||
|
|
||||||
|
pub fn make_leaf_struct_ast_node_impl(spec: &LeafStructBuildSpec) -> TokenStream {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
52
ast-generator/src/ast_node/mod.rs
Normal file
52
ast-generator/src/ast_node/mod.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
mod enum_ast_node;
|
||||||
|
mod leaf_enum_ast_node;
|
||||||
|
mod struct_ast_node;
|
||||||
|
mod leaf_struct_ast_node;
|
||||||
|
mod polymorphic_type_ast_node;
|
||||||
|
mod polymorphic_enum_loop_ast_node;
|
||||||
|
|
||||||
|
use crate::spec::BuildSpec;
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{format_ident, quote};
|
||||||
|
use crate::ast_node::enum_ast_node::make_enum_ast_node_impl;
|
||||||
|
use crate::ast_node::leaf_enum_ast_node::make_leaf_enum_ast_node_impl;
|
||||||
|
use crate::ast_node::leaf_struct_ast_node::make_leaf_struct_ast_node_impl;
|
||||||
|
use crate::ast_node::polymorphic_enum_loop_ast_node::make_polymorphic_enum_loop_ast_node_impl;
|
||||||
|
use crate::ast_node::polymorphic_type_ast_node::make_polymorphic_type_ast_node_impl;
|
||||||
|
use crate::ast_node::struct_ast_node::make_struct_ast_node_impl;
|
||||||
|
|
||||||
|
pub fn make_ast_node_impl(build_spec: &BuildSpec) -> Option<TokenStream> {
|
||||||
|
match build_spec {
|
||||||
|
BuildSpec::Enum(enum_spec) => {
|
||||||
|
Some(make_enum_ast_node_impl(enum_spec))
|
||||||
|
}
|
||||||
|
BuildSpec::LeafEnum(leaf_enum) => {
|
||||||
|
Some(make_leaf_enum_ast_node_impl(leaf_enum))
|
||||||
|
}
|
||||||
|
BuildSpec::Struct(struct_spec) => {
|
||||||
|
Some(make_struct_ast_node_impl(struct_spec))
|
||||||
|
}
|
||||||
|
BuildSpec::LeafStruct(leaf_struct) => {
|
||||||
|
Some(make_leaf_struct_ast_node_impl(leaf_struct))
|
||||||
|
}
|
||||||
|
BuildSpec::Production(_) => None,
|
||||||
|
BuildSpec::NodeProduction(_) => None,
|
||||||
|
BuildSpec::PolymorphicType(polymorphic_type) => {
|
||||||
|
Some(make_polymorphic_type_ast_node_impl(polymorphic_type))
|
||||||
|
}
|
||||||
|
BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop) => {
|
||||||
|
Some(make_polymorphic_enum_loop_ast_node_impl(polymorphic_enum_loop))
|
||||||
|
}
|
||||||
|
BuildSpec::PolymorphicPassThrough(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn make_ast_enum_member(build_spec: &BuildSpec) -> Option<TokenStream> {
|
||||||
|
match build_spec {
|
||||||
|
BuildSpec::Struct(struct_spec) => {
|
||||||
|
let type_ident = format_ident!("{}", struct_spec.build());
|
||||||
|
Some(quote! { #type_ident(#type_ident) })
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use crate::spec::polymorphic_enum_loop_spec::PolymorphicEnumLoopBuildSpec;
|
||||||
|
|
||||||
|
pub fn make_polymorphic_enum_loop_ast_node_impl(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
6
ast-generator/src/ast_node/polymorphic_type_ast_node.rs
Normal file
6
ast-generator/src/ast_node/polymorphic_type_ast_node.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use crate::spec::polymorphic_type_spec::PolymorphicTypeBuildSpec;
|
||||||
|
|
||||||
|
pub fn make_polymorphic_type_ast_node_impl(spec: &PolymorphicTypeBuildSpec) -> TokenStream {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
55
ast-generator/src/ast_node/struct_ast_node.rs
Normal file
55
ast-generator/src/ast_node/struct_ast_node.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use crate::spec::struct_spec::{MemberChildBuild, StructChild, StructSpec, VecChildBuild};
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{format_ident, quote};
|
||||||
|
|
||||||
|
pub fn make_struct_ast_node_impl(spec: &StructSpec) -> TokenStream {
|
||||||
|
let type_ident = format_ident!("{}", spec.build());
|
||||||
|
let child_adders = spec
|
||||||
|
.children()
|
||||||
|
.map(|child| match child {
|
||||||
|
StructChild::SkipChild(_) => None,
|
||||||
|
StructChild::VecChild(vec_child) => {
|
||||||
|
match vec_child.build() {
|
||||||
|
VecChildBuild::String(_) => None,
|
||||||
|
VecChildBuild::Node(_) => {
|
||||||
|
let child_ident = format_ident!("{}", vec_child.name());
|
||||||
|
let children_stream = quote! {
|
||||||
|
for child in self.#child_ident().map(AstNode::as_node_ref).collect() {
|
||||||
|
children.push(child);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(children_stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StructChild::MemberChild(member_child) => {
|
||||||
|
match member_child.build() {
|
||||||
|
MemberChildBuild::Node(_) => {
|
||||||
|
let child_ident = format_ident!("{}", member_child.name());
|
||||||
|
let child_stream = quote! {
|
||||||
|
children.add(self.#child_ident().as_node_ref())
|
||||||
|
};
|
||||||
|
Some(child_stream)
|
||||||
|
}
|
||||||
|
MemberChildBuild::Boolean(_) => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Option::is_some)
|
||||||
|
.map(Option::unwrap)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
impl AstNode for #type_ident {
|
||||||
|
fn children(&self) -> Vec<AstNodeRef> {
|
||||||
|
let children: Vec<AstNodeRef> = vec![];
|
||||||
|
#(#child_adders;)*
|
||||||
|
children
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_node_ref(&self) -> AstNodeRef {
|
||||||
|
AstNodeRef::#type_ident(&self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,11 @@
|
|||||||
|
mod ast_node;
|
||||||
mod build_fn;
|
mod build_fn;
|
||||||
mod deserialize;
|
mod deserialize;
|
||||||
mod pretty_print;
|
mod pretty_print;
|
||||||
mod spec;
|
mod spec;
|
||||||
mod type_gen;
|
mod type_gen;
|
||||||
|
|
||||||
|
use crate::ast_node::{make_ast_enum_member, make_ast_node_impl};
|
||||||
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;
|
||||||
@ -107,7 +109,7 @@ fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let combined = quote! {
|
let combined = quote! {
|
||||||
use std::range::Range;
|
use std::range::Range;
|
||||||
|
|
||||||
#(#types)*
|
#(#types)*
|
||||||
};
|
};
|
||||||
AstGeneratedFile {
|
AstGeneratedFile {
|
||||||
@ -129,7 +131,7 @@ fn generate_pretty_print_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
|||||||
.filter(Option::is_some)
|
.filter(Option::is_some)
|
||||||
.map(Option::unwrap)
|
.map(Option::unwrap)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let combined = quote! {
|
let combined = quote! {
|
||||||
use crate::ast::node::*;
|
use crate::ast::node::*;
|
||||||
#(#impls)*
|
#(#impls)*
|
||||||
@ -140,6 +142,48 @@ fn generate_pretty_print_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_ast_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
||||||
|
let impls = build_specs
|
||||||
|
.iter()
|
||||||
|
.map(|build_spec| {
|
||||||
|
let maybe_stream = make_ast_node_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 ast_enum_members = build_specs
|
||||||
|
.iter()
|
||||||
|
.map(|build_spec| make_ast_enum_member(build_spec))
|
||||||
|
.filter(Option::is_some)
|
||||||
|
.map(Option::unwrap)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let combined = quote! {
|
||||||
|
use crate::ast::node::*;
|
||||||
|
|
||||||
|
pub enum AstNodeRef {
|
||||||
|
#(#ast_enum_members,)*
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AstNode {
|
||||||
|
fn children(&self) -> Vec<AstNodeRef>;
|
||||||
|
|
||||||
|
fn as_node_ref(&self) -> AstNodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#(#impls)*
|
||||||
|
};
|
||||||
|
AstGeneratedFile {
|
||||||
|
name: String::from("ast_node.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> {
|
||||||
deserialize_yaml_spec(yaml)
|
deserialize_yaml_spec(yaml)
|
||||||
}
|
}
|
||||||
@ -149,5 +193,6 @@ pub fn generate_files(build_specs: &[BuildSpec]) -> Vec<AstGeneratedFile> {
|
|||||||
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),
|
||||||
|
generate_ast_node_file(build_specs),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,3 +141,23 @@ pub mod pretty_print {
|
|||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/src/ast/pretty_print.rs"));
|
include!(concat!(env!("OUT_DIR"), "/src/ast/pretty_print.rs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod ast_node {
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/src/ast/ast_node.rs"));
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::ast::ast_node::AstNode;
|
||||||
|
use crate::ast::node::CompilationUnit;
|
||||||
|
|
||||||
|
fn get_cu() -> CompilationUnit {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple() {
|
||||||
|
let cu = get_cu();
|
||||||
|
for child in cu.children() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user