regenerate.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. use matzo::grammar;
  2. use matzo::lexer;
  3. use matzo::interp;
  4. use std::collections::BTreeMap;
  5. use std::io::Write;
  6. const MAX_RUN_EXPECTATIONS: u64 = 64;
  7. fn generate_runs(source: &str) -> Result<BTreeMap<String, String>, Box<dyn std::error::Error>> {
  8. let mut found_results: BTreeMap<String, u64> = BTreeMap::new();
  9. for seed in 0..MAX_RUN_EXPECTATIONS {
  10. let state = interp::State::new_from_seed(seed);
  11. let mut out = Vec::new();
  12. state.run_with_writer(source, &mut out)?;
  13. let out = std::str::from_utf8(&out).unwrap().trim().to_string();
  14. if !found_results.contains_key(&out) {
  15. let _ = found_results.insert(out, seed);
  16. }
  17. }
  18. let output = found_results.into_iter().map(|(k, v)| (format!("{}", v), k)).collect();
  19. Ok(output)
  20. }
  21. fn main() -> Result<(), Box<dyn std::error::Error>> {
  22. for exp in std::fs::read_dir("tests")? {
  23. let exp = exp?.path().canonicalize()?;
  24. let fname = exp.file_name().ok_or("bad file name")?.to_string_lossy();
  25. if let Some(prefix) = fname.strip_suffix(".matzo") {
  26. println!("regenerating {}.matzo", prefix);
  27. let exp_filename = |new_suffix| {
  28. let mut f = exp.clone();
  29. f.pop();
  30. f.push(format!("{}.{}", prefix, new_suffix));
  31. f
  32. };
  33. let mut ast = matzo::ast::ASTArena::new();
  34. let src = std::fs::read_to_string(&exp)?;
  35. let tokens = lexer::tokens(&src);
  36. let file = ast.add_file(src.to_string());
  37. if let Ok(stmts) = grammar::StmtsParser::new().parse(&mut ast, file, tokens) {
  38. let mut f = std::fs::File::create(exp_filename("parsed"))?;
  39. for stmt in stmts {
  40. writeln!(f, "{:#?}", stmt.show(&ast))?;
  41. }
  42. }
  43. if let Ok(existing) = std::fs::read_to_string(exp_filename("output")) {
  44. let existing: BTreeMap<String, String> = serde_yaml::from_str(&existing)?;
  45. print!(" generating output for {}: ", fname);
  46. let map = generate_runs(&src)?;
  47. if map != existing {
  48. let mut f = std::fs::File::create(exp_filename("output"))?;
  49. writeln!(f, "# generated for {}", env!("VERGEN_GIT_SHA"))?;
  50. writeln!(f, "{}", serde_yaml::to_string(&map)?)?;
  51. println!("generated {} cases", map.len());
  52. } else {
  53. println!("no changes needed");
  54. }
  55. }
  56. }
  57. }
  58. Ok(())
  59. }