From 0185d8f0e52ebc074c3420654108f4873f998816 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 10:54:11 -0300 Subject: [PATCH 1/9] WIP add arguments option --- Cargo.lock | 52 ++++++++++++++++---------------- src/lib.rs | 29 +++++++++++------- src/main.rs | 12 ++++++-- src/net/net_to_hvmc.rs | 10 ++++-- src/term/check/set_entrypoint.rs | 4 +-- tests/golden_tests.rs | 6 ++-- 6 files changed, 67 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df20db785..c9f0d361e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" +checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" dependencies = [ "cfg-if", "once_cell", @@ -16,9 +16,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -70,9 +70,9 @@ checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] name = "cc" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" [[package]] name = "cfg-if" @@ -227,9 +227,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "967d6dd42f16dbf0eb8040cb9e477933562684d3918f7d253f2ff9087fb3e7a3" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -401,9 +401,9 @@ checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" [[package]] name = "syn" -version = "2.0.50" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74f1bdc9872430ce9b75da68329d1c1746faf50ffac5f19e02b71e37ff881ffb" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -480,9 +480,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -495,45 +495,45 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "yaml-rust" diff --git a/src/lib.rs b/src/lib.rs index df68be3ce..6d8c8f4c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,18 +10,14 @@ use hvmc::{ stdlib::LogDef, }; use hvmc_net::{pre_reduce::pre_reduce_book, prune::prune_defs}; -use net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::nets_to_hvmc}; +use net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::{net_to_hvmc, nets_to_hvmc}}; use std::{ str::FromStr, sync::{Arc, Mutex}, time::Instant, }; use term::{ - book_to_nets, - display::{display_readback_errors, DisplayJoin}, - net_to_term::net_to_term, - term_to_net::Labels, - AdtEncoding, Book, Ctx, ReadbackError, Term, + book_to_nets, display::{display_readback_errors, DisplayJoin}, net_to_term::net_to_term, term_to_compat_net, term_to_net::Labels, AdtEncoding, Book, Ctx, ReadbackError, Term }; pub mod diagnostics; @@ -95,14 +91,24 @@ pub fn create_host(book: Arc, labels: Arc, compile_opts: CompileOp pub fn check_book(book: &mut Book) -> Result<(), Info> { // TODO: Do the checks without having to do full compilation // TODO: Shouldn't the check mode show warnings? - compile_book(book, CompileOpts::light())?; + compile_book(book, None, CompileOpts::light())?; Ok(()) } -pub fn compile_book(book: &mut Book, opts: CompileOpts) -> Result { +pub fn compile_book(book: &mut Book, args: Option>, opts: CompileOpts) -> Result { let warns = desugar_book(book, opts)?; - let (nets, labels) = book_to_nets(book); - let mut core_book = nets_to_hvmc(nets)?; + let (nets, mut labels) = book_to_nets(book); + + let mut net_args = Vec::new(); + if let Some(args) = args { + for term in &args { + let inet = term_to_compat_net(term, &mut labels); + let net = net_to_hvmc(&inet).expect(""); + net_args.push(net); + } + } + + let mut core_book = nets_to_hvmc(nets, net_args, book.hvmc_entrypoint())?; if opts.pre_reduce { pre_reduce_book(&mut core_book, book.hvmc_entrypoint())?; } @@ -184,8 +190,9 @@ pub fn run_book( run_opts: RunOpts, warning_opts: WarningOpts, compile_opts: CompileOpts, + args: Vec, ) -> Result<(Term, RunInfo), Info> { - let CompileResult { core_book, labels, warns } = compile_book(&mut book, compile_opts)?; + let CompileResult { core_book, labels, warns } = compile_book(&mut book, Some(args), compile_opts)?; // Turn the book into an Arc so that we can use it for logging, debugging, etc. // from anywhere else in the program diff --git a/src/main.rs b/src/main.rs index 7f4f5d2a7..ad7d0bd47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,6 +86,13 @@ enum Mode { )] comp_opts: Vec, + #[arg(value_parser = |arg: &str| hvml::term::parser::parse_term(arg) + .map_err(|e| match e[0].reason() { + chumsky::error::RichReason::Many(errs) => format!("{}", &errs[0]), + _ => format!("{}", e[0].reason()), + }))] + arguments: Vec, + #[command(flatten)] warn_opts: CliWarnOpts, }, @@ -192,7 +199,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { } let mut book = load_book(&path)?; - let compiled = compile_book(&mut book, opts)?; + let compiled = compile_book(&mut book, None, opts)?; println!("{}", compiled.display_with_warns(warning_opts)?); } Mode::Desugar { path, comp_opts, lazy_mode } => { @@ -216,6 +223,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { comp_opts, warn_opts, lazy_mode, + arguments, } => { if debug && lazy_mode { return Err("Unsupported configuration, can not use debug mode `-d` with lazy mode `-L`".into()); @@ -235,7 +243,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { let run_opts = RunOpts { single_core, debug, linear, lazy_mode, max_memory: max_mem, max_rewrites: max_rwts }; let (res_term, RunInfo { stats, readback_errors, net, book: _, labels: _ }) = - run_book(book, max_mem as usize, run_opts, warning_opts, opts)?; + run_book(book, max_mem as usize, run_opts, warning_opts, opts, arguments)?; let total_rewrites = stats.rewrites.total() as f64; let rps = total_rewrites / stats.run_time / 1_000_000.0; diff --git a/src/net/net_to_hvmc.rs b/src/net/net_to_hvmc.rs index 8eeefb164..9ac4e73e9 100644 --- a/src/net/net_to_hvmc.rs +++ b/src/net/net_to_hvmc.rs @@ -5,10 +5,16 @@ use hvmc::ast::{Book, Net, Tree}; use std::collections::{HashMap, HashSet}; /// Converts the inet-encoded definitions into an hvmc AST Book. -pub fn nets_to_hvmc(nets: HashMap) -> Result { +pub fn nets_to_hvmc(nets: HashMap, args: Vec, entrypoint: &str) -> Result { let mut book = Book::default(); for (name, inet) in nets { - let net = net_to_hvmc(&inet)?; + let mut net = net_to_hvmc(&inet)?; + if name == entrypoint { + for arg in args.clone() { + net.rdex.extend(arg.rdex); + net.apply_tree(arg.root); + } + } book.insert(name, net); } Ok(book) diff --git a/src/term/check/set_entrypoint.rs b/src/term/check/set_entrypoint.rs index 104300650..e3160704f 100644 --- a/src/term/check/set_entrypoint.rs +++ b/src/term/check/set_entrypoint.rs @@ -71,8 +71,8 @@ impl Ctx<'_> { fn validate_entry_point(entry: &Definition) -> Result { if entry.rules.len() > 1 { Err(EntryErr::MultipleRules) - } else if !entry.rules[0].pats.is_empty() { - Err(EntryErr::Arguments) + // } else if !entry.rules[0].pats.is_empty() { + // Err(EntryErr::Arguments) } else { Ok(entry.name.clone()) } diff --git a/tests/golden_tests.rs b/tests/golden_tests.rs index e4e54c347..4a81b31a0 100644 --- a/tests/golden_tests.rs +++ b/tests/golden_tests.rs @@ -109,7 +109,7 @@ fn compile_term() { fn compile_file_o_all() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - let compiled = compile_book(&mut book, CompileOpts::heavy())?; + let compiled = compile_book(&mut book, None, CompileOpts::heavy())?; Ok(format!("{:?}", compiled)) }) } @@ -117,7 +117,7 @@ fn compile_file_o_all() { fn compile_file() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - let compiled = compile_book(&mut book, CompileOpts::light())?; + let compiled = compile_book(&mut book, None, CompileOpts::light())?; Ok(format!("{:?}", compiled)) }) } @@ -287,7 +287,7 @@ fn compile_entrypoint() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; book.entrypoint = Some(Name::from("foo")); - let compiled = compile_book(&mut book, CompileOpts::light())?; + let compiled = compile_book(&mut book, None, CompileOpts::light())?; Ok(format!("{:?}", compiled)) }) } From 98bf2f708f1420f26fe6dc17e24a07fee60bae47 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 11:26:30 -0300 Subject: [PATCH 2/9] Update golden tests file --- src/lib.rs | 4 ++-- src/main.rs | 2 +- tests/golden_tests.rs | 16 +++++++++------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6d8c8f4c6..78f4748e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -190,9 +190,9 @@ pub fn run_book( run_opts: RunOpts, warning_opts: WarningOpts, compile_opts: CompileOpts, - args: Vec, + args: Option>, ) -> Result<(Term, RunInfo), Info> { - let CompileResult { core_book, labels, warns } = compile_book(&mut book, Some(args), compile_opts)?; + let CompileResult { core_book, labels, warns } = compile_book(&mut book, args, compile_opts)?; // Turn the book into an Arc so that we can use it for logging, debugging, etc. // from anywhere else in the program diff --git a/src/main.rs b/src/main.rs index ad7d0bd47..94d019fd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -91,7 +91,7 @@ enum Mode { chumsky::error::RichReason::Many(errs) => format!("{}", &errs[0]), _ => format!("{}", e[0].reason()), }))] - arguments: Vec, + arguments: Option>, #[command(flatten)] warn_opts: CliWarnOpts, diff --git a/tests/golden_tests.rs b/tests/golden_tests.rs index 4a81b31a0..6ef805cb0 100644 --- a/tests/golden_tests.rs +++ b/tests/golden_tests.rs @@ -132,6 +132,7 @@ fn linear_readback() { RunOpts { linear: true, ..Default::default() }, WarningOpts::deny_all(), CompileOpts::heavy(), + None, )?; Ok(format!("{}{}", display_readback_errors(&info.readback_errors), res)) }); @@ -143,14 +144,14 @@ fn run_file() { let book = do_parse_book(code, path)?; // 1 million nodes for the test runtime. Smaller doesn't seem to make it any faster let (res, info) = - run_book(book, 1 << 24, RunOpts::lazy(), WarningOpts::deny_all(), CompileOpts::heavy())?; + run_book(book, 1 << 24, RunOpts::lazy(), WarningOpts::deny_all(), CompileOpts::heavy(), None)?; Ok(format!("{}{}", display_readback_errors(&info.readback_errors), res)) }), (&|code, path| { let book = do_parse_book(code, path)?; // 1 million nodes for the test runtime. Smaller doesn't seem to make it any faster let (res, info) = - run_book(book, 1 << 24, RunOpts::default(), WarningOpts::deny_all(), CompileOpts::heavy())?; + run_book(book, 1 << 24, RunOpts::default(), WarningOpts::deny_all(), CompileOpts::heavy(), None)?; Ok(format!("{}{}", display_readback_errors(&info.readback_errors), res)) }), ]) @@ -166,7 +167,7 @@ fn run_lazy() { desugar_opts.lazy_mode(); // 1 million nodes for the test runtime. Smaller doesn't seem to make it any faster - let (res, info) = run_book(book, 1 << 24, run_opts, WarningOpts::deny_all(), desugar_opts)?; + let (res, info) = run_book(book, 1 << 24, run_opts, WarningOpts::deny_all(), desugar_opts, None)?; Ok(format!("{}{}", display_readback_errors(&info.readback_errors), res)) }) } @@ -188,7 +189,7 @@ fn simplify_matches() { let mut book = do_parse_book(code, path)?; let mut ctx = Ctx::new(&mut book); ctx.check_shared_names(); - ctx.set_entrypoint(); + ctx.set_entrypoint(0); ctx.book.encode_adts(AdtEncoding::TaggedScott); ctx.book.encode_builtins(); ctx.book.resolve_ctrs_in_pats(); @@ -226,7 +227,7 @@ fn encode_pattern_match() { let mut book = do_parse_book(code, path)?; let mut ctx = Ctx::new(&mut book); ctx.check_shared_names(); - ctx.set_entrypoint(); + ctx.set_entrypoint(0); ctx.book.encode_adts(adt_encoding); ctx.book.encode_builtins(); ctx.book.resolve_ctrs_in_pats(); @@ -273,7 +274,8 @@ fn hangs() { let lck = Arc::new(RwLock::new(false)); let got = lck.clone(); std::thread::spawn(move || { - let _ = run_book(book, 1 << 20, RunOpts::default(), WarningOpts::deny_all(), CompileOpts::heavy()); + let _ = + run_book(book, 1 << 20, RunOpts::default(), WarningOpts::deny_all(), CompileOpts::heavy(), None); *got.write().unwrap() = true; }); std::thread::sleep(std::time::Duration::from_secs(expected_normalization_time)); @@ -299,7 +301,7 @@ fn run_entrypoint() { book.entrypoint = Some(Name::from("foo")); // 1 million nodes for the test runtime. Smaller doesn't seem to make it any faster let (res, info) = - run_book(book, 1 << 24, RunOpts::default(), WarningOpts::deny_all(), CompileOpts::heavy())?; + run_book(book, 1 << 24, RunOpts::default(), WarningOpts::deny_all(), CompileOpts::heavy(), None)?; Ok(format!("{}{}", display_readback_errors(&info.readback_errors), res)) }) } From d2ab89fb31925ebc9a2e1f614f6ceb2bc5d52f27 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 12:39:39 -0300 Subject: [PATCH 3/9] Apply cli arguments at lambda level --- src/lib.rs | 39 ++++++++++++++++++-------------- src/main.rs | 2 +- src/net/net_to_hvmc.rs | 10 ++------ src/term/check/set_entrypoint.rs | 18 +++++++-------- src/term/transform/apply_args.rs | 24 ++++++++++++++++++++ src/term/transform/mod.rs | 1 + tests/golden_tests.rs | 2 +- 7 files changed, 60 insertions(+), 36 deletions(-) create mode 100644 src/term/transform/apply_args.rs diff --git a/src/lib.rs b/src/lib.rs index 78f4748e0..904e387d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,14 +10,18 @@ use hvmc::{ stdlib::LogDef, }; use hvmc_net::{pre_reduce::pre_reduce_book, prune::prune_defs}; -use net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::{net_to_hvmc, nets_to_hvmc}}; +use net::{hvmc_to_net::hvmc_to_net, net_to_hvmc::nets_to_hvmc}; use std::{ str::FromStr, sync::{Arc, Mutex}, time::Instant, }; use term::{ - book_to_nets, display::{display_readback_errors, DisplayJoin}, net_to_term::net_to_term, term_to_compat_net, term_to_net::Labels, AdtEncoding, Book, Ctx, ReadbackError, Term + book_to_nets, + display::{display_readback_errors, DisplayJoin}, + net_to_term::net_to_term, + term_to_net::Labels, + AdtEncoding, Book, Ctx, ReadbackError, Term, }; pub mod diagnostics; @@ -95,20 +99,15 @@ pub fn check_book(book: &mut Book) -> Result<(), Info> { Ok(()) } -pub fn compile_book(book: &mut Book, args: Option>, opts: CompileOpts) -> Result { - let warns = desugar_book(book, opts)?; - let (nets, mut labels) = book_to_nets(book); - - let mut net_args = Vec::new(); - if let Some(args) = args { - for term in &args { - let inet = term_to_compat_net(term, &mut labels); - let net = net_to_hvmc(&inet).expect(""); - net_args.push(net); - } - } +pub fn compile_book( + book: &mut Book, + args: Option>, + opts: CompileOpts, +) -> Result { + let warns = desugar_book(book, args, opts)?; + let (nets, labels) = book_to_nets(book); - let mut core_book = nets_to_hvmc(nets, net_args, book.hvmc_entrypoint())?; + let mut core_book = nets_to_hvmc(nets)?; if opts.pre_reduce { pre_reduce_book(&mut core_book, book.hvmc_entrypoint())?; } @@ -118,11 +117,17 @@ pub fn compile_book(book: &mut Book, args: Option>, opts: CompileOpts) Ok(CompileResult { core_book, labels, warns }) } -pub fn desugar_book(book: &mut Book, opts: CompileOpts) -> Result, Info> { +pub fn desugar_book( + book: &mut Book, + args: Option>, + opts: CompileOpts, +) -> Result, Info> { let mut ctx = Ctx::new(book); ctx.check_shared_names(); - ctx.set_entrypoint(); + ctx.set_entrypoint(if let Some(args) = &args { args.len() } else { 0 }); + + ctx.book.apply_args(args)?; ctx.book.encode_adts(opts.adt_encoding); ctx.book.encode_builtins(); diff --git a/src/main.rs b/src/main.rs index 94d019fd8..2630ac459 100644 --- a/src/main.rs +++ b/src/main.rs @@ -209,7 +209,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { } let mut book = load_book(&path)?; // TODO: Shouldn't the desugar have `warn_opts` too? maybe WarningOpts::allow_all() by default - let _warns = desugar_book(&mut book, opts)?; + let _warns = desugar_book(&mut book, None, opts)?; println!("{}", book); } Mode::Run { diff --git a/src/net/net_to_hvmc.rs b/src/net/net_to_hvmc.rs index 9ac4e73e9..8eeefb164 100644 --- a/src/net/net_to_hvmc.rs +++ b/src/net/net_to_hvmc.rs @@ -5,16 +5,10 @@ use hvmc::ast::{Book, Net, Tree}; use std::collections::{HashMap, HashSet}; /// Converts the inet-encoded definitions into an hvmc AST Book. -pub fn nets_to_hvmc(nets: HashMap, args: Vec, entrypoint: &str) -> Result { +pub fn nets_to_hvmc(nets: HashMap) -> Result { let mut book = Book::default(); for (name, inet) in nets { - let mut net = net_to_hvmc(&inet)?; - if name == entrypoint { - for arg in args.clone() { - net.rdex.extend(arg.rdex); - net.apply_tree(arg.root); - } - } + let net = net_to_hvmc(&inet)?; book.insert(name, net); } Ok(book) diff --git a/src/term/check/set_entrypoint.rs b/src/term/check/set_entrypoint.rs index e3160704f..f6f7dde95 100644 --- a/src/term/check/set_entrypoint.rs +++ b/src/term/check/set_entrypoint.rs @@ -9,7 +9,7 @@ pub enum EntryErr { NotFound(Name), Multiple(Vec), MultipleRules, - Arguments, + Arguments(usize, usize), } impl Display for EntryErr { @@ -23,19 +23,19 @@ impl Display for EntryErr { write!(f, "File has '{}', '{}' and '{}' definitions.", fnd[0], fnd[1], fnd[2]) } EntryErr::MultipleRules => write!(f, "Main definition can't have more than one rule."), - EntryErr::Arguments => write!(f, "Main definition can't have any arguments."), + EntryErr::Arguments(expected, got) => write!(f, "Main definition expects {expected} arguments, got {got}."), } } } impl Ctx<'_> { - pub fn set_entrypoint(&mut self) { + pub fn set_entrypoint(&mut self, given_arguments: usize) { let mut entrypoint = None; let (custom, main, hvm1_main) = self.book.get_possible_entry_points(); match (custom, main, hvm1_main) { (Some(entry), None, None) | (None, Some(entry), None) | (None, None, Some(entry)) => { - match validate_entry_point(entry) { + match validate_entry_point(entry, given_arguments) { Ok(name) => entrypoint = Some(name), Err(err) => self.info.error(err), } @@ -44,7 +44,7 @@ impl Ctx<'_> { (Some(a), Some(b), None) | (None, Some(a), Some(b)) | (Some(a), None, Some(b)) => { self.info.error(EntryErr::Multiple(vec![a.name.clone(), b.name.clone()])); - match validate_entry_point(a) { + match validate_entry_point(a, given_arguments) { Ok(name) => entrypoint = Some(name), Err(err) => self.info.error(err), } @@ -53,7 +53,7 @@ impl Ctx<'_> { (Some(a), Some(b), Some(c)) => { self.info.error(EntryErr::Multiple(vec![a.name.clone(), b.name.clone(), c.name.clone()])); - match validate_entry_point(a) { + match validate_entry_point(a, given_arguments) { Ok(name) => entrypoint = Some(name), Err(err) => self.info.error(err), } @@ -68,11 +68,11 @@ impl Ctx<'_> { } } -fn validate_entry_point(entry: &Definition) -> Result { +fn validate_entry_point(entry: &Definition, given_arguments: usize) -> Result { if entry.rules.len() > 1 { Err(EntryErr::MultipleRules) - // } else if !entry.rules[0].pats.is_empty() { - // Err(EntryErr::Arguments) + } else if !(entry.rules[0].pats.len() == given_arguments) { + Err(EntryErr::Arguments(entry.rules[0].pats.len(), given_arguments)) } else { Ok(entry.name.clone()) } diff --git a/src/term/transform/apply_args.rs b/src/term/transform/apply_args.rs new file mode 100644 index 000000000..7ea9c8d15 --- /dev/null +++ b/src/term/transform/apply_args.rs @@ -0,0 +1,24 @@ +use crate::term::{Book, Pattern, Term}; + +impl Book { + pub fn apply_args(&mut self, args: Option>) -> Result<(), String> { + if let Some(main) = &self.entrypoint + && let Some(args) = args + { + let mut args = args.into_iter(); + let main_rule = &mut self.defs[main].rules[0]; + let main_body = &mut main_rule.body; + + for pat in &main_rule.pats { + if let Pattern::Var(Some(x)) = pat { + main_body.subst(x, &args.next().unwrap()); + } else { + return Err(format!("Expected a variable pattern, but found '{pat}'.")); + } + } + + main_rule.pats.clear(); + } + Ok(()) + } +} diff --git a/src/term/transform/mod.rs b/src/term/transform/mod.rs index 5a8693c66..6c4b14d66 100644 --- a/src/term/transform/mod.rs +++ b/src/term/transform/mod.rs @@ -1,3 +1,4 @@ +pub mod apply_args; pub mod definition_merge; pub mod definition_pruning; pub mod desugar_implicit_match_binds; diff --git a/tests/golden_tests.rs b/tests/golden_tests.rs index 6ef805cb0..a3d006b49 100644 --- a/tests/golden_tests.rs +++ b/tests/golden_tests.rs @@ -258,7 +258,7 @@ fn encode_pattern_match() { fn desugar_file() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - desugar_book(&mut book, CompileOpts::light())?; + desugar_book(&mut book, None, CompileOpts::light())?; Ok(book.to_string()) }) } From 25c51b697984659574b29bd7b6834d4022a351c6 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 13:12:17 -0300 Subject: [PATCH 4/9] Improve apply_args code --- src/term/check/set_entrypoint.rs | 6 ++++-- src/term/transform/apply_args.rs | 17 +++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/term/check/set_entrypoint.rs b/src/term/check/set_entrypoint.rs index f6f7dde95..d2eb61812 100644 --- a/src/term/check/set_entrypoint.rs +++ b/src/term/check/set_entrypoint.rs @@ -23,7 +23,9 @@ impl Display for EntryErr { write!(f, "File has '{}', '{}' and '{}' definitions.", fnd[0], fnd[1], fnd[2]) } EntryErr::MultipleRules => write!(f, "Main definition can't have more than one rule."), - EntryErr::Arguments(expected, got) => write!(f, "Main definition expects {expected} arguments, got {got}."), + EntryErr::Arguments(expected, got) => { + write!(f, "Main definition expects {expected} arguments, got {got}.") + } } } } @@ -71,7 +73,7 @@ impl Ctx<'_> { fn validate_entry_point(entry: &Definition, given_arguments: usize) -> Result { if entry.rules.len() > 1 { Err(EntryErr::MultipleRules) - } else if !(entry.rules[0].pats.len() == given_arguments) { + } else if entry.rules[0].pats.len() != given_arguments { Err(EntryErr::Arguments(entry.rules[0].pats.len(), given_arguments)) } else { Ok(entry.name.clone()) diff --git a/src/term/transform/apply_args.rs b/src/term/transform/apply_args.rs index 7ea9c8d15..6f64d21f8 100644 --- a/src/term/transform/apply_args.rs +++ b/src/term/transform/apply_args.rs @@ -5,19 +5,16 @@ impl Book { if let Some(main) = &self.entrypoint && let Some(args) = args { - let mut args = args.into_iter(); - let main_rule = &mut self.defs[main].rules[0]; - let main_body = &mut main_rule.body; + let main_def = &mut self.defs[main]; - for pat in &main_rule.pats { - if let Pattern::Var(Some(x)) = pat { - main_body.subst(x, &args.next().unwrap()); - } else { - return Err(format!("Expected a variable pattern, but found '{pat}'.")); - } + if !main_def.rules[0].pats.iter().all(|pat| matches!(pat, Pattern::Var(Some(..)))) { + return Err("Main definition should contain only var patterns.".into()); } - main_rule.pats.clear(); + main_def.convert_match_def_to_term(); + let main_body = &mut self.defs[main].rule_mut().body; + + *main_body = Term::call(main_body.clone(), args); } Ok(()) } From 5870f0d6e55ebfb73792cc2e1ea7bd11d0489c74 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 14:39:30 -0300 Subject: [PATCH 5/9] Remove static arguments compilation --- src/lib.rs | 25 +++++++---------- src/main.rs | 4 +-- src/term/check/set_entrypoint.rs | 27 ++++++++----------- src/term/transform/apply_args.rs | 14 +++++++--- tests/golden_tests.rs | 12 ++++----- tests/golden_tests/compile_file/add_args.hvm | 3 +++ .../snapshots/compile_file__add_args.hvm.snap | 7 +++++ 7 files changed, 48 insertions(+), 44 deletions(-) create mode 100644 tests/golden_tests/compile_file/add_args.hvm create mode 100644 tests/snapshots/compile_file__add_args.hvm.snap diff --git a/src/lib.rs b/src/lib.rs index 904e387d3..da416fae6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,16 +95,12 @@ pub fn create_host(book: Arc, labels: Arc, compile_opts: CompileOp pub fn check_book(book: &mut Book) -> Result<(), Info> { // TODO: Do the checks without having to do full compilation // TODO: Shouldn't the check mode show warnings? - compile_book(book, None, CompileOpts::light())?; + compile_book(book, CompileOpts::light())?; Ok(()) } -pub fn compile_book( - book: &mut Book, - args: Option>, - opts: CompileOpts, -) -> Result { - let warns = desugar_book(book, args, opts)?; +pub fn compile_book(book: &mut Book, opts: CompileOpts) -> Result { + let warns = desugar_book(book, opts)?; let (nets, labels) = book_to_nets(book); let mut core_book = nets_to_hvmc(nets)?; @@ -117,17 +113,11 @@ pub fn compile_book( Ok(CompileResult { core_book, labels, warns }) } -pub fn desugar_book( - book: &mut Book, - args: Option>, - opts: CompileOpts, -) -> Result, Info> { +pub fn desugar_book(book: &mut Book, opts: CompileOpts) -> Result, Info> { let mut ctx = Ctx::new(book); ctx.check_shared_names(); - ctx.set_entrypoint(if let Some(args) = &args { args.len() } else { 0 }); - - ctx.book.apply_args(args)?; + ctx.set_entrypoint(); ctx.book.encode_adts(opts.adt_encoding); ctx.book.encode_builtins(); @@ -197,7 +187,10 @@ pub fn run_book( compile_opts: CompileOpts, args: Option>, ) -> Result<(Term, RunInfo), Info> { - let CompileResult { core_book, labels, warns } = compile_book(&mut book, args, compile_opts)?; + let mut ctx = Ctx::new(&mut book); + ctx.set_entrypoint(); + ctx.book.apply_args(args)?; + let CompileResult { core_book, labels, warns } = compile_book(&mut book, compile_opts)?; // Turn the book into an Arc so that we can use it for logging, debugging, etc. // from anywhere else in the program diff --git a/src/main.rs b/src/main.rs index 2630ac459..dfab69a56 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,7 +199,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { } let mut book = load_book(&path)?; - let compiled = compile_book(&mut book, None, opts)?; + let compiled = compile_book(&mut book, opts)?; println!("{}", compiled.display_with_warns(warning_opts)?); } Mode::Desugar { path, comp_opts, lazy_mode } => { @@ -209,7 +209,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { } let mut book = load_book(&path)?; // TODO: Shouldn't the desugar have `warn_opts` too? maybe WarningOpts::allow_all() by default - let _warns = desugar_book(&mut book, None, opts)?; + let _warns = desugar_book(&mut book, opts)?; println!("{}", book); } Mode::Run { diff --git a/src/term/check/set_entrypoint.rs b/src/term/check/set_entrypoint.rs index d2eb61812..8823ab864 100644 --- a/src/term/check/set_entrypoint.rs +++ b/src/term/check/set_entrypoint.rs @@ -9,7 +9,6 @@ pub enum EntryErr { NotFound(Name), Multiple(Vec), MultipleRules, - Arguments(usize, usize), } impl Display for EntryErr { @@ -23,21 +22,23 @@ impl Display for EntryErr { write!(f, "File has '{}', '{}' and '{}' definitions.", fnd[0], fnd[1], fnd[2]) } EntryErr::MultipleRules => write!(f, "Main definition can't have more than one rule."), - EntryErr::Arguments(expected, got) => { - write!(f, "Main definition expects {expected} arguments, got {got}.") - } } } } impl Ctx<'_> { - pub fn set_entrypoint(&mut self, given_arguments: usize) { + pub fn set_entrypoint(&mut self) { + // already setted + if self.book.entrypoint.is_some() { + return; + } + let mut entrypoint = None; let (custom, main, hvm1_main) = self.book.get_possible_entry_points(); match (custom, main, hvm1_main) { (Some(entry), None, None) | (None, Some(entry), None) | (None, None, Some(entry)) => { - match validate_entry_point(entry, given_arguments) { + match validate_entry_point(entry) { Ok(name) => entrypoint = Some(name), Err(err) => self.info.error(err), } @@ -46,7 +47,7 @@ impl Ctx<'_> { (Some(a), Some(b), None) | (None, Some(a), Some(b)) | (Some(a), None, Some(b)) => { self.info.error(EntryErr::Multiple(vec![a.name.clone(), b.name.clone()])); - match validate_entry_point(a, given_arguments) { + match validate_entry_point(a) { Ok(name) => entrypoint = Some(name), Err(err) => self.info.error(err), } @@ -55,7 +56,7 @@ impl Ctx<'_> { (Some(a), Some(b), Some(c)) => { self.info.error(EntryErr::Multiple(vec![a.name.clone(), b.name.clone(), c.name.clone()])); - match validate_entry_point(a, given_arguments) { + match validate_entry_point(a) { Ok(name) => entrypoint = Some(name), Err(err) => self.info.error(err), } @@ -70,14 +71,8 @@ impl Ctx<'_> { } } -fn validate_entry_point(entry: &Definition, given_arguments: usize) -> Result { - if entry.rules.len() > 1 { - Err(EntryErr::MultipleRules) - } else if entry.rules[0].pats.len() != given_arguments { - Err(EntryErr::Arguments(entry.rules[0].pats.len(), given_arguments)) - } else { - Ok(entry.name.clone()) - } +fn validate_entry_point(entry: &Definition) -> Result { + if entry.rules.len() > 1 { Err(EntryErr::MultipleRules) } else { Ok(entry.name.clone()) } } impl Book { diff --git a/src/term/transform/apply_args.rs b/src/term/transform/apply_args.rs index 6f64d21f8..074a4a29d 100644 --- a/src/term/transform/apply_args.rs +++ b/src/term/transform/apply_args.rs @@ -2,17 +2,23 @@ use crate::term::{Book, Pattern, Term}; impl Book { pub fn apply_args(&mut self, args: Option>) -> Result<(), String> { - if let Some(main) = &self.entrypoint + if let Some(entrypoint) = &self.entrypoint && let Some(args) = args { - let main_def = &mut self.defs[main]; + let main_def = &mut self.defs[entrypoint]; + let expected = main_def.rules[0].pats.len(); + let got = args.len(); if !main_def.rules[0].pats.iter().all(|pat| matches!(pat, Pattern::Var(Some(..)))) { - return Err("Main definition should contain only var patterns.".into()); + return Err("Definition '{entrypoint}' should contain only var patterns.".into()); + } + + if expected != got { + return Err(format!("Expected {expected} arguments, got {got}.")); } main_def.convert_match_def_to_term(); - let main_body = &mut self.defs[main].rule_mut().body; + let main_body = &mut self.defs[entrypoint].rule_mut().body; *main_body = Term::call(main_body.clone(), args); } diff --git a/tests/golden_tests.rs b/tests/golden_tests.rs index a3d006b49..2df2be992 100644 --- a/tests/golden_tests.rs +++ b/tests/golden_tests.rs @@ -109,7 +109,7 @@ fn compile_term() { fn compile_file_o_all() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - let compiled = compile_book(&mut book, None, CompileOpts::heavy())?; + let compiled = compile_book(&mut book, CompileOpts::heavy())?; Ok(format!("{:?}", compiled)) }) } @@ -117,7 +117,7 @@ fn compile_file_o_all() { fn compile_file() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - let compiled = compile_book(&mut book, None, CompileOpts::light())?; + let compiled = compile_book(&mut book, CompileOpts::light())?; Ok(format!("{:?}", compiled)) }) } @@ -189,7 +189,7 @@ fn simplify_matches() { let mut book = do_parse_book(code, path)?; let mut ctx = Ctx::new(&mut book); ctx.check_shared_names(); - ctx.set_entrypoint(0); + ctx.set_entrypoint(); ctx.book.encode_adts(AdtEncoding::TaggedScott); ctx.book.encode_builtins(); ctx.book.resolve_ctrs_in_pats(); @@ -227,7 +227,7 @@ fn encode_pattern_match() { let mut book = do_parse_book(code, path)?; let mut ctx = Ctx::new(&mut book); ctx.check_shared_names(); - ctx.set_entrypoint(0); + ctx.set_entrypoint(); ctx.book.encode_adts(adt_encoding); ctx.book.encode_builtins(); ctx.book.resolve_ctrs_in_pats(); @@ -258,7 +258,7 @@ fn encode_pattern_match() { fn desugar_file() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - desugar_book(&mut book, None, CompileOpts::light())?; + desugar_book(&mut book, CompileOpts::light())?; Ok(book.to_string()) }) } @@ -289,7 +289,7 @@ fn compile_entrypoint() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; book.entrypoint = Some(Name::from("foo")); - let compiled = compile_book(&mut book, None, CompileOpts::light())?; + let compiled = compile_book(&mut book, CompileOpts::light())?; Ok(format!("{:?}", compiled)) }) } diff --git a/tests/golden_tests/compile_file/add_args.hvm b/tests/golden_tests/compile_file/add_args.hvm new file mode 100644 index 000000000..ea539fc5f --- /dev/null +++ b/tests/golden_tests/compile_file/add_args.hvm @@ -0,0 +1,3 @@ +add x y = (+ x y) + +main x y = (add x y) diff --git a/tests/snapshots/compile_file__add_args.hvm.snap b/tests/snapshots/compile_file__add_args.hvm.snap new file mode 100644 index 000000000..653e8733a --- /dev/null +++ b/tests/snapshots/compile_file__add_args.hvm.snap @@ -0,0 +1,7 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/compile_file/add_args.hvm +--- +@add = (<+ a b> (a b)) +@main = (a (b c)) +& @add ~ (a (b c)) From 69ada38a06a52ebe156b794ca15a88cc5c0e8ef5 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 15:19:04 -0300 Subject: [PATCH 6/9] Refactor apply_args errors --- src/diagnostics.rs | 14 ++++++++--- src/lib.rs | 2 +- src/term/check/set_entrypoint.rs | 2 +- src/term/transform/apply_args.rs | 41 +++++++++++++++++++++++++------- 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/diagnostics.rs b/src/diagnostics.rs index c3b9a9c73..30cef9503 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -5,7 +5,7 @@ use crate::term::{ }, display::DisplayFn, transform::{ - encode_pattern_matching::MatchErr, resolve_refs::ReferencedMainErr, simplify_ref_to_ref::CyclicDefErr, + apply_args::ArgError, encode_pattern_matching::MatchErr, resolve_refs::ReferencedMainErr, simplify_ref_to_ref::CyclicDefErr }, Name, }; @@ -59,8 +59,8 @@ impl Info { self.err_counter = 0; } - /// Checks if any error was emitted since the start of the pass, - /// Returning all the current information as a `Err(Info)`, replacing `&mut self` with an empty one. + /// Checks if any error was emitted since the start of the pass, + /// Returning all the current information as a `Err(Info)`, replacing `&mut self` with an empty one. /// Otherwise, returns the given arg as an `Ok(T)`. pub fn fatal(&mut self, t: T) -> Result { if self.err_counter == 0 { Ok(t) } else { Err(std::mem::take(self)) } @@ -110,6 +110,7 @@ pub enum Error { EntryPoint(EntryErr), TopLevel(TopLevelErr), Custom(String), + ArgError(ArgError), } impl Display for Error { @@ -129,6 +130,7 @@ impl Error { Error::EntryPoint(err) => write!(f, "{err}"), Error::TopLevel(err) => write!(f, "{err}"), Error::Custom(err) => write!(f, "{err}"), + Error::ArgError(err) => write!(f, "{err}"), }) } } @@ -175,6 +177,12 @@ impl From for Error { } } +impl From for Error { + fn from(value: ArgError) -> Self { + Self::ArgError(value) + } +} + #[derive(Debug, Clone)] pub enum Warning { MatchOnlyVars(Name), diff --git a/src/lib.rs b/src/lib.rs index da416fae6..e2721bee7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -189,7 +189,7 @@ pub fn run_book( ) -> Result<(Term, RunInfo), Info> { let mut ctx = Ctx::new(&mut book); ctx.set_entrypoint(); - ctx.book.apply_args(args)?; + ctx.apply_args(args)?; let CompileResult { core_book, labels, warns } = compile_book(&mut book, compile_opts)?; // Turn the book into an Arc so that we can use it for logging, debugging, etc. diff --git a/src/term/check/set_entrypoint.rs b/src/term/check/set_entrypoint.rs index 8823ab864..e9d7aff7c 100644 --- a/src/term/check/set_entrypoint.rs +++ b/src/term/check/set_entrypoint.rs @@ -28,7 +28,7 @@ impl Display for EntryErr { impl Ctx<'_> { pub fn set_entrypoint(&mut self) { - // already setted + // already set if self.book.entrypoint.is_some() { return; } diff --git a/src/term/transform/apply_args.rs b/src/term/transform/apply_args.rs index 074a4a29d..8f3c9d184 100644 --- a/src/term/transform/apply_args.rs +++ b/src/term/transform/apply_args.rs @@ -1,27 +1,50 @@ -use crate::term::{Book, Pattern, Term}; +use std::fmt::Display; -impl Book { - pub fn apply_args(&mut self, args: Option>) -> Result<(), String> { - if let Some(entrypoint) = &self.entrypoint +use crate::{ + diagnostics::Info, + term::{Ctx, Pattern, Term}, +}; + +#[derive(Clone, Debug)] +pub enum ArgError { + PatternArgError, + ArityArgError { expected: usize, got: usize }, +} + +impl Display for ArgError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ArgError::PatternArgError => write!(f, ""), + ArgError::ArityArgError { expected, got } => write!(f, "Expected {expected} arguments, got {got}."), + } + } +} + +impl Ctx<'_> { + pub fn apply_args(&mut self, args: Option>) -> Result<(), Info> { + self.info.start_pass(); + + if let Some(entrypoint) = &self.book.entrypoint && let Some(args) = args { - let main_def = &mut self.defs[entrypoint]; + let main_def = &mut self.book.defs[entrypoint]; let expected = main_def.rules[0].pats.len(); let got = args.len(); if !main_def.rules[0].pats.iter().all(|pat| matches!(pat, Pattern::Var(Some(..)))) { - return Err("Definition '{entrypoint}' should contain only var patterns.".into()); + self.info.def_error(entrypoint.clone(), ArgError::PatternArgError); } if expected != got { - return Err(format!("Expected {expected} arguments, got {got}.")); + self.info.error(ArgError::ArityArgError { expected, got }); } main_def.convert_match_def_to_term(); - let main_body = &mut self.defs[entrypoint].rule_mut().body; + let main_body = &mut self.book.defs[entrypoint].rule_mut().body; *main_body = Term::call(main_body.clone(), args); } - Ok(()) + + self.info.fatal(()) } } From e7edca1bc2a3ab0bafc527d7137cbbf376513b45 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Thu, 29 Feb 2024 15:56:42 -0300 Subject: [PATCH 7/9] Adjusts formatting --- src/diagnostics.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 30cef9503..2387bd98f 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -5,7 +5,8 @@ use crate::term::{ }, display::DisplayFn, transform::{ - apply_args::ArgError, encode_pattern_matching::MatchErr, resolve_refs::ReferencedMainErr, simplify_ref_to_ref::CyclicDefErr + apply_args::ArgError, encode_pattern_matching::MatchErr, resolve_refs::ReferencedMainErr, + simplify_ref_to_ref::CyclicDefErr, }, Name, }; From 5cf5d240860f806ee5460695c02ee074ea63ec48 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Fri, 1 Mar 2024 09:25:56 -0300 Subject: [PATCH 8/9] Refactor cli arguments --- src/lib.rs | 22 ++++++++++++++-------- src/main.rs | 4 ++-- src/term/check/set_entrypoint.rs | 5 ----- src/term/transform/apply_args.rs | 16 ++++++++-------- tests/golden_tests.rs | 8 ++++---- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e2721bee7..b2912035f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,12 +95,16 @@ pub fn create_host(book: Arc, labels: Arc, compile_opts: CompileOp pub fn check_book(book: &mut Book) -> Result<(), Info> { // TODO: Do the checks without having to do full compilation // TODO: Shouldn't the check mode show warnings? - compile_book(book, CompileOpts::light())?; + compile_book(book, CompileOpts::light(), None)?; Ok(()) } -pub fn compile_book(book: &mut Book, opts: CompileOpts) -> Result { - let warns = desugar_book(book, opts)?; +pub fn compile_book( + book: &mut Book, + opts: CompileOpts, + args: Option>, +) -> Result { + let warns = desugar_book(book, opts, args)?; let (nets, labels) = book_to_nets(book); let mut core_book = nets_to_hvmc(nets)?; @@ -113,11 +117,16 @@ pub fn compile_book(book: &mut Book, opts: CompileOpts) -> Result Result, Info> { +pub fn desugar_book( + book: &mut Book, + opts: CompileOpts, + args: Option>, +) -> Result, Info> { let mut ctx = Ctx::new(book); ctx.check_shared_names(); ctx.set_entrypoint(); + ctx.apply_args(args)?; ctx.book.encode_adts(opts.adt_encoding); ctx.book.encode_builtins(); @@ -187,10 +196,7 @@ pub fn run_book( compile_opts: CompileOpts, args: Option>, ) -> Result<(Term, RunInfo), Info> { - let mut ctx = Ctx::new(&mut book); - ctx.set_entrypoint(); - ctx.apply_args(args)?; - let CompileResult { core_book, labels, warns } = compile_book(&mut book, compile_opts)?; + let CompileResult { core_book, labels, warns } = compile_book(&mut book, compile_opts, args)?; // Turn the book into an Arc so that we can use it for logging, debugging, etc. // from anywhere else in the program diff --git a/src/main.rs b/src/main.rs index dfab69a56..23413bde6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,7 +199,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { } let mut book = load_book(&path)?; - let compiled = compile_book(&mut book, opts)?; + let compiled = compile_book(&mut book, opts, None)?; println!("{}", compiled.display_with_warns(warning_opts)?); } Mode::Desugar { path, comp_opts, lazy_mode } => { @@ -209,7 +209,7 @@ fn execute_cli_mode(mut cli: Cli) -> Result<(), Info> { } let mut book = load_book(&path)?; // TODO: Shouldn't the desugar have `warn_opts` too? maybe WarningOpts::allow_all() by default - let _warns = desugar_book(&mut book, opts)?; + let _warns = desugar_book(&mut book, opts, None)?; println!("{}", book); } Mode::Run { diff --git a/src/term/check/set_entrypoint.rs b/src/term/check/set_entrypoint.rs index e9d7aff7c..1f0832a97 100644 --- a/src/term/check/set_entrypoint.rs +++ b/src/term/check/set_entrypoint.rs @@ -28,11 +28,6 @@ impl Display for EntryErr { impl Ctx<'_> { pub fn set_entrypoint(&mut self) { - // already set - if self.book.entrypoint.is_some() { - return; - } - let mut entrypoint = None; let (custom, main, hvm1_main) = self.book.get_possible_entry_points(); diff --git a/src/term/transform/apply_args.rs b/src/term/transform/apply_args.rs index 8f3c9d184..5fe26cf39 100644 --- a/src/term/transform/apply_args.rs +++ b/src/term/transform/apply_args.rs @@ -24,25 +24,25 @@ impl Ctx<'_> { pub fn apply_args(&mut self, args: Option>) -> Result<(), Info> { self.info.start_pass(); - if let Some(entrypoint) = &self.book.entrypoint - && let Some(args) = args - { + if let Some(entrypoint) = &self.book.entrypoint { let main_def = &mut self.book.defs[entrypoint]; - let expected = main_def.rules[0].pats.len(); - let got = args.len(); if !main_def.rules[0].pats.iter().all(|pat| matches!(pat, Pattern::Var(Some(..)))) { self.info.def_error(entrypoint.clone(), ArgError::PatternArgError); } + let expected = main_def.rules[0].pats.len(); + let got = if let Some(args) = &args { args.len() } else { 0 }; if expected != got { self.info.error(ArgError::ArityArgError { expected, got }); } - main_def.convert_match_def_to_term(); - let main_body = &mut self.book.defs[entrypoint].rule_mut().body; + if let Some(args) = args { + main_def.convert_match_def_to_term(); + let main_body = &mut self.book.defs[entrypoint].rule_mut().body; - *main_body = Term::call(main_body.clone(), args); + *main_body = Term::call(main_body.clone(), args); + } } self.info.fatal(()) diff --git a/tests/golden_tests.rs b/tests/golden_tests.rs index 2df2be992..0550b4ac1 100644 --- a/tests/golden_tests.rs +++ b/tests/golden_tests.rs @@ -109,7 +109,7 @@ fn compile_term() { fn compile_file_o_all() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - let compiled = compile_book(&mut book, CompileOpts::heavy())?; + let compiled = compile_book(&mut book, CompileOpts::heavy(), None)?; Ok(format!("{:?}", compiled)) }) } @@ -117,7 +117,7 @@ fn compile_file_o_all() { fn compile_file() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - let compiled = compile_book(&mut book, CompileOpts::light())?; + let compiled = compile_book(&mut book, CompileOpts::light(), None)?; Ok(format!("{:?}", compiled)) }) } @@ -258,7 +258,7 @@ fn encode_pattern_match() { fn desugar_file() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; - desugar_book(&mut book, CompileOpts::light())?; + desugar_book(&mut book, CompileOpts::light(), None)?; Ok(book.to_string()) }) } @@ -289,7 +289,7 @@ fn compile_entrypoint() { run_golden_test_dir(function_name!(), &|code, path| { let mut book = do_parse_book(code, path)?; book.entrypoint = Some(Name::from("foo")); - let compiled = compile_book(&mut book, CompileOpts::light())?; + let compiled = compile_book(&mut book, CompileOpts::light(), None)?; Ok(format!("{:?}", compiled)) }) } From d7ce3079b9889bb7e4101a909ccd583020703389 Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Fri, 1 Mar 2024 09:42:36 -0300 Subject: [PATCH 9/9] Fix argument checking for other options --- src/term/transform/apply_args.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/term/transform/apply_args.rs b/src/term/transform/apply_args.rs index 5fe26cf39..c6d09092f 100644 --- a/src/term/transform/apply_args.rs +++ b/src/term/transform/apply_args.rs @@ -31,13 +31,13 @@ impl Ctx<'_> { self.info.def_error(entrypoint.clone(), ArgError::PatternArgError); } - let expected = main_def.rules[0].pats.len(); - let got = if let Some(args) = &args { args.len() } else { 0 }; - if expected != got { - self.info.error(ArgError::ArityArgError { expected, got }); - } - if let Some(args) = args { + let expected = main_def.rules[0].pats.len(); + let got = args.len(); + if expected != got { + self.info.error(ArgError::ArityArgError { expected, got }); + } + main_def.convert_match_def_to_term(); let main_body = &mut self.book.defs[entrypoint].rule_mut().body;