diff --git a/ast-generator/src/lib.rs b/ast-generator/src/lib.rs index 6f5716a..99a98cc 100644 --- a/ast-generator/src/lib.rs +++ b/ast-generator/src/lib.rs @@ -1,5 +1,5 @@ +pub mod deserialize; mod build_fn_gen; -mod deserialize; mod spec; mod type_gen; @@ -9,7 +9,6 @@ use proc_macro2::TokenStream; use quote::quote; use spec::BuildSpec; use syn::File; -use syn::spanned::Spanned; fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) { println!("*** BuildSpec ***"); @@ -26,6 +25,42 @@ fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) { 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) => { quote! {} } + BuildSpec::Struct(struct_build_spec) => { + let struct_build_fn_stream = make_struct_build_fn(struct_build_spec); + debug_built_spec(build_spec, &struct_build_fn_stream); + struct_build_fn_stream + } + } + }) + .collect::>(); + let combined = quote! { + #(#build_fns)* + }; + AstGeneratedFile { + name: String::from("build.rs"), + contents: token_stream_to_string(combined) + } +} + +pub fn generate_files(build_specs: &[BuildSpec]) -> Vec { + vec![generate_build_file(build_specs)] +} + pub fn test_dump() -> String { let build_specs = deserialize::deserialize_yaml_spec(include_str!("../../src/parser/ast.yaml")); let mut streams: Vec = vec![]; diff --git a/build.rs b/build.rs index bdc8fe9..b4e88be 100644 --- a/build.rs +++ b/build.rs @@ -1,17 +1,40 @@ +use ast_generator::{deserialize, generate_files}; use cst_test_generator::generate_test_files; use std::env; use std::fs; +use std::io; use std::path::Path; -fn main() -> std::io::Result<()> { - println!("cargo:rerun-if-changed=src/parser/deimos.pest"); - println!("cargo:rerun-if-changed=src/parser/tests"); - let out_dir = env::var("OUT_DIR").unwrap(); - let out_dir_path = Path::new(&out_dir); - let parser_tests_dir = out_dir_path.join("src").join("parser").join("tests"); +fn generate_parser_tests(out_dir: &Path) -> io::Result<()> { + let parser_tests_dir = out_dir.join("src").join("parser").join("tests"); fs::create_dir_all(&parser_tests_dir)?; let test_suites_file = generate_test_files(Path::new("src/parser/tests"))?; let file_path = parser_tests_dir.join(&test_suites_file.file_name); fs::write(file_path, &test_suites_file.contents)?; Ok(()) } + +fn generate_ast_files(out_dir: &Path) -> io::Result<()> { + let gen_ast_dir = out_dir.join("src").join("ast"); + fs::create_dir_all(&gen_ast_dir)?; + + let ast_yaml = include_str!("src/parser/ast.yaml"); + let build_specs = deserialize::deserialize_yaml_spec(ast_yaml); + let generated_files = generate_files(&build_specs); + for generated_file in &generated_files { + let path = gen_ast_dir.join(&generated_file.name); + fs::write(path, &generated_file.contents)?; + } + Ok(()) +} + +fn main() -> io::Result<()> { + println!("cargo:rerun-if-changed=src/parser/tests"); + println!("cargo:rerun-if-changed=src/parser/ast.yaml"); + println!("cargo:rerun-if-changed=src/parser/deimos.pest"); + let out_dir = env::var_os("OUT_DIR").unwrap(); + let out_dir_path = Path::new(&out_dir); + generate_parser_tests(out_dir_path)?; + generate_ast_files(out_dir_path)?; + Ok(()) +} diff --git a/src/ast/build.rs b/src/ast/build.rs new file mode 100644 index 0000000..4be5b6a --- /dev/null +++ b/src/ast/build.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs")); diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 5a22d93..9636c8b 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1,4 +1,4 @@ -// pub mod build; +pub mod build; pub mod children; pub mod node; pub mod pretty_print;