extern crate lalrpop; use std::env; use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; fn main() { lalrpop::process_root().unwrap(); if let Err(e) = generate_example_tests() { eprintln!("Failure building example tests: {}", e); std::process::exit(3); } } fn generate_example_tests() -> std::io::Result<()> { let out_dir = env::var_os("OUT_DIR").expect("OUT_DIR"); let dest_path = Path::new(&out_dir).join("examples.rs"); let mut output = File::create(dest_path)?; generate_tests(&mut output, PathBuf::from("examples"))?; println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=example.rs"); Ok(()) } fn generate_tests(f: &mut File, path_so_far: PathBuf) -> std::io::Result<()> { for entry in fs::read_dir(path_so_far)? { let entry = entry?; let file_name = entry .file_name() .into_string() .expect("reasonable file name"); let name = file_name.trim_end_matches(".ngr"); if entry.file_type()?.is_dir() { writeln!(f, "mod {} {{", name)?; writeln!(f, " use super::*;")?; generate_tests(f, entry.path())?; writeln!(f, "}}")?; } else { writeln!(f, "#[test]")?; writeln!(f, "fn {}() {{", name)?; writeln!(f, " let mut file_database = SimpleFiles::new();")?; writeln!( f, " let syntax = Syntax::parse_file(&mut file_database, {:?});", entry.path().display() )?; if entry.path().to_string_lossy().contains("broken") { writeln!(f, " if syntax.is_err() {{")?; writeln!(f, " return;")?; writeln!(f, " }}")?; writeln!(f, " let (errors, _) = syntax.unwrap().validate();")?; writeln!( f, " assert_ne!(errors.len(), 0, \"should have seen an error\");" )?; } else { writeln!( f, " let syntax = syntax.expect(\"file should have parsed\");" )?; writeln!(f, " let (errors, _) = syntax.validate();")?; writeln!( f, " assert_eq!(errors.len(), 0, \"file should have no validation errors\");" )?; writeln!(f, " let syntax_result = syntax.eval();")?; writeln!(f, " let ir = IR::from(syntax);")?; writeln!( f, " assert_eq!(syntax_result, ir.eval(), \"syntax equivalent to IR\");" )?; writeln!(f, " let compiled_result = Backend::::eval(ir);")?; writeln!(f, " assert_eq!(syntax_result, compiled_result);")?; } writeln!(f, "}}")?; } } Ok(()) }