mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-21 00:27:20 +03:00
Merge pull request #293 from HigherOrderCO/feature/sc-670/add-priority-redexes-to-bend-output
[sc-670] Add priority redexes and order dups correctly in compilation
This commit is contained in:
commit
ca9acd535a
61
Cargo.lock
generated
61
Cargo.lock
generated
@ -21,47 +21,48 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.13"
|
||||
version = "0.6.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.2"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys",
|
||||
@ -75,9 +76,9 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "bend"
|
||||
@ -106,9 +107,9 @@ checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.95"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
|
||||
checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -158,9 +159,9 @@ checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
@ -213,7 +214,7 @@ checksum = "809e18805660d7b6b2e2b9f316a5099521b5998d5cba4dda11b5157a21aaef03"
|
||||
[[package]]
|
||||
name = "hvm-core"
|
||||
version = "0.2.24"
|
||||
source = "git+https://github.com/HigherOrderCO/hvm-core.git?branch=hvm32-compat#8bc55acaa14bb18d889e2c80a300a2fadb400d03"
|
||||
source = "git+https://github.com/HigherOrderCO/hvm-core.git?branch=hvm32-compat#389b3be2d0c0dbe23623adda9175c622dd9ce0b8"
|
||||
dependencies = [
|
||||
"TSPL 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"arrayvec",
|
||||
@ -252,6 +253,12 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8c60687056b35a996f2213287048a7092d801b61df5fee3bd5bd9bf6f17a2d0"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
@ -269,9 +276,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.154"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
@ -326,9 +333,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.81"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
|
||||
checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@ -414,9 +421,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.60"
|
||||
version = "2.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
|
||||
checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -425,18 +432,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.59"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
|
||||
checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.59"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
|
||||
checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -6,12 +6,10 @@
|
||||
| `-Ono-all` | Disabled | Disables all compiler passes |
|
||||
| `-Oeta` `-Ono-eta` | Disabled | [eta-reduction](#eta-reduction) |
|
||||
| `-Oprune` `-Ono-prune` | Disabled | [definition-pruning](#definition-pruning) |
|
||||
| `-Opre-reduce` `-Ono-pre-reduce` | Disabled | [pre-reduce](#pre-reduce) |
|
||||
| `-Olinearize-matches` `-Olinearize-matches-extra` `-Ono-linearize-matches` | Enabled | [linearize-matches](#linearize-matches) |
|
||||
| `-Olinearize-matches` `-Olinearize-matches-alt` `-Ono-linearize-matches` | Enabled | [linearize-matches](#linearize-matches) |
|
||||
| `-Ofloat_combinators` `-Ono-float_combinators` | Enabled | [float-combinators](#float-combinators) |
|
||||
| `-Omerge` `-Ono-merge` | Disabled | [definition-merging](#definition-merging) |
|
||||
| `-Oinline` `-Ono-inline` | Disabled | [inline](#inline) |
|
||||
| `-e` `--entrypoint` | `Main \| main` | [entrypoint](#entrypoint) |
|
||||
|
||||
## Eta-reduction
|
||||
|
||||
|
@ -428,9 +428,9 @@ impl<'a> TermParser<'a> {
|
||||
// Match
|
||||
if self.try_consume_keyword("match") {
|
||||
unexpected_tag(self)?;
|
||||
let (bnd, arg, with) = self.parse_match_arg()?;
|
||||
let (bnd, arg, with) = self.parse_match_header()?;
|
||||
let arms = self.list_like(|p| p.parse_match_arm(), "{", "}", ";", false, 1)?;
|
||||
return Ok(Term::Mat { arg: Box::new(arg), bnd: Some(bnd), with, arms });
|
||||
return Ok(Term::Mat { arg: Box::new(arg), bnd, with, arms });
|
||||
}
|
||||
|
||||
// Switch
|
||||
@ -452,9 +452,9 @@ impl<'a> TermParser<'a> {
|
||||
// Fold
|
||||
if self.try_consume_keyword("fold") {
|
||||
unexpected_tag(self)?;
|
||||
let (bnd, arg, with) = self.parse_match_arg()?;
|
||||
let (bnd, arg, with) = self.parse_match_header()?;
|
||||
let arms = self.list_like(|p| p.parse_match_arm(), "{", "}", ";", false, 1)?;
|
||||
return Ok(Term::Fold { arg: Box::new(arg), bnd: Some(bnd), with, arms });
|
||||
return Ok(Term::Fold { arg: Box::new(arg), bnd, with, arms });
|
||||
}
|
||||
|
||||
// Bend
|
||||
@ -564,9 +564,25 @@ impl<'a> TermParser<'a> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_match_arg(&mut self) -> Result<(Name, Term, Vec<Name>), String> {
|
||||
let bnd = self.parse_bend_name()?;
|
||||
let arg = if self.try_consume("=") { self.parse_term()? } else { Term::Var { nam: bnd.clone() } };
|
||||
fn parse_match_arg(&mut self) -> Result<(Option<Name>, Term), String> {
|
||||
let ini_idx = *self.index();
|
||||
let mut arg = self.parse_term()?;
|
||||
let end_idx = *self.index();
|
||||
|
||||
self.skip_trivia();
|
||||
match (&mut arg, self.starts_with("=")) {
|
||||
(Term::Var { nam }, true) => {
|
||||
self.consume("=")?;
|
||||
Ok((Some(std::mem::take(nam)), self.parse_term()?))
|
||||
}
|
||||
(Term::Var { nam }, false) => Ok((Some(nam.clone()), Term::Var { nam: std::mem::take(nam) })),
|
||||
(_, true) => self.expected_spanned("argument name", ini_idx, end_idx),
|
||||
(arg, false) => Ok((Some(Name::new("%arg")), std::mem::take(arg))),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_match_header(&mut self) -> Result<(Option<Name>, Term, Vec<Name>), String> {
|
||||
let (bnd, arg) = self.parse_match_arg()?;
|
||||
let with = if self.try_consume_keyword("with") {
|
||||
let mut with = vec![self.parse_bend_name()?];
|
||||
while !self.skip_starts_with("{") {
|
||||
@ -589,7 +605,7 @@ impl<'a> TermParser<'a> {
|
||||
}
|
||||
|
||||
fn parse_switch(&mut self) -> Result<Term, String> {
|
||||
let (bnd, arg, with) = self.parse_match_arg()?;
|
||||
let (bnd, arg, with) = self.parse_match_header()?;
|
||||
self.consume("{")?;
|
||||
let mut expected_num = 0;
|
||||
let mut arms = vec![];
|
||||
@ -619,9 +635,9 @@ impl<'a> TermParser<'a> {
|
||||
self.try_consume(";");
|
||||
expected_num += 1;
|
||||
}
|
||||
let pred = Some(Name::new(format!("{}-{}", bnd, arms.len() - 1)));
|
||||
let pred = Some(Name::new(format!("{}-{}", bnd.as_ref().unwrap(), arms.len() - 1)));
|
||||
self.consume("}")?;
|
||||
Ok(Term::Swt { arg: Box::new(arg), bnd: Some(bnd), with, pred, arms })
|
||||
Ok(Term::Swt { arg: Box::new(arg), bnd, with, pred, arms })
|
||||
}
|
||||
|
||||
fn num_range_err<T>(&mut self, ini_idx: usize, typ: &str) -> Result<T, String> {
|
||||
|
@ -51,6 +51,7 @@ pub fn term_to_net(term: &Term, labels: &mut Labels) -> Result<Net, String> {
|
||||
let mut net = Net::default();
|
||||
|
||||
let mut state = EncodeTermState {
|
||||
lets: Default::default(),
|
||||
vars: Default::default(),
|
||||
wires: Default::default(),
|
||||
redexes: Default::default(),
|
||||
@ -74,9 +75,10 @@ pub fn term_to_net(term: &Term, labels: &mut Labels) -> Result<Net, String> {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct EncodeTermState<'t, 'l> {
|
||||
lets: Vec<(&'t Pattern, &'t Term)>,
|
||||
vars: HashMap<(bool, Name), Place<'t>>,
|
||||
wires: Vec<Option<Place<'t>>>,
|
||||
redexes: Vec<LoanedMut<'t, (Tree, Tree)>>,
|
||||
redexes: Vec<LoanedMut<'t, (bool, Tree, Tree)>>,
|
||||
name_idx: u64,
|
||||
created_nodes: usize,
|
||||
labels: &'l mut Labels,
|
||||
@ -101,7 +103,7 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
/// `vars` has the information of which ports the variables are declared and used in.
|
||||
/// `global_vars` has the same information for global lambdas. Must be linked outside this function.
|
||||
/// Expects variables to be linear, refs to be stored as Refs and all names to be bound.
|
||||
fn encode_term(&mut self, term: &Term, up: Place<'t>) {
|
||||
fn encode_term(&mut self, term: &'t Term, up: Place<'t>) {
|
||||
maybe_grow(|| {
|
||||
match term {
|
||||
Term::Era => self.link(up, Place::Tree(LoanedMut::new(Tree::Era))),
|
||||
@ -155,10 +157,9 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
self.link(up, Place::Hole(out));
|
||||
}
|
||||
Term::Let { pat, val, nxt } => {
|
||||
let wire = self.new_wire();
|
||||
self.encode_term(val, Place::Wire(wire));
|
||||
self.encode_pat(pat, Place::Wire(wire));
|
||||
|
||||
// Dups/tup eliminators are not actually scoped like other terms.
|
||||
// They are depended on
|
||||
self.lets.push((pat, val));
|
||||
self.encode_term(nxt, up);
|
||||
}
|
||||
Term::Fan { fan, tag, els } => {
|
||||
@ -213,6 +214,11 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
| Term::List { .. } // Removed in encode_list
|
||||
| Term::Err => unreachable!(),
|
||||
}
|
||||
while let Some((pat, val)) = self.lets.pop() {
|
||||
let wire = self.new_wire();
|
||||
self.encode_term(val, Place::Wire(wire));
|
||||
self.encode_pat(pat, Place::Wire(wire));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -232,8 +238,8 @@ impl<'t, 'l> EncodeTermState<'t, 'l> {
|
||||
fn link(&mut self, a: Place<'t>, b: Place<'t>) {
|
||||
match (a, b) {
|
||||
(Place::Tree(a), Place::Tree(b)) => self.redexes.push(LoanedMut::merge(Default::default(), |r, m| {
|
||||
m.place(b, &mut r.0);
|
||||
m.place(a, &mut r.1);
|
||||
m.place(b, &mut r.1);
|
||||
m.place(a, &mut r.2);
|
||||
})),
|
||||
(Place::Tree(t), Place::Hole(h)) | (Place::Hole(h), Place::Tree(t)) => {
|
||||
t.place(h);
|
||||
|
@ -1,55 +1,58 @@
|
||||
use crate::maybe_grow;
|
||||
use hvmc::ast::{Book, Net, Tree};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use crate::maybe_grow;
|
||||
|
||||
/// Reorder redexes in the book to have more efficient execution.
|
||||
///
|
||||
/// Especially for hvm-cuda, we want to keep the number of nodes/vars/redexes
|
||||
/// low so we put redexes with recursive refs last (at the bottom of the stack).
|
||||
pub fn reorder_redexes_recursive_last(book: &mut Book) {
|
||||
pub fn add_recursive_priority(book: &mut Book) {
|
||||
// Direct dependencies
|
||||
let deps = book.iter().map(|(nam, net)| (nam.clone(), dependencies(net))).collect::<HashMap<_, _>>();
|
||||
// Recursive cycles
|
||||
let cycles = cycles(&deps);
|
||||
|
||||
// Look at dependencies to find if recursive
|
||||
let recursive_nets = cycles(&deps).into_iter().flatten().collect::<HashSet<_>>();
|
||||
|
||||
for net in book.values_mut() {
|
||||
reorder_redexes_net(net, &recursive_nets);
|
||||
}
|
||||
}
|
||||
|
||||
/// Reorder redexes to have recursive last (bottom of the stack).
|
||||
fn reorder_redexes_net(net: &mut Net, recursive_nets: &HashSet<String>) {
|
||||
let mut recursive_redexes = vec![];
|
||||
let mut non_recursive_redexes = vec![];
|
||||
|
||||
for (a, b) in std::mem::take(&mut net.redexes) {
|
||||
if tree_has_recursive(&a, recursive_nets) || tree_has_recursive(&b, recursive_nets) {
|
||||
recursive_redexes.push((a, b));
|
||||
} else {
|
||||
non_recursive_redexes.push((a, b));
|
||||
for cycle in cycles {
|
||||
// For each function in the cycle, if there are redexes with the
|
||||
// next ref in the cycle, add a priority to one of those redexes.
|
||||
for i in 0 .. cycle.len() {
|
||||
let cur = book.get_mut(&cycle[i]).unwrap();
|
||||
let nxt = &cycle[(i + 1) % cycle.len()];
|
||||
add_priority_next_in_cycle(cur, nxt);
|
||||
}
|
||||
}
|
||||
let mut redexes = recursive_redexes;
|
||||
redexes.append(&mut non_recursive_redexes);
|
||||
net.redexes = redexes;
|
||||
}
|
||||
|
||||
/// Whether a tree has a reference to a recursive net or not.
|
||||
fn tree_has_recursive(tree: &Tree, recursive_nets: &HashSet<String>) -> bool {
|
||||
maybe_grow(|| {
|
||||
if let Tree::Ref { nam } = tree {
|
||||
recursive_nets.contains(nam)
|
||||
} else {
|
||||
for child in tree.children() {
|
||||
if tree_has_recursive(child, recursive_nets) {
|
||||
return true;
|
||||
fn add_priority_next_in_cycle(net: &mut Net, nxt: &String) {
|
||||
let mut count = 0;
|
||||
|
||||
// Count the number of recursive refs
|
||||
for (_, a, b) in net.redexes.iter() {
|
||||
if let Tree::Ref { nam } = a {
|
||||
if nam == nxt {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
if let Tree::Ref { nam } = b {
|
||||
if nam == nxt {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are more than one recursive ref, add a priority to the last (first to execute).
|
||||
if count > 1 {
|
||||
for (pri, a, b) in net.redexes.iter_mut().rev() {
|
||||
if let Tree::Ref { nam } = a {
|
||||
if nam == nxt {
|
||||
*pri = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Tree::Ref { nam } = b {
|
||||
if nam == nxt {
|
||||
*pri = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type DepGraph = HashMap<String, HashSet<String>>;
|
||||
@ -102,7 +105,7 @@ fn find_cycles(
|
||||
fn dependencies(net: &Net) -> HashSet<String> {
|
||||
let mut deps = HashSet::new();
|
||||
dependencies_tree(&net.root, &mut deps);
|
||||
for (a, b) in &net.redexes {
|
||||
for (_, a, b) in &net.redexes {
|
||||
dependencies_tree(a, &mut deps);
|
||||
dependencies_tree(b, &mut deps);
|
||||
}
|
||||
@ -110,7 +113,7 @@ fn dependencies(net: &Net) -> HashSet<String> {
|
||||
}
|
||||
|
||||
fn dependencies_tree(tree: &Tree, deps: &mut HashSet<String>) {
|
||||
if let Tree::Ref { nam } = tree {
|
||||
if let Tree::Ref { nam, .. } = tree {
|
||||
deps.insert(nam.clone());
|
||||
} else {
|
||||
for subtree in tree.children() {
|
@ -23,7 +23,7 @@ pub fn check_net_sizes(book: &Book, diagnostics: &mut Diagnostics) -> Result<(),
|
||||
pub fn count_nodes<'l>(net: &'l hvmc::ast::Net) -> usize {
|
||||
let mut visit: Vec<&'l hvmc::ast::Tree> = vec![&net.root];
|
||||
let mut count = 0usize;
|
||||
for (l, r) in &net.redexes {
|
||||
for (_, l, r) in &net.redexes {
|
||||
visit.push(l);
|
||||
visit.push(r);
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
pub mod add_recursive_priority;
|
||||
pub mod check_net_size;
|
||||
pub mod mutual_recursion;
|
||||
pub mod reorder_redexes;
|
@ -107,7 +107,7 @@ impl Graph {
|
||||
/// Collect active refs from the tree.
|
||||
fn collect_refs(current: Ref, tree: &Tree, graph: &mut Graph) {
|
||||
maybe_grow(|| match tree {
|
||||
Tree::Ref { nam } => graph.add(current, nam.clone()),
|
||||
Tree::Ref { nam, .. } => graph.add(current, nam.clone()),
|
||||
Tree::Ctr { ports, .. } => {
|
||||
if let Some(last) = ports.last() {
|
||||
collect_refs(current, last, graph);
|
||||
@ -130,11 +130,11 @@ impl From<&Book> for Graph {
|
||||
collect_refs(r#ref.clone(), &net.root, &mut graph);
|
||||
|
||||
// Collect active refs from redexes.
|
||||
for (left, right) in net.redexes.iter() {
|
||||
if let Tree::Ref { nam } = left {
|
||||
for (_, left, right) in net.redexes.iter() {
|
||||
if let Tree::Ref { nam, .. } = left {
|
||||
graph.add(r#ref.clone(), nam.clone());
|
||||
}
|
||||
if let Tree::Ref { nam } = right {
|
||||
if let Tree::Ref { nam, .. } = right {
|
||||
graph.add(r#ref.clone(), nam.clone());
|
||||
}
|
||||
}
|
34
src/lib.rs
34
src/lib.rs
@ -3,18 +3,18 @@
|
||||
|
||||
use crate::fun::{book_to_nets, net_to_term::net_to_term, term_to_net::Labels, Book, Ctx, Term};
|
||||
use diagnostics::{Diagnostics, DiagnosticsConfig, ERR_INDENT_SIZE};
|
||||
use hvmc::ast::Net;
|
||||
use hvmc_net::{
|
||||
use hvm::{
|
||||
add_recursive_priority::add_recursive_priority,
|
||||
check_net_size::{check_net_sizes, MAX_NET_SIZE},
|
||||
mutual_recursion,
|
||||
reorder_redexes::reorder_redexes_recursive_last,
|
||||
};
|
||||
use hvmc::ast::Net;
|
||||
use net::hvmc_to_net::hvmc_to_net;
|
||||
use std::{process::Output, str::FromStr};
|
||||
|
||||
pub mod diagnostics;
|
||||
pub mod fun;
|
||||
pub mod hvmc_net;
|
||||
pub mod hvm;
|
||||
pub mod imp;
|
||||
pub mod net;
|
||||
|
||||
@ -41,20 +41,20 @@ pub fn compile_book(
|
||||
) -> Result<CompileResult, Diagnostics> {
|
||||
let mut diagnostics = desugar_book(book, opts.clone(), diagnostics_cfg, args)?;
|
||||
|
||||
let (mut core_book, labels) = book_to_nets(book, &mut diagnostics)?;
|
||||
let (mut hvm_book, labels) = book_to_nets(book, &mut diagnostics)?;
|
||||
|
||||
if opts.eta {
|
||||
core_book.values_mut().for_each(Net::eta_reduce);
|
||||
hvm_book.values_mut().for_each(Net::eta_reduce);
|
||||
}
|
||||
|
||||
mutual_recursion::check_cycles(&core_book, &mut diagnostics)?;
|
||||
mutual_recursion::check_cycles(&hvm_book, &mut diagnostics)?;
|
||||
if opts.eta {
|
||||
core_book.values_mut().for_each(Net::eta_reduce);
|
||||
hvm_book.values_mut().for_each(Net::eta_reduce);
|
||||
}
|
||||
|
||||
if opts.inline {
|
||||
diagnostics.start_pass();
|
||||
if let Err(e) = core_book.inline() {
|
||||
if let Err(e) = hvm_book.inline() {
|
||||
diagnostics.add_book_error(format!("During inlining:\n{:ERR_INDENT_SIZE$}{}", "", e));
|
||||
}
|
||||
diagnostics.fatal(())?;
|
||||
@ -62,16 +62,14 @@ pub fn compile_book(
|
||||
|
||||
if opts.prune {
|
||||
let prune_entrypoints = vec![book.hvmc_entrypoint().to_string()];
|
||||
core_book.prune(&prune_entrypoints);
|
||||
hvm_book.prune(&prune_entrypoints);
|
||||
}
|
||||
|
||||
check_net_sizes(&core_book, &mut diagnostics)?;
|
||||
check_net_sizes(&hvm_book, &mut diagnostics)?;
|
||||
|
||||
if opts.recursive_last {
|
||||
reorder_redexes_recursive_last(&mut core_book);
|
||||
}
|
||||
add_recursive_priority(&mut hvm_book);
|
||||
|
||||
Ok(CompileResult { core_book, labels, diagnostics })
|
||||
Ok(CompileResult { core_book: hvm_book, labels, diagnostics })
|
||||
}
|
||||
|
||||
pub fn desugar_book(
|
||||
@ -238,9 +236,6 @@ pub struct CompileOpts {
|
||||
|
||||
/// Enables [fun::transform::inline].
|
||||
pub inline: bool,
|
||||
|
||||
/// Enables [hvmc_net::reorder_redexes::reorder_redexes_recursive_last].
|
||||
pub recursive_last: bool,
|
||||
}
|
||||
|
||||
impl CompileOpts {
|
||||
@ -253,7 +248,6 @@ impl CompileOpts {
|
||||
float_combinators: true,
|
||||
merge: true,
|
||||
inline: true,
|
||||
recursive_last: true,
|
||||
linearize_matches: OptLevel::Enabled,
|
||||
}
|
||||
}
|
||||
@ -268,7 +262,6 @@ impl CompileOpts {
|
||||
float_combinators: false,
|
||||
merge: false,
|
||||
inline: false,
|
||||
recursive_last: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +289,6 @@ impl Default for CompileOpts {
|
||||
float_combinators: true,
|
||||
merge: false,
|
||||
inline: false,
|
||||
recursive_last: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,8 +161,6 @@ pub enum OptArgs {
|
||||
NoMerge,
|
||||
Inline,
|
||||
NoInline,
|
||||
RecursiveLast,
|
||||
NoRecursiveLast,
|
||||
}
|
||||
|
||||
fn compile_opts_from_cli(args: &Vec<OptArgs>) -> CompileOpts {
|
||||
@ -183,8 +181,6 @@ fn compile_opts_from_cli(args: &Vec<OptArgs>) -> CompileOpts {
|
||||
NoMerge => opts.merge = false,
|
||||
Inline => opts.inline = true,
|
||||
NoInline => opts.inline = false,
|
||||
RecursiveLast => opts.recursive_last = true,
|
||||
NoRecursiveLast => opts.recursive_last = false,
|
||||
|
||||
LinearizeMatches => opts.linearize_matches = OptLevel::Enabled,
|
||||
LinearizeMatchesAlt => opts.linearize_matches = OptLevel::Alt,
|
||||
|
@ -22,7 +22,7 @@ fn hvmc_to_inodes(net: &Net) -> INodes {
|
||||
}
|
||||
|
||||
// Convert all the trees forming active pairs.
|
||||
for (i, (tree1, tree2)) in net.redexes.iter().enumerate() {
|
||||
for (i, (_, tree1, tree2)) in net.redexes.iter().enumerate() {
|
||||
let tree_root = format!("a{i}");
|
||||
let mut tree1 = tree_to_inodes(tree1, tree_root.clone(), net_root, &mut n_vars);
|
||||
inodes.append(&mut tree1);
|
||||
|
@ -1,10 +1,7 @@
|
||||
use bend::{
|
||||
compile_book, desugar_book,
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
|
||||
fun::{
|
||||
load_book::do_parse_core_book, net_to_term::net_to_term, parser::TermParser, term_to_net::Labels, Book,
|
||||
Ctx, Name,
|
||||
},
|
||||
fun::{load_book::do_parse_core_book, net_to_term::net_to_term, term_to_net::Labels, Book, Ctx, Name},
|
||||
net::hvmc_to_net::hvmc_to_net,
|
||||
run_book, CompileOpts, RunOpts,
|
||||
};
|
||||
@ -93,25 +90,6 @@ fn run_golden_test_dir_multiple(test_name: &str, run: &[&RunFn]) {
|
||||
and what to save as a snapshot.
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn compile_term() {
|
||||
run_golden_test_dir(function_name!(), &|code, _| {
|
||||
let mut term = TermParser::new(code).parse_term()?;
|
||||
let mut vec = Vec::new();
|
||||
term.check_unbound_vars(&mut HashMap::new(), &mut vec);
|
||||
|
||||
if !vec.is_empty() {
|
||||
return Err(vec.into_iter().map(|e| e.to_string()).join("\n").into());
|
||||
}
|
||||
|
||||
term.make_var_names_unique();
|
||||
term.linearize_vars();
|
||||
let net = bend::fun::term_to_net(&term, &mut Default::default()).map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(format!("{}", net))
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_file() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
|
1
tests/golden_tests/compile_file/addition.hvm
Normal file
1
tests/golden_tests/compile_file/addition.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (λx (+ (+ 1 1) x) 8)
|
1
tests/golden_tests/compile_file/church_one.hvm
Normal file
1
tests/golden_tests/compile_file/church_one.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (λk λs λz let {s0 s1} = s; (s0 ((k s1) z)) λq λw w)
|
1
tests/golden_tests/compile_file/church_zero.hvm
Normal file
1
tests/golden_tests/compile_file/church_zero.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = λs λz z
|
1
tests/golden_tests/compile_file/complicated_dup.hvm
Normal file
1
tests/golden_tests/compile_file/complicated_dup.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = let {x1 x2} = ($a $b); λy let {y1 y2} = y; (λ$a (y1 x1) λ$b (y2 x2))
|
1
tests/golden_tests/compile_file/cyclic_global_lam.hvm
Normal file
1
tests/golden_tests/compile_file/cyclic_global_lam.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = λa ($a λ$a a)
|
1
tests/golden_tests/compile_file/dup_apply.hvm
Normal file
1
tests/golden_tests/compile_file/dup_apply.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = λa let {a1 a2} = a; (a1 a2)
|
1
tests/golden_tests/compile_file/dup_global_lam.hvm
Normal file
1
tests/golden_tests/compile_file/dup_global_lam.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = let {x1 x2} = $a; ((λ$a λb b) (x1 x2))
|
1
tests/golden_tests/compile_file/erased_dup.hvm
Normal file
1
tests/golden_tests/compile_file/erased_dup.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = λa let {a1 a2} = a; a2
|
1
tests/golden_tests/compile_file/f24_oper.hvm
Normal file
1
tests/golden_tests/compile_file/f24_oper.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (/ (* +124.0928 1.24) (+ 0.0 -235.12235))
|
@ -1,3 +1,4 @@
|
||||
main =
|
||||
let fst = (@t let (f, *) = t; f);
|
||||
let snd = (@t let (*, s) = t; s);
|
||||
(snd (fst ((1, 3), 2)))
|
1
tests/golden_tests/compile_file/global_lam.hvm
Normal file
1
tests/golden_tests/compile_file/global_lam.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = ((λ$a λa a) $a)
|
1
tests/golden_tests/compile_file/i24_oper.hvm
Normal file
1
tests/golden_tests/compile_file/i24_oper.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (* (+ +1 -1) (- -12 +14))
|
1
tests/golden_tests/compile_file/id.hvm
Normal file
1
tests/golden_tests/compile_file/id.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = λa a
|
1
tests/golden_tests/compile_file/infer_dup.hvm
Normal file
1
tests/golden_tests/compile_file/infer_dup.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = λa (a a)
|
1
tests/golden_tests/compile_file/let_substitution.hvm
Normal file
1
tests/golden_tests/compile_file/let_substitution.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = let x = λa (a a); x
|
1
tests/golden_tests/compile_file/let_tup.hvm
Normal file
1
tests/golden_tests/compile_file/let_tup.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = let tup = (@x@y x, @x@y y); tup
|
@ -1,3 +1,4 @@
|
||||
main =
|
||||
let a0 = λx0 x0;
|
||||
let a1 = λx1 x1;
|
||||
let a2 = λx2 x2;
|
4
tests/golden_tests/compile_file/match.hvm
Normal file
4
tests/golden_tests/compile_file/match.hvm
Normal file
@ -0,0 +1,4 @@
|
||||
main = switch x = (+ 0 1) {
|
||||
0: λt λf t
|
||||
_: λt λf f
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
main =
|
||||
let (a, b) = ((2, 4), (3, 6));
|
||||
let (a1, a2) = a;
|
||||
let (b1, b2) = b;
|
1
tests/golden_tests/compile_file/number_too_large.hvm
Normal file
1
tests/golden_tests/compile_file/number_too_large.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = 0x10000000
|
1
tests/golden_tests/compile_file/nums.hvm
Normal file
1
tests/golden_tests/compile_file/nums.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (+ 0xFF_FFFF (+ 0b101 1_000))
|
1
tests/golden_tests/compile_file/op2.hvm
Normal file
1
tests/golden_tests/compile_file/op2.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (% (+ (- (* (/ (< (> (| (& (== (!= 0 1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11)
|
@ -1,3 +1,5 @@
|
||||
data Tree = (Tree.node lft rgt) | (Tree.leaf val)
|
||||
|
||||
tail_recursive = @x (x @pred @acc (tail_recursive pred (+ 1 acc)) @acc 0)
|
||||
|
||||
fold_ = @bm (bm
|
||||
@ -10,4 +12,91 @@ add = @a (a
|
||||
@b b
|
||||
)
|
||||
|
||||
List.sum xs acc = match xs {
|
||||
List.nil: acc
|
||||
List.cons: (List.sum xs.tail (+ xs.head acc))
|
||||
}
|
||||
|
||||
List.len xs = match xs {
|
||||
List.nil: 0
|
||||
List.cons: (+ 1 (List.len xs.tail))
|
||||
}
|
||||
|
||||
List.len_tr xs acc = match xs {
|
||||
List.nil: acc
|
||||
List.cons: (List.len_tr xs.tail (+ 1 acc))
|
||||
}
|
||||
|
||||
List.map xs f = match xs {
|
||||
List.nil: List.nil
|
||||
List.cons: (List.cons (f xs.head) (List.map xs.tail f))
|
||||
}
|
||||
|
||||
List.concat xs ys = match xs {
|
||||
List.nil: ys
|
||||
List.cons: (List.cons xs.head (List.concat xs.tail ys))
|
||||
}
|
||||
|
||||
List.reverse_bad xs = match xs {
|
||||
List.nil: List.nil
|
||||
List.cons: (List.concat (List.reverse_bad xs.tail) (List.cons xs.head List.nil))
|
||||
}
|
||||
|
||||
List.reverse_tr xs acc = (List.reverse_over xs List.nil)
|
||||
|
||||
List.fold xs c n = match xs {
|
||||
List.nil: n
|
||||
List.cons: (c xs.head (List.fold xs.tail c n))
|
||||
}
|
||||
|
||||
List.reduce xs f acc = match xs {
|
||||
List.nil: acc
|
||||
List.cons: (List.reduce xs.tail f (f acc xs.head))
|
||||
}
|
||||
|
||||
List.reverse_over xs ys = match xs {
|
||||
List.nil: ys
|
||||
List.cons: (List.reverse_over xs.tail (List.cons xs.head ys))
|
||||
}
|
||||
|
||||
Tree.leaves tree = match tree {
|
||||
Tree.leaf: 1
|
||||
Tree.node: (+ (Tree.leaves tree.lft) (Tree.leaves tree.rgt))
|
||||
}
|
||||
|
||||
Tree.nodes tree = match tree {
|
||||
Tree.leaf: 0
|
||||
Tree.node: (+ 1 (+ (Tree.nodes tree.lft) (Tree.nodes tree.rgt)))
|
||||
}
|
||||
|
||||
Tree.height tree = match tree {
|
||||
Tree.leaf: 0
|
||||
Tree.node: (+ 1 (max (Tree.height tree.lft) (Tree.height tree.rgt)))
|
||||
}
|
||||
|
||||
Tree.map tree f = match tree {
|
||||
Tree.leaf: (Tree.leaf (f tree.val))
|
||||
Tree.node: (Tree.node (Tree.map tree.lft f) (Tree.map tree.rgt f))
|
||||
}
|
||||
|
||||
max a b = switch (> a b) {
|
||||
0: b
|
||||
_: a
|
||||
}
|
||||
|
||||
Tree.flip tree = match tree {
|
||||
Tree.leaf: tree
|
||||
Tree.node: (Tree.node (Tree.flip tree.rgt) (Tree.flip tree.lft))
|
||||
}
|
||||
|
||||
calc =
|
||||
let n0 = 1
|
||||
let n1 = (* n0 n0)
|
||||
let n2 = (* n1 n1)
|
||||
let n3 = (* n2 n2)
|
||||
let n4 = (* n3 n3)
|
||||
let n5 = (* n4 n4)
|
||||
(Foo (+ n0 n1) (+ n2 n3) (+ n4 n5))
|
||||
Foo = @a @b @c @x (x a b c)
|
||||
|
||||
main = *
|
1
tests/golden_tests/compile_file/simple_tup.hvm
Normal file
1
tests/golden_tests/compile_file/simple_tup.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (0, 42)
|
1
tests/golden_tests/compile_file/tup.hvm
Normal file
1
tests/golden_tests/compile_file/tup.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = let x = ((1, 4), (2, 3)); x
|
1
tests/golden_tests/compile_file/tup_add.hvm
Normal file
1
tests/golden_tests/compile_file/tup_add.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = let (a, b) = (1, 2); (+ a b)
|
1
tests/golden_tests/compile_file/unbound_var.hvm
Normal file
1
tests/golden_tests/compile_file/unbound_var.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = a
|
@ -1,3 +1,3 @@
|
||||
// Fully parenthesized, this is (λa ((λb b) b)).
|
||||
// Since applications must have (), the second 'b' is not in scope
|
||||
λa (λb b b)
|
||||
main = λa (λb b b)
|
1
tests/golden_tests/compile_file/wrong_nums.hvm
Normal file
1
tests/golden_tests/compile_file/wrong_nums.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (+ 0b012345 0FA)
|
1
tests/golden_tests/compile_file/wrong_unicode_escape.hvm
Normal file
1
tests/golden_tests/compile_file/wrong_unicode_escape.hvm
Normal file
@ -0,0 +1 @@
|
||||
main = (String.cons '\u{1' "\u2}\u{zxcx}")
|
@ -1 +0,0 @@
|
||||
(λx (+ (+ 1 1) x) 8)
|
@ -1 +0,0 @@
|
||||
(λk λs λz let {s0 s1} = s; (s0 ((k s1) z)) λq λw w)
|
@ -1 +0,0 @@
|
||||
λs λz z
|
@ -1 +0,0 @@
|
||||
let {x1 x2} = ($a $b); λy let {y1 y2} = y; (λ$a (y1 x1) λ$b (y2 x2))
|
@ -1 +0,0 @@
|
||||
λa ($a λ$a a)
|
@ -1 +0,0 @@
|
||||
λa let {a1 a2} = a; (a1 a2)
|
@ -1 +0,0 @@
|
||||
let {x1 x2} = $a; ((λ$a λb b) (x1 x2))
|
@ -1 +0,0 @@
|
||||
λa let {a1 a2} = a; a2
|
@ -1 +0,0 @@
|
||||
(/ (* +124.0928 1.24) (+ 0.0 -235.12235))
|
@ -1 +0,0 @@
|
||||
((λ$a λa a) $a)
|
@ -1 +0,0 @@
|
||||
(* (+ +1 -1) (- -12 +14))
|
@ -1 +0,0 @@
|
||||
λa a
|
@ -1 +0,0 @@
|
||||
λa (a a)
|
@ -1 +0,0 @@
|
||||
let x = λa (a a); x
|
@ -1 +0,0 @@
|
||||
let tup = (@x@y x, @x@y y); tup
|
@ -1,4 +0,0 @@
|
||||
switch x = (+ 0 1) {
|
||||
0: λt λf t
|
||||
_: λ* λt λf f // The term to hvmc function assumes the pred variable is already detached from the match
|
||||
}
|
@ -1 +0,0 @@
|
||||
0x10000000
|
@ -1 +0,0 @@
|
||||
(+ 0xFF_FFFF (+ 0b101 1_000))
|
@ -1 +0,0 @@
|
||||
(+ (- (* (/ (< (> (| (& 1 2) 3) 4) 5) 6) 7) 8) 9)
|
@ -1 +0,0 @@
|
||||
(0, 42)
|
@ -1 +0,0 @@
|
||||
let x = ((1, 4), (2, 3)); x
|
@ -1 +0,0 @@
|
||||
let (a, b) = (1, 2); (+ a b)
|
@ -1 +0,0 @@
|
||||
a
|
@ -1 +0,0 @@
|
||||
(+ 0b012345 0FA)
|
@ -1 +0,0 @@
|
||||
(String.cons '\u{1' "\u2}\u{zxcx}")
|
@ -3,7 +3,7 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_no_opts.hvm
|
||||
---
|
||||
error: invalid value 'no-pre-reduce' for '-O <COMP_OPTS>'
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
||||
|
||||
tip: a similar value exists: 'no-prune'
|
||||
|
||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_pre_reduce.hvm
|
||||
---
|
||||
error: invalid value 'pre-reduce' for '-O <COMP_OPTS>'
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
||||
|
||||
For more information, try '--help'.
|
||||
|
@ -3,7 +3,7 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_wrong_opt.hvm
|
||||
---
|
||||
error: invalid value 'foo' for '-O <COMP_OPTS>'
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
||||
|
||||
tip: a similar value exists: 'float-combinators'
|
||||
|
||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/desugar_bool_scott.hvm
|
||||
---
|
||||
error: invalid value 'adt-scott' for '-O <COMP_OPTS>'
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
||||
|
||||
For more information, try '--help'.
|
||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/desugar_bool_tagged.hvm
|
||||
---
|
||||
error: invalid value 'adt-tagged-scott' for '-O <COMP_OPTS>'
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline, recursive-last, no-recursive-last]
|
||||
[possible values: all, no-all, eta, no-eta, prune, no-prune, linearize-matches, linearize-matches-alt, no-linearize-matches, float-combinators, no-float-combinators, merge, no-merge, inline, no-inline]
|
||||
|
||||
For more information, try '--help'.
|
||||
|
9
tests/snapshots/compile_file__addition.hvm.snap
Normal file
9
tests/snapshots/compile_file__addition.hvm.snap
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/addition.hvm
|
||||
---
|
||||
@main = a
|
||||
& @main__C0 ~ (8 a)
|
||||
|
||||
@main__C0 = (a b)
|
||||
& $(1 $(:[+] $(a b))) ~ [+1]
|
8
tests/snapshots/compile_file__church_one.hvm.snap
Normal file
8
tests/snapshots/compile_file__church_one.hvm.snap
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/church_one.hvm
|
||||
---
|
||||
@main = b
|
||||
& @main__C0 ~ ((* (a a)) b)
|
||||
|
||||
@main__C0 = ((a (b c)) ({(c d) a} (b d)))
|
5
tests/snapshots/compile_file__church_zero.hvm.snap
Normal file
5
tests/snapshots/compile_file__church_zero.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/church_zero.hvm
|
||||
---
|
||||
@main = (* (a a))
|
6
tests/snapshots/compile_file__complicated_dup.hvm.snap
Normal file
6
tests/snapshots/compile_file__complicated_dup.hvm.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/complicated_dup.hvm
|
||||
---
|
||||
@main = ({(a b) (d e)} f)
|
||||
& ((c {a d}) b) ~ ((c e) f)
|
7
tests/snapshots/compile_file__cyclic_global_lam.hvm.snap
Normal file
7
tests/snapshots/compile_file__cyclic_global_lam.hvm.snap
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/cyclic_global_lam.hvm
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
[1mIn compiled inet '[4mmain[0m[1m':[0m
|
||||
Found term that compiles into an inet with a vicious cycle
|
5
tests/snapshots/compile_file__dup_apply.hvm.snap
Normal file
5
tests/snapshots/compile_file__dup_apply.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/dup_apply.hvm
|
||||
---
|
||||
@main = ({(a b) a} b)
|
6
tests/snapshots/compile_file__dup_global_lam.hvm.snap
Normal file
6
tests/snapshots/compile_file__dup_global_lam.hvm.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/dup_global_lam.hvm
|
||||
---
|
||||
@main = d
|
||||
& ({(b c) b} (a a)) ~ (c d)
|
5
tests/snapshots/compile_file__erased_dup.hvm.snap
Normal file
5
tests/snapshots/compile_file__erased_dup.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/erased_dup.hvm
|
||||
---
|
||||
@main = ({* a} a)
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_term/f24_oper.hvm
|
||||
input_file: tests/golden_tests/compile_file/f24_oper.hvm
|
||||
---
|
||||
b
|
||||
@main = b
|
||||
& $(1.240 $(:[/] $(a b))) ~ [*4583519]
|
||||
& $(-235.121 a) ~ [+0]
|
13
tests/snapshots/compile_file__fst_snd.hvm.snap
Normal file
13
tests/snapshots/compile_file__fst_snd.hvm.snap
Normal file
@ -0,0 +1,13 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/fst_snd.hvm
|
||||
---
|
||||
@main = a
|
||||
& @main__C2 ~ (@main__C1 a)
|
||||
|
||||
@main__C0 = ((a *) a)
|
||||
|
||||
@main__C1 = a
|
||||
& @main__C0 ~ (((1 3) 2) a)
|
||||
|
||||
@main__C2 = ((* a) a)
|
6
tests/snapshots/compile_file__global_lam.hvm.snap
Normal file
6
tests/snapshots/compile_file__global_lam.hvm.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/global_lam.hvm
|
||||
---
|
||||
@main = c
|
||||
& (b (a a)) ~ (b c)
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_term/i24_oper.hvm
|
||||
input_file: tests/golden_tests/compile_file/i24_oper.hvm
|
||||
---
|
||||
b
|
||||
@main = b
|
||||
& $(-1 $(:[*] $(a b))) ~ [+1]
|
||||
& $(+14 a) ~ [-16777204]
|
5
tests/snapshots/compile_file__id.hvm.snap
Normal file
5
tests/snapshots/compile_file__id.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/id.hvm
|
||||
---
|
||||
@main = (a a)
|
5
tests/snapshots/compile_file__infer_dup.hvm.snap
Normal file
5
tests/snapshots/compile_file__infer_dup.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/infer_dup.hvm
|
||||
---
|
||||
@main = ({(a b) a} b)
|
5
tests/snapshots/compile_file__let_substitution.hvm.snap
Normal file
5
tests/snapshots/compile_file__let_substitution.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/let_substitution.hvm
|
||||
---
|
||||
@main = ({(a b) a} b)
|
5
tests/snapshots/compile_file__let_tup.hvm.snap
Normal file
5
tests/snapshots/compile_file__let_tup.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/let_tup.hvm
|
||||
---
|
||||
@main = ((a (* a)) (* (b b)))
|
12
tests/snapshots/compile_file__lets.hvm.snap
Normal file
12
tests/snapshots/compile_file__lets.hvm.snap
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/lets.hvm
|
||||
---
|
||||
@main = @main__C0
|
||||
& (a a) ~ *
|
||||
|
||||
@main__C0 = n
|
||||
& (a a) ~ (f (i (m n)))
|
||||
& (d d) ~ {(e f) e}
|
||||
& (c c) ~ {(g (h i)) {g h}}
|
||||
& (b b) ~ {(j (k (l m))) {j {k l}}}
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_term/match.hvm
|
||||
input_file: tests/golden_tests/compile_file/match.hvm
|
||||
---
|
||||
c
|
||||
@main = c
|
||||
& $(1 ?(((a (* a)) (* (* (b b)))) c)) ~ [+0]
|
6
tests/snapshots/compile_file__nested_let.hvm.snap
Normal file
6
tests/snapshots/compile_file__nested_let.hvm.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/nested_let.hvm
|
||||
---
|
||||
@main = a
|
||||
& ((2 4) (3 6)) ~ (* (a *))
|
8
tests/snapshots/compile_file__number_too_large.hvm.snap
Normal file
8
tests/snapshots/compile_file__number_too_large.hvm.snap
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/number_too_large.hvm
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
In tests/golden_tests/compile_file/number_too_large.hvm :
|
||||
[1mNumber literal outside of range for U24.[0m
|
||||
[0m 1 | main = [4m[31m0x10000000[0m
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_term/nums.hvm
|
||||
input_file: tests/golden_tests/compile_file/nums.hvm
|
||||
---
|
||||
b
|
||||
@main = b
|
||||
& $(a b) ~ [+16777215]
|
||||
& $(1000 a) ~ [+5]
|
6
tests/snapshots/compile_file__op2.hvm.snap
Normal file
6
tests/snapshots/compile_file__op2.hvm.snap
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/op2.hvm
|
||||
---
|
||||
@main = a
|
||||
& $(1 $([=2] $([&3] $([|4] $([>5] $([<6] $([/7] $([*8] $([-9] $([+10] $([%11] a))))))))))) ~ [!0]
|
@ -2,11 +2,121 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/redex_order_recursive.hvm
|
||||
---
|
||||
@Foo = (a (b (c ((a (b (c d))) d))))
|
||||
|
||||
@List.concat = ((@List.concat__C0 ((a a) b)) b)
|
||||
|
||||
@List.concat__C0 = (a (b (c e)))
|
||||
& @List.cons ~ (a (d e))
|
||||
& @List.concat ~ (b (c d))
|
||||
|
||||
@List.cons = (a (b ((a (b c)) (* c))))
|
||||
|
||||
@List.fold = ((@List.fold__C0 ((a (* a)) (b (c d)))) (c (b d)))
|
||||
|
||||
@List.fold__C0 = (a (b (d ({(a (e f)) c} f))))
|
||||
& @List.fold ~ (b (c (d e)))
|
||||
|
||||
@List.len = ((@List.len__C0 (0 a)) a)
|
||||
|
||||
@List.len__C0 = (* (a c))
|
||||
& $(b c) ~ [+1]
|
||||
& @List.len ~ (a b)
|
||||
|
||||
@List.len_tr = ((@List.len_tr__C0 ((a a) b)) b)
|
||||
|
||||
@List.len_tr__C0 = (* (a (b d)))
|
||||
& @List.len_tr ~ (a (c d))
|
||||
& $(b c) ~ [+1]
|
||||
|
||||
@List.map = ((@List.map__C0 ((* @List.nil) a)) a)
|
||||
|
||||
@List.map__C0 = (a (c ({(a b) d} f)))
|
||||
& @List.cons ~ (b (e f))
|
||||
& @List.map ~ (c (d e))
|
||||
|
||||
@List.nil = (* (a a))
|
||||
|
||||
@List.reduce = ((@List.reduce__C0 ((a (* a)) (b (c d)))) (c (b d)))
|
||||
|
||||
@List.reduce__C0 = (d (a (c ({b (c (d e))} f))))
|
||||
& @List.reduce ~ (a (b (e f)))
|
||||
|
||||
@List.reverse_bad = ((@List.reverse_bad__C0 (@List.nil a)) a)
|
||||
|
||||
@List.reverse_bad__C0 = (c (a e))
|
||||
& @List.concat ~ (b (d e))
|
||||
& @List.reverse_bad ~ (a b)
|
||||
& @List.cons ~ (c (@List.nil d))
|
||||
|
||||
@List.reverse_over = ((@List.reverse_over__C0 ((a a) b)) b)
|
||||
|
||||
@List.reverse_over__C0 = (b (a (c e)))
|
||||
& @List.reverse_over ~ (a (d e))
|
||||
& @List.cons ~ (b (c d))
|
||||
|
||||
@List.reverse_tr = (a (* b))
|
||||
& @List.reverse_over ~ (a (@List.nil b))
|
||||
|
||||
@List.sum = ((@List.sum__C0 ((a a) b)) b)
|
||||
|
||||
@List.sum__C0 = ($(:[+] $(b c)) (a (b d)))
|
||||
& @List.sum ~ (a (c d))
|
||||
|
||||
@Tree.flip = ((@Tree.flip__C1 (@Tree.flip__C0 a)) a)
|
||||
|
||||
@Tree.flip__C0 = a
|
||||
& @Tree.leaf ~ a
|
||||
|
||||
@Tree.flip__C1 = (c (a e))
|
||||
& @Tree.node ~ (b (d e))
|
||||
& @Tree.flip ~ (a b)
|
||||
&! @Tree.flip ~ (c d)
|
||||
|
||||
@Tree.height = ((@Tree.height__C0 ((* 0) a)) a)
|
||||
|
||||
@Tree.height__C0 = (a (c f))
|
||||
& $(e f) ~ [+1]
|
||||
& @max ~ (b (d e))
|
||||
& @Tree.height ~ (a b)
|
||||
&! @Tree.height ~ (c d)
|
||||
|
||||
@Tree.leaf = (a (* ((a b) b)))
|
||||
|
||||
@Tree.leaves = ((@Tree.leaves__C0 ((* 1) a)) a)
|
||||
|
||||
@Tree.leaves__C0 = (a (b d))
|
||||
& @Tree.leaves ~ (a $(:[+] $(c d)))
|
||||
&! @Tree.leaves ~ (b c)
|
||||
|
||||
@Tree.map = ((@Tree.map__C1 (@Tree.map__C0 a)) a)
|
||||
|
||||
@Tree.map__C0 = (a ((a b) c))
|
||||
& @Tree.leaf ~ (b c)
|
||||
|
||||
@Tree.map__C1 = (a (d ({b e} g)))
|
||||
& @Tree.node ~ (c (f g))
|
||||
& @Tree.map ~ (a (b c))
|
||||
&! @Tree.map ~ (d (e f))
|
||||
|
||||
@Tree.node = (a (b ((a (b c)) (* c))))
|
||||
|
||||
@Tree.nodes = ((@Tree.nodes__C0 ((* 0) a)) a)
|
||||
|
||||
@Tree.nodes__C0 = (a (b e))
|
||||
& $(d e) ~ [+1]
|
||||
& @Tree.nodes ~ (a $(:[+] $(c d)))
|
||||
&! @Tree.nodes ~ (b c)
|
||||
|
||||
@add = ((@add__C0 ((a a) b)) b)
|
||||
|
||||
@add__C0 = (a (b d))
|
||||
& @add ~ (a (((b c) (* c)) d))
|
||||
|
||||
@calc = l
|
||||
& @Foo ~ (f (h (k l)))
|
||||
& 1 ~ {$(:[+] $(e f)) {$(:[*] $(a {e {$(:[*] $(b {$(:[+] $(g h)) {$(:[*] $(c {g {$(:[*] $(d {$(:[+] $(j k)) {$(:[*] $(i j)) i}})) d}})) c}})) b}})) a}}
|
||||
|
||||
@fold_ = ((@fold___C1 (@fold___C0 a)) a)
|
||||
|
||||
@fold___C0 = (((* (a a)) b) (* b))
|
||||
@ -14,10 +124,12 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.hvm
|
||||
@fold___C1 = (a (c e))
|
||||
& @add ~ (b (d e))
|
||||
& @fold_ ~ (a b)
|
||||
& @fold_ ~ (c d)
|
||||
&! @fold_ ~ (c d)
|
||||
|
||||
@main = *
|
||||
|
||||
@max = ({$(:[>] $(a ?(((b (* b)) (* (* (c c)))) (d (e f))))) e} ({a d} f))
|
||||
|
||||
@tail_recursive = ((@tail_recursive__C0 ((* 0) a)) a)
|
||||
|
||||
@tail_recursive__C0 = (a (b d))
|
||||
|
5
tests/snapshots/compile_file__simple_tup.hvm.snap
Normal file
5
tests/snapshots/compile_file__simple_tup.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/simple_tup.hvm
|
||||
---
|
||||
@main = (0 42)
|
5
tests/snapshots/compile_file__tup.hvm.snap
Normal file
5
tests/snapshots/compile_file__tup.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/tup.hvm
|
||||
---
|
||||
@main = ((1 4) (2 3))
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_term/tup_add.hvm
|
||||
input_file: tests/golden_tests/compile_file/tup_add.hvm
|
||||
---
|
||||
b
|
||||
@main = b
|
||||
& (1 2) ~ ($(:[+] $(a b)) a)
|
7
tests/snapshots/compile_file__unbound_var.hvm.snap
Normal file
7
tests/snapshots/compile_file__unbound_var.hvm.snap
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/unbound_var.hvm
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
[1mIn definition '[4mmain[0m[1m':[0m
|
||||
Unbound variable 'a'.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user