regenerate.rs 2.7 KB

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