mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-11-05 04:51:40 +03:00
Refactor warnings
This commit is contained in:
parent
9f5a9b5df6
commit
02435adf44
101
src/lib.rs
101
src/lib.rs
@ -98,20 +98,21 @@ pub fn run_book(
|
||||
parallel: bool,
|
||||
debug: bool,
|
||||
linear: bool,
|
||||
fatal_warnings: bool,
|
||||
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 fatal_warnings {
|
||||
return Err(format!("{warnings}\nCould not run the code because of the previous warnings"));
|
||||
} else {
|
||||
eprintln!("{warnings}");
|
||||
}
|
||||
let warns = warning_opts.filter(&warnings, WarnState::Warn);
|
||||
if !warns.is_empty() {
|
||||
let warns = warns.iter().join("\n");
|
||||
eprintln!("{}", format!("Warnings:\n{warns}"));
|
||||
}
|
||||
|
||||
let denies = warning_opts.filter(&warnings, WarnState::Deny);
|
||||
if !denies.is_empty() {
|
||||
let denies = denies.iter().join("\n");
|
||||
return Err(format!("{denies}\nCould not run the code because of the previous warnings"));
|
||||
}
|
||||
|
||||
fn debug_hook(net: &Net, book: &Book, hvmc_names: &HvmcNames, labels: &Labels, linear: bool) {
|
||||
@ -244,51 +245,69 @@ impl Opts {
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct WarningOpts {
|
||||
pub match_only_vars: bool,
|
||||
pub unused_defs: bool,
|
||||
pub match_only_vars: WarnState,
|
||||
pub unused_defs: WarnState,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum WarnState {
|
||||
#[default]
|
||||
Warn,
|
||||
Allow,
|
||||
Deny,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
pub enum WarningArgs {
|
||||
All,
|
||||
UnusedDefs,
|
||||
MatchOnlyVars,
|
||||
}
|
||||
|
||||
impl WarningOpts {
|
||||
pub fn all() -> Self {
|
||||
Self { match_only_vars: true, unused_defs: true }
|
||||
pub fn deny_all() -> Self {
|
||||
Self { match_only_vars: WarnState::Deny, unused_defs: WarnState::Deny }
|
||||
}
|
||||
|
||||
fn iter_vals(&mut self, values: Vec<String>, all: Self, switch: bool) -> Result<(), String> {
|
||||
for value in values {
|
||||
match value.as_ref() {
|
||||
"all" => *self = all,
|
||||
"unused-defs" => self.unused_defs = switch,
|
||||
"match-only-vars" => self.match_only_vars = switch,
|
||||
other => return Err(format!("Unknown option '{other}'.")),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
pub fn allow_all() -> Self {
|
||||
Self { match_only_vars: WarnState::Allow, unused_defs: WarnState::Allow }
|
||||
}
|
||||
|
||||
// TODO(refactor): this kind of code does not look good
|
||||
pub fn deny(&mut self, values: Vec<String>) -> Result<(), String> {
|
||||
self.iter_vals(values, Self::all(), true)
|
||||
fn iter_vals(&mut self, values: Vec<WarningArgs>, all: Self, switch: WarnState) -> Result<(), String> {
|
||||
for value in values {
|
||||
match value {
|
||||
WarningArgs::All => *self = all,
|
||||
WarningArgs::UnusedDefs => self.unused_defs = switch,
|
||||
WarningArgs::MatchOnlyVars => self.match_only_vars = switch,
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn allow(&mut self, values: Vec<String>) -> Result<(), String> {
|
||||
self.iter_vals(values, Self::default(), false)
|
||||
pub fn allow(&mut self, values: Vec<WarningArgs>) -> Result<(), String> {
|
||||
self.iter_vals(values, Self::allow_all(), WarnState::Allow)
|
||||
}
|
||||
|
||||
pub fn warn(&mut self, values: Vec<WarningArgs>) -> Result<(), String> {
|
||||
self.iter_vals(values, Self::default(), WarnState::Warn)
|
||||
}
|
||||
|
||||
pub fn deny(&mut self, values: Vec<WarningArgs>) -> Result<(), String> {
|
||||
self.iter_vals(values, Self::deny_all(), WarnState::Deny)
|
||||
}
|
||||
|
||||
/// Filters warnings based on the enabled flags.
|
||||
pub fn filter(&self, wrns: Vec<Warning>) -> Vec<Warning> {
|
||||
wrns.into_iter().filter(|w| self.is_warning_enabled(w)).collect_vec()
|
||||
}
|
||||
|
||||
pub fn is_warning_enabled(&self, w: &Warning) -> bool {
|
||||
!self.is_warning_denied(w)
|
||||
}
|
||||
|
||||
pub fn is_warning_denied(&self, w: &Warning) -> bool {
|
||||
match w {
|
||||
Warning::MatchOnlyVars { .. } => self.match_only_vars,
|
||||
Warning::UnusedDefinition { .. } => self.unused_defs,
|
||||
}
|
||||
pub fn filter<'a>(&'a self, wrns: &'a Vec<Warning>, ws: WarnState) -> Vec<&Warning> {
|
||||
wrns
|
||||
.into_iter()
|
||||
.filter(|w| {
|
||||
(match w {
|
||||
Warning::MatchOnlyVars { .. } => self.match_only_vars,
|
||||
Warning::UnusedDefinition { .. } => self.unused_defs,
|
||||
}) == ws
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
36
src/main.rs
36
src/main.rs
@ -15,6 +15,16 @@ struct Args {
|
||||
#[arg(short, long)]
|
||||
pub verbose: bool,
|
||||
|
||||
#[arg(
|
||||
short = 'W',
|
||||
long = "warn",
|
||||
value_delimiter = ' ',
|
||||
action = clap::ArgAction::Append,
|
||||
long_help = r#"Show compilation warnings
|
||||
all, unused-defs, match-only-vars"#
|
||||
)]
|
||||
pub warns: Vec<hvml::WarningArgs>,
|
||||
|
||||
#[arg(
|
||||
short = 'D',
|
||||
long = "deny",
|
||||
@ -23,7 +33,7 @@ struct Args {
|
||||
long_help = r#"Deny compilation warnings
|
||||
all, unused-defs, match-only-vars"#
|
||||
)]
|
||||
pub deny_warnings: Vec<String>,
|
||||
pub denies: Vec<hvml::WarningArgs>,
|
||||
|
||||
#[arg(
|
||||
short = 'A',
|
||||
@ -33,7 +43,7 @@ struct Args {
|
||||
long_help = r#"Allow compilation warnings
|
||||
all, unused-defs, match-only-vars"#
|
||||
)]
|
||||
pub allow_warnings: Vec<String>,
|
||||
pub allows: Vec<hvml::WarningArgs>,
|
||||
|
||||
#[arg(long, help = "Stops if any warning was produced")]
|
||||
pub fatal_warnings: bool,
|
||||
@ -101,9 +111,11 @@ 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::deny(&mut warning_opts, args.deny_warnings)?;
|
||||
WarningOpts::allow(&mut warning_opts, args.allow_warnings)?;
|
||||
WarningOpts::allow(&mut warning_opts, args.allows)?;
|
||||
WarningOpts::deny(&mut warning_opts, args.denies)?;
|
||||
WarningOpts::warn(&mut warning_opts, args.warns)?;
|
||||
|
||||
let mut book = load_file_to_book(&args.path)?;
|
||||
if args.verbose {
|
||||
@ -111,9 +123,7 @@ fn main() {
|
||||
}
|
||||
|
||||
match args.mode {
|
||||
Mode::Check => {
|
||||
check_book(book)?;
|
||||
}
|
||||
Mode::Check => check_book(book)?,
|
||||
Mode::Compile => {
|
||||
let compiled = compile_book(&mut book, opts)?;
|
||||
|
||||
@ -129,16 +139,8 @@ 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.fatal_warnings,
|
||||
warning_opts,
|
||||
opts,
|
||||
)?;
|
||||
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;
|
||||
|
@ -1,12 +1,16 @@
|
||||
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, WarningOpts
|
||||
},
|
||||
Opts, WarningOpts,
|
||||
};
|
||||
use insta::assert_snapshot;
|
||||
use itertools::Itertools;
|
||||
@ -112,7 +116,8 @@ 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, true, WarningOpts::default(), Opts::heavy())?;
|
||||
let (res, def_names, info) =
|
||||
run_book(book, 1 << 20, true, false, false, WarningOpts::deny_all(), Opts::heavy())?;
|
||||
Ok(format!("{}{}", info.readback_errors.display(&def_names), res.display(&def_names)))
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user