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

Code before:
    None => return Err("Mem size argument is empty".to_string()),
    Some('k') => (&arg[0 .. arg.len() - 1], 1 << 10),
    Some('m') => (&arg[0 .. arg.len() - 1], 1 << 20),
    Some('g') => (&arg[0 .. arg.len() - 1], 1 << 30),
    Some(_) => (arg, 1),
  };
  let base = base.parse::<usize>().map_err(|e| e.to_string())?;
  Ok(base * mult)
}

fn main() {
  fn run() -> Result<(), String> {
    #[cfg(not(feature = "cli"))]
    compile_error!("The 'cli' feature is needed for the hvm-lang cli");

    let args = Args::parse();
    let mut opts = Opts::light();
    Opts::from_vec(&mut opts, args.opts)?;

    let mut warning_opts = WarningOpts::default();
    let argm = Args::command().get_matches();
    let wopts_id_seq = argm.get_many::<clap::Id>("WOpts").unwrap().collect::<Vec<_>>();
    let allows = &mut args.wopts.allows.into_iter();
    let denies = &mut args.wopts.denies.into_iter();
    let warns = &mut args.wopts.warns.into_iter();
    WarningOpts::go(&mut warning_opts, wopts_id_seq, allows, denies, warns);

    let mut book = load_file_to_book(&args.path)?;
    if args.verbose {
      println!("{book:?}");
    }

    match args.mode {
      Mode::Check => check_book(book)?,
      Mode::Compile => {
        let compiled = compile_book(&mut book, opts)?;

        for warn in &compiled.warnings {
          eprintln!("WARNING: {warn}");
        }

        print!("{}", show_book(&compiled.core_book));
      }
      Mode::Desugar => {
        desugar_book(&mut book, opts)?;
        println!("{book}");
      }
      Mode::Run => {
        let mem_size = args.mem / std::mem::size_of::<(hvmc::run::APtr, hvmc::run::APtr)>();
        let (res_term, def_names, info) =
          run_book(book, mem_size, !args.single_core, args.debug, args.linear, warning_opts, opts)?;

Review comment (suggestion):
Can you push this stuff inside this function and rename it something like `from_cli_opts`.
```
WarningOpts::from_cli_opts(wopts: WOpts, wopts_id_seq: Vec<clap::Id>) -> Self {
 ...
}
```

Code after:

    let args = Args::parse();
    let mut opts = Opts::light();
    Opts::from_vec(&mut opts, args.opts)?;
    let warning_opts = args.wopts.get_warning_opts();

    let mut book = load_file_to_book(&args.path)?;
    if args.verbose {
      println!("{book:?}");
    }

    match args.mode {
      Mode::Check => check_book(book)?,
      Mode::Compile => {
        let compiled = compile_book(&mut book, opts)?;

        for warn in &compiled.warnings {
          eprintln!("WARNING: {warn}");
        }

        print!("{}", show_book(&compiled.core_book));
      }
      Mode::Desugar => {
        desugar_book(&mut book, opts)?;
        println!("{book}");
      }
      Mode::Run => {
        let mem_size = args.mem / std::mem::size_of::<(hvmc::run::APtr, hvmc::run::APtr)>();
        let (res_term, def_names, info) =
          run_book(book, mem_size, !args.single_core, args.debug, args.linear, warning_opts, opts)?;
        let RunInfo { stats, readback_errors, net: lnet } = info;
        let total_rewrites = total_rewrites(&stats.rewrites) as f64;
        let rps = total_rewrites / stats.run_time / 1_000_000.0;
        if args.verbose {
          println!("\n{}", show_net(&lnet));
        }

        println!("{}{}", readback_errors.display(&def_names), res_term.display(&def_names));

        if args.stats {
          println!("\nRWTS   : {}", total_rewrites);
          println!("- ANNI : {}", stats.rewrites.anni);
          println!("- COMM : {}", stats.rewrites.comm);
          println!("- ERAS : {}", stats.rewrites.eras);
          println!("- DREF : {}", stats.rewrites.dref);
          println!("- OPER : {}", stats.rewrites.oper);
          println!("TIME   : {:.3} s", stats.run_time);
          println!("RPS    : {:.3} m", rps);
        }
      }
    }