Repository: HigherOrderCO/Bend
File: src/lib.rs (Rust)

Code before:
  book.check_unbound_pats()?;
  book.flatten_rules();
  book.resolve_refs();
  book.simplify_matches()?;
  let def_types = book.infer_def_types()?;
  book.check_exhaustive_patterns(&def_types)?;
  book.encode_pattern_matching_functions(&def_types);
  book.check_unbound_vars()?;
  book.make_var_names_unique();
  book.linearize_vars();
  book.eta_reduction();
  book.detach_supercombinators();
  book.simplify_ref_to_ref()?;
  book.prune(main);
  Ok(main)
}

fn debug_hook(net: &Net, book: &Book, hvmc_names: &HvmcNames, labels: &Labels, linear: bool) {
  let net = hvmc_to_net(net, &|id| hvmc_names.hvmc_name_to_id[&id]);
  let (res_term, errors) = net_to_term(&net, book, labels, linear);
  println!(
    "{}{}\n---------------------------------------",
    if errors.is_empty() { "".to_string() } else { format!("Invalid readback: {:?}\n", errors) },
    res_term.display(&book.def_names)
  );
}

pub struct RunInfo {
  pub stats: RunStats,
  pub readback_errors: Vec<ReadbackError>,
  pub net: Net,
}

pub struct RunStats {
  pub rewrites: Rewrites,
  pub used: usize,
  pub run_time: f64,
}

pub fn total_rewrites(rwrts: &Rewrites) -> usize {
  rwrts.anni + rwrts.comm + rwrts.eras + rwrts.dref + rwrts.oper
}


Review comment (bug):
I remember a case where a recursive rule with native number matching was not working properly without the eta_reduction active. I don't know if it was a bug that got fixed or the issue still persists. So, something to keep in mind if that happens again.

Code after:

  let debug_hook =
    if debug { Some(|net: &_| debug_hook(net, &book, &hvmc_names, &labels, linear)) } else { None };
  let (res_lnet, stats) = run_compiled(&core_book, mem_size, parallel, debug_hook);
  let net = hvmc_to_net(&res_lnet, &|id| hvmc_names.hvmc_name_to_id[&id]);
  let (res_term, readback_errors) = net_to_term(&net, &book, &labels, linear);
  let info = RunInfo { stats, readback_errors, net: res_lnet };
  Ok((res_term, book.def_names, info))
}

pub fn desugar_book(book: &mut Book, opt_level: OptimizationLevel) -> Result<DefId, String> {
  let main = book.check_has_main()?;
  book.check_shared_names()?;
  book.resolve_ctrs_in_pats();
  book.generate_scott_adts();
  book.check_unbound_pats()?;
  book.flatten_rules();
  book.resolve_refs();
  book.simplify_matches()?;
  let def_types = book.infer_def_types()?;
  book.check_exhaustive_patterns(&def_types)?;
  book.encode_pattern_matching_functions(&def_types);
  book.check_unbound_vars()?;
  book.make_var_names_unique();
  book.linearize_vars();
  if opt_level >= OptimizationLevel::Heavy {
    book.eta_reduction();
  }
  book.detach_supercombinators();
  book.simplify_ref_to_ref()?;
  book.prune(main);
  Ok(main)
}

fn debug_hook(net: &Net, book: &Book, hvmc_names: &HvmcNames, labels: &Labels, linear: bool) {
  let net = hvmc_to_net(net, &|id| hvmc_names.hvmc_name_to_id[&id]);
  let (res_term, errors) = net_to_term(&net, book, labels, linear);
  println!(
    "{}{}\n---------------------------------------",
    if errors.is_empty() { "".to_string() } else { format!("Invalid readback: {:?}\n", errors) },
    res_term.display(&book.def_names)
  );
}

pub struct RunInfo {
  pub stats: RunStats,
  pub readback_errors: Vec<ReadbackError>,
  pub net: Net,
}

pub struct RunStats {