deimos-lang/ast-generator/src/lib.rs

119 lines
3.8 KiB
Rust

pub mod deserialize;
mod enum_build_fn;
mod leaf_enum_build_fn;
mod leaf_struct_build_fn;
mod production_build_fn;
mod spec;
mod struct_build_fn;
mod type_gen;
mod util;
use crate::enum_build_fn::make_enum_build_fn;
use crate::leaf_enum_build_fn::make_leaf_enum_build_fn;
use crate::leaf_struct_build_fn::make_leaf_struct_build_fn;
use crate::production_build_fn::make_production_build_fn;
use crate::struct_build_fn::make_struct_build_fn;
use crate::type_gen::make_type;
use proc_macro2::TokenStream;
use quote::quote;
use spec::BuildSpec;
use syn::File;
fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) {
println!("*** BuildSpec ***");
match build_spec {
BuildSpec::Enum(enum_build_spec) => {
println!("Enum Spec - build: {}", enum_build_spec.build());
}
BuildSpec::LeafEnum(leaf_enum_build_spec) => {
println!("Leaf Enum Spec - build: {}", leaf_enum_build_spec.build());
}
BuildSpec::Struct(struct_build_spec) => {
println!("Struct Spec - build: {}", struct_build_spec.build());
}
BuildSpec::LeafStruct(leaf_struct_build_spec) => {
println!(
"Leaf Struct Spec - build: {}",
leaf_struct_build_spec.build()
);
}
BuildSpec::Production(production_build_spec) => {
println!("Production Spec - rule: {}", production_build_spec.rule())
}
}
println!("{:#?}", token_stream);
let parsed: File = syn::parse2(token_stream.clone()).unwrap();
println!("{}", prettyplease::unparse(&parsed));
}
pub struct AstGeneratedFile {
pub name: String,
pub contents: String,
}
fn token_stream_to_string(token_stream: TokenStream) -> String {
let file: File = syn::parse2(token_stream).unwrap();
prettyplease::unparse(&file)
}
fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
let build_fns = build_specs
.iter()
.map(|build_spec| match build_spec {
BuildSpec::Enum(enum_build_spec) => {
let stream = make_enum_build_fn(enum_build_spec);
debug_built_spec(build_spec, &stream);
stream
}
BuildSpec::LeafEnum(leaf_enum_build_spec) => {
let stream = make_leaf_enum_build_fn(leaf_enum_build_spec);
debug_built_spec(build_spec, &stream);
stream
}
BuildSpec::Struct(struct_build_spec) => {
let stream = make_struct_build_fn(struct_build_spec);
debug_built_spec(build_spec, &stream);
stream
}
BuildSpec::LeafStruct(leaf_struct_build_spec) => {
let stream = make_leaf_struct_build_fn(leaf_struct_build_spec);
debug_built_spec(build_spec, &stream);
stream
}
BuildSpec::Production(production_build_spec) => {
let stream = make_production_build_fn(production_build_spec);
debug_built_spec(build_spec, &stream);
stream
}
})
.collect::<Vec<_>>();
let combined = quote! {
#(#build_fns)*
};
AstGeneratedFile {
name: String::from("build.rs"),
contents: token_stream_to_string(combined),
}
}
fn generate_node_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
let types = build_specs
.iter()
.map(|build_spec| make_type(build_spec))
.collect::<Vec<_>>();
let combined = quote! {
#(#types)*
};
AstGeneratedFile {
name: String::from("node.rs"),
contents: token_stream_to_string(combined),
}
}
pub fn generate_files(build_specs: &[BuildSpec]) -> Vec<AstGeneratedFile> {
vec![
generate_build_file(build_specs),
generate_node_file(build_specs),
]
}