mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-11-05 04:51:40 +03:00
Apply cli arguments at lambda level
This commit is contained in:
parent
98bf2f708f
commit
d2ab89fb31
39
src/lib.rs
39
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<Vec<Term>>, opts: CompileOpts) -> Result<CompileResult, Info> {
|
||||
let warns = desugar_book(book, opts)?;
|
||||
let (nets, mut labels) = book_to_nets(book);
|
||||
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 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())?;
|
||||
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<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();
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -9,7 +9,7 @@ pub enum EntryErr {
|
||||
NotFound(Name),
|
||||
Multiple(Vec<Name>),
|
||||
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<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())
|
||||
}
|
||||
|
24
src/term/transform/apply_args.rs
Normal file
24
src/term/transform/apply_args.rs
Normal file
@ -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,3 +1,4 @@
|
||||
pub mod apply_args;
|
||||
pub mod definition_merge;
|
||||
pub mod definition_pruning;
|
||||
pub mod desugar_implicit_match_binds;
|
||||
|
@ -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())
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user