Skip to content

Commit

Permalink
Apply cli arguments at lambda level
Browse files Browse the repository at this point in the history
  • Loading branch information
imaqtkatt committed Feb 29, 2024
1 parent 98bf2f7 commit d2ab89f
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 36 deletions.
39 changes: 22 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -95,20 +99,15 @@ pub fn check_book(book: &mut Book) -> Result<(), Info> {
Ok(())
}

pub fn compile_book(book: &mut Book, args: Option<Vec<Term>>, opts: CompileOpts) -> Result<CompileResult, Info> {
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<Vec<Term>>,
opts: CompileOpts,
) -> Result<CompileResult, Info> {
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())?;
}
Expand All @@ -118,11 +117,17 @@ pub fn compile_book(book: &mut Book, args: Option<Vec<Term>>, opts: CompileOpts)
Ok(CompileResult { core_book, labels, warns })
}

pub fn desugar_book(book: &mut Book, opts: CompileOpts) -> Result<Vec<Warning>, Info> {
pub fn desugar_book(
book: &mut Book,
args: Option<Vec<Term>>,
opts: CompileOpts,
) -> Result<Vec<Warning>, 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();
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 2 additions & 8 deletions src/net/net_to_hvmc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, INet>, args: Vec<Net>, entrypoint: &str) -> Result<Book, String> {
pub fn nets_to_hvmc(nets: HashMap<String, INet>) -> Result<Book, String> {
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)
Expand Down
18 changes: 9 additions & 9 deletions src/term/check/set_entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub enum EntryErr {
NotFound(Name),
Multiple(Vec<Name>),
MultipleRules,
Arguments,
Arguments(usize, usize),
}

impl Display for EntryErr {
Expand All @@ -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),
}
Expand All @@ -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),
}
Expand All @@ -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),
}
Expand All @@ -68,11 +68,11 @@ impl Ctx<'_> {
}
}

fn validate_entry_point(entry: &Definition) -> Result<Name, EntryErr> {
fn validate_entry_point(entry: &Definition, given_arguments: usize) -> Result<Name, EntryErr> {
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())
}
Expand Down
24 changes: 24 additions & 0 deletions src/term/transform/apply_args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::term::{Book, Pattern, Term};

impl Book {
pub fn apply_args(&mut self, args: Option<Vec<Term>>) -> 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(())
}
}
1 change: 1 addition & 0 deletions src/term/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod apply_args;
pub mod definition_merge;
pub mod definition_pruning;
pub mod desugar_implicit_match_binds;
Expand Down
2 changes: 1 addition & 1 deletion tests/golden_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
})
}
Expand Down

0 comments on commit d2ab89f

Please sign in to comment.