Add cli warnings option

This commit is contained in:
imaqtkatt 2024-01-29 16:29:39 -03:00
parent c47767ca39
commit 4761aabe2e
3 changed files with 88 additions and 18 deletions

View File

@ -98,17 +98,25 @@ pub fn run_book(
parallel: bool,
debug: bool,
linear: bool,
skip_warnings: bool,
errors: bool,
mut warning_opts: WarningOpts,
opts: Opts,
) -> Result<(Term, DefNames, RunInfo), String> {
let CompileResult { core_book, hvmc_names, labels, warnings } = compile_book(&mut book, opts)?;
let warnings = warning_opts.filter(warnings);
if !warnings.is_empty() {
let warnings = warnings.iter().join("\n");
if !skip_warnings {
return Err(format!("{warnings}\nCould not run the code because of the previous warnings"));
} else {
eprintln!("{warnings}");
// if both enabled, ignore the all option
if warning_opts.all && errors {
warning_opts.all = false;
}
if !warning_opts.all {
if !warnings.is_empty() {
let warnings = warnings.iter().join("\n");
if errors {
return Err(format!("{warnings}\nCould not run the code because of the previous warnings"));
} else {
eprintln!("{warnings}");
}
}
}
@ -240,6 +248,52 @@ impl Opts {
}
}
#[derive(Default)]
pub struct WarningOpts {
pub all: bool,
pub match_only_vars: bool,
pub unused_defs: bool,
}
impl WarningOpts {
pub fn all() -> Self {
Self { all: true, match_only_vars: true, unused_defs: true }
}
// TODO(refactor): this kind of code does not look good
pub fn from_vec(&mut self, values: Vec<String>) -> Result<(), String> {
for value in values {
match value.as_ref() {
"all" => self.all = true,
"unused-defs" => self.unused_defs = true,
"mach-only-vars" => self.match_only_vars = true,
other => return Err(format!("Unknown option '{other}'.")),
}
}
Ok(())
}
/// Removes warnings based on the enabled flags.
pub fn filter(&self, wrns: Vec<Warning>) -> Vec<Warning> {
if self.all {
// return the vec in case of the --errors flag be enabled
return wrns;
};
wrns
.into_iter()
.filter(|w| {
if self.match_only_vars {
!matches!(w, Warning::MatchOnlyVars { .. })
} else if self.unused_defs {
!matches!(w, Warning::UnusedDefinition { .. })
} else {
true
}
})
.collect_vec()
}
}
pub struct CompileResult {
pub core_book: hvmc::ast::Book,
pub hvmc_names: HvmcNames,

View File

@ -2,6 +2,7 @@ use clap::{Parser, ValueEnum};
use hvmc::ast::{show_book, show_net};
use hvml::{
check_book, compile_book, desugar_book, load_file_to_book, run_book, total_rewrites, Opts, RunInfo,
WarningOpts,
};
use std::path::PathBuf;
@ -14,8 +15,17 @@ struct Args {
#[arg(short, long)]
pub verbose: bool,
#[arg(short = 'w', help = "Skip compilation warnings")]
pub skip_warnings: bool,
#[arg(
short = 'W',
value_delimiter = ' ',
action = clap::ArgAction::Append,
long_help = r#"Skip compilation warnings
all, unused-defs, match-only-vars"#
)]
pub skip_warnings: Vec<String>,
#[arg(long, help = "Stops if any warning was produced")]
pub errors: bool,
#[arg(short, long, help = "Shows runtime stats and rewrite counts")]
pub stats: bool,
@ -80,6 +90,8 @@ fn main() {
let args = Args::parse();
let mut opts = Opts::light();
Opts::from_vec(&mut opts, args.opts)?;
let mut warning_opts = WarningOpts::default();
WarningOpts::from_vec(&mut warning_opts, args.skip_warnings)?;
let mut book = load_file_to_book(&args.path)?;
if args.verbose {
@ -105,8 +117,16 @@ fn main() {
}
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, args.skip_warnings, opts)?;
let (res_term, def_names, info) = run_book(
book,
mem_size,
!args.single_core,
args.debug,
args.linear,
args.errors,
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;

View File

@ -1,16 +1,12 @@
use hvmc::ast::{parse_net, show_net};
use hvml::{
compile_book, encode_pattern_matching,
net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::net_to_hvmc},
run_book,
term::{
compile_book, encode_pattern_matching, net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::net_to_hvmc}, run_book, term::{
net_to_term::net_to_term,
parser::{parse_definition_book, parse_term, parser::error_to_msg},
term_to_compat_net,
transform::{encode_lists::BuiltinList, encode_strs::BuiltinString},
Book, DefId, Term,
},
Opts,
}, Opts, WarningOpts
};
use insta::assert_snapshot;
use itertools::Itertools;
@ -116,7 +112,7 @@ fn run_file() {
run_golden_test_dir(function_name!(), &|code| {
let book = do_parse_book(code)?;
// 1 million nodes for the test runtime. Smaller doesn't seem to make it any faster
let (res, def_names, info) = run_book(book, 1 << 20, true, false, false, false, Opts::heavy())?;
let (res, def_names, info) = run_book(book, 1 << 20, true, false, false, true, WarningOpts::default(), Opts::heavy())?;
Ok(format!("{}{}", info.readback_errors.display(&def_names), res.display(&def_names)))
})
}