mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 03:45:29 +03:00
[sc-663] Add num-scott adt encoding, it a cli opt
This commit is contained in:
parent
add15416db
commit
f7a238c58a
@ -101,7 +101,7 @@ def Maybe/or_default(x, default):
|
||||
return default
|
||||
```
|
||||
|
||||
### Folding
|
||||
### Folding and bending
|
||||
|
||||
We use `~` to indicate that a field is recursive.
|
||||
This allows us to easily create and consume these recursive data structures with `bend` and `fold`.
|
||||
@ -152,7 +152,7 @@ def main:
|
||||
return MyTree.sum(x)
|
||||
```
|
||||
|
||||
Making your program around trees is a very good way of making it parallelizable, since each core can be dispatched to work on a different branch of the tree.
|
||||
Making your program around folding trees is a very good way of making it parallelizable, since each core can be dispatched to work on a different branch of the tree.
|
||||
|
||||
You can also pass some state variables to `fold` just like the variables used in a `bend`.
|
||||
If you give a `fold` some state, then you necessarily need to pass it by calling the folded fields of the matched value, like passing an additional argument to the fold call.
|
||||
|
@ -15,14 +15,14 @@ Arguments are passed to programs by applying them to the entrypoint function:
|
||||
def main(x1, x2, x3):
|
||||
return MainBody(x1 x2 x3)
|
||||
|
||||
// Calling with `bend run <file> arg1 arg2 arg3 argN`, it becomes (in the "fun" syntax):
|
||||
# Calling with `bend run <file> arg1 arg2 arg3 argN`, it becomes (in the "fun" syntax):
|
||||
main = (x1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3 argN)
|
||||
```
|
||||
|
||||
There are no restrictions on the number of arguments passed to the program.
|
||||
You can even pass more arguments than the function expects, although that can lead to unexpected results.
|
||||
```rust
|
||||
// Expects 2 CLI arguments
|
||||
```py
|
||||
# Expects 2 CLI arguments
|
||||
def main(x, y):
|
||||
return {x - y, y - x}
|
||||
```
|
||||
|
@ -11,6 +11,7 @@
|
||||
| `-Omerge` `-Ono-merge` | Disabled | [definition-merging](#definition-merging) |
|
||||
| `-Oinline` `-Ono-inline` | Disabled | [inline](#inline) |
|
||||
| `-Ocheck-net-size` `-Ono-check-net-size` | Enabled | [check-net-size](#check-net-size) |
|
||||
| `-Oadt-scott` `-Oadt-num-scott` | adt-num-scott | [adt-encoding](#adt-encoding) | |
|
||||
|
||||
## Eta-reduction
|
||||
|
||||
@ -130,7 +131,7 @@ These automatic linearization passes are done before the manual linearization fr
|
||||
# These variables are only linearized once
|
||||
λa λb λc switch a with b c { 0: (b c); _: (a-1 b c) }
|
||||
|
||||
# With -Olinearize-matches-extra becomes
|
||||
# With -Olinearize-matches becomes
|
||||
λa λb λc (switch a { 0: λb λc (b c); _: λb λc (a-1 b c) } b c)
|
||||
|
||||
# And not
|
||||
@ -160,21 +161,26 @@ fold = λinit λf λxs (xs λh λt (fold (f init h) f t) init)
|
||||
|
||||
# Inline
|
||||
|
||||
If enabled, inlines terms that compiles to 0 or 1 inet nodes at lambda level, before pre reduction.
|
||||
If enabled, inlines terms that compile to nullary inet nodes (refs, numbers, erasures).
|
||||
|
||||
Example:
|
||||
```py
|
||||
foo = (2, 3)
|
||||
# program
|
||||
foo = 2
|
||||
id = λx x
|
||||
|
||||
main = (id foo)
|
||||
|
||||
# -Oinline, compilation output
|
||||
@foo = [#2 #3]
|
||||
# -Ono-inline, compilation output
|
||||
@foo = 2
|
||||
@id = (a a)
|
||||
|
||||
@main = a
|
||||
& (b b) ~ ([#2 #3] a)
|
||||
& @id ~ (@foo a)
|
||||
|
||||
# -Oinline, compilation output
|
||||
@foo = 2
|
||||
@id = (a a)
|
||||
@main = a
|
||||
& @id ~ (2 a)
|
||||
```
|
||||
|
||||
## Check-net-size
|
||||
@ -214,3 +220,29 @@ Example:
|
||||
let r = (Swap (& n 8388608) r Map_/Free)
|
||||
r
|
||||
```
|
||||
|
||||
## ADT Encoding
|
||||
|
||||
Selects the lambda encoding for types defined with `data`, `type` and `object`.
|
||||
|
||||
`-Oadt-scott` uses Scott encoding.
|
||||
`-Oadt-num-scott` uses a variation of Scott encoding where instead of one lambda per constructor, we use a numeric tag to indicate which constructor it is. The numeric tag is assigned to the constructors in the order they are defined.
|
||||
|
||||
```py
|
||||
# Generates functions Option/Some and Option/None
|
||||
type Option:
|
||||
Some { value }
|
||||
None
|
||||
|
||||
# With -Oadt-scott they become:
|
||||
Option/Some = λvalue λSome λNone (Some value)
|
||||
Option/None = λSome λNone (None)
|
||||
|
||||
# With -Oadt-num-scott they become:
|
||||
Option/Some = λvalue λx (x 0 value)
|
||||
Option/None = λx (x 1)
|
||||
```
|
||||
|
||||
Pattern-matching with `match` and `fold` is generated according to the encoding.
|
||||
|
||||
Note: IO is **only** available with `-Oadt-num-scott`.
|
||||
|
@ -342,9 +342,9 @@ The monadic bind function should be of type `(Result a) -> (a -> Result b) -> Re
|
||||
```python
|
||||
def Result/bind(res, nxt):
|
||||
match res:
|
||||
case Result/ok:
|
||||
case Result/Ok:
|
||||
return nxt(res.value)
|
||||
case Result/err:
|
||||
case Result/Err:
|
||||
return res
|
||||
```
|
||||
|
||||
@ -915,17 +915,17 @@ match x {
|
||||
### Monadic bind blocks
|
||||
|
||||
```rust
|
||||
Result/bind (Result.ok val) f = (f val)
|
||||
Result/bind (Result/Ok val) f = (f val)
|
||||
Result/bind err _ = err
|
||||
|
||||
div a b = switch b {
|
||||
0: (Result.err "Div by 0")
|
||||
_: (Result.ok (/ a b))
|
||||
0: (Result/Err "Div by 0")
|
||||
_: (Result/Ok (/ a b))
|
||||
}
|
||||
|
||||
rem a b = switch b {
|
||||
0: (Result.err "Mod by 0")
|
||||
_: (Result.ok (% a b))
|
||||
0: (Result/Err "Mod by 0")
|
||||
_: (Result/Ok (% a b))
|
||||
}
|
||||
|
||||
Main = do Result {
|
||||
|
@ -1,5 +1,5 @@
|
||||
data String = (Cons head ~tail) | (Nil)
|
||||
data List = (Cons head ~tail) | (Nil)
|
||||
data String = (Nil) | (Cons head ~tail)
|
||||
data List = (Nil) | (Cons head ~tail)
|
||||
data Result = (Ok val) | (Err val)
|
||||
data Nat = (Succ ~pred) | (Zero)
|
||||
|
||||
@ -69,32 +69,3 @@ data IO
|
||||
| (GetTime cont)
|
||||
| (Sleep time cont)
|
||||
| (DrawImage tree cont)
|
||||
|
||||
MkStr (String/Cons x xs) = λt (t STRING_CONS_TAG x (MkStr xs))
|
||||
MkStr (String/Nil) = λt (t STRING_NIL_TAG)
|
||||
|
||||
ReadStr s = (s λtag switch tag {
|
||||
0: String/Nil
|
||||
_: λx λxs (String/Cons x (ReadStr xs))
|
||||
})
|
||||
|
||||
MkIO (IO/Done term) = λt (t IO_DONE_TAG term)
|
||||
MkIO (IO/PutText text cont) = λt (t IO_PUT_TEXT_TAG text λx (MkIO (cont x)))
|
||||
MkIO (IO/GetText cont) = λt (t IO_GET_TEXT_TAG λx (MkIO (cont x)))
|
||||
MkIO (IO/WriteFile file data cont) = λt (t IO_WRITE_FILE_TAG file data λx (MkIO (cont x)))
|
||||
MkIO (IO/ReadFile file cont) = λt (t IO_READ_FILE_TAG file λx(MkIO (cont x)))
|
||||
MkIO (IO/GetTime cont) = λt (t IO_GET_TIME_TAG λx (MkIO (cont x)))
|
||||
MkIO (IO/Sleep time cont) = λt (t IO_SLEEP_TAG time λx (MkIO (cont x)))
|
||||
MkIO (IO/DrawImage tree cont) = λt (t IO_DRAW_IMAGE_TAG tree λx (MkIO (cont x)))
|
||||
|
||||
ReadIO io = (io λtag switch tag {
|
||||
0: λterm (IO/Done term)
|
||||
1: λtext (IO/PutText (ReadStr text) λcont (ReadIO cont))
|
||||
2: (IO/GetText λcont (ReadIO cont))
|
||||
3: λfile λdata (IO/WriteFile file data λcont (ReadIO cont))
|
||||
4: λfile (IO/ReadFile file λcont (ReadIO cont))
|
||||
5: (IO/GetTime λcont (ReadIO cont))
|
||||
6: λtime (IO/Sleep time λcont (ReadIO cont))
|
||||
7: λtree (IO/DrawImage tree λcont (ReadIO cont))
|
||||
_: *
|
||||
})
|
||||
|
@ -6,6 +6,7 @@ const BUILTINS: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/src/fu
|
||||
pub const LIST: &str = "List";
|
||||
pub const LCONS: &str = "List/Cons";
|
||||
pub const LNIL: &str = "List/Nil";
|
||||
pub const LCONS_TAG: u32 = 1;
|
||||
|
||||
pub const HEAD: &str = "head";
|
||||
pub const TAIL: &str = "tail";
|
||||
@ -13,14 +14,12 @@ pub const TAIL: &str = "tail";
|
||||
pub const STRING: &str = "String";
|
||||
pub const SCONS: &str = "String/Cons";
|
||||
pub const SNIL: &str = "String/Nil";
|
||||
|
||||
pub const RESULT: &str = "Result";
|
||||
pub const RESULT_OK: &str = "Result/Ok";
|
||||
pub const RESULT_ERR: &str = "Result/Err";
|
||||
pub const SCONS_TAG: u32 = 1;
|
||||
|
||||
pub const NAT: &str = "Nat";
|
||||
pub const NAT_SUCC: &str = "Nat/Succ";
|
||||
pub const NAT_ZERO: &str = "Nat/Zero";
|
||||
pub const NAT_SUCC_TAG: u32 = 0;
|
||||
|
||||
impl Book {
|
||||
pub fn builtins() -> Book {
|
||||
@ -69,14 +68,6 @@ impl Term {
|
||||
pub fn encode_nat(val: u32) -> Term {
|
||||
(0 .. val).fold(Term::r#ref(NAT_ZERO), |acc, _| Term::app(Term::r#ref(NAT_SUCC), acc))
|
||||
}
|
||||
|
||||
pub fn encode_ok(val: Term) -> Term {
|
||||
Term::call(Term::r#ref(RESULT_OK), [val])
|
||||
}
|
||||
|
||||
pub fn encode_err(val: Term) -> Term {
|
||||
Term::call(Term::r#ref(RESULT_ERR), [val])
|
||||
}
|
||||
}
|
||||
|
||||
impl Pattern {
|
||||
|
@ -429,14 +429,22 @@ impl From<Option<Name>> for Pattern {
|
||||
|
||||
impl Term {
|
||||
/* Common construction patterns */
|
||||
|
||||
/// Lambda with a static tag
|
||||
pub fn lam(pat: Pattern, bod: Term) -> Self {
|
||||
Self::tagged_lam(Tag::Static, pat, bod)
|
||||
}
|
||||
|
||||
/// Lambda with any tag
|
||||
pub fn tagged_lam(tag: Tag, pat: Pattern, bod: Term) -> Self {
|
||||
Term::Lam { tag, pat: Box::new(pat), bod: Box::new(bod) }
|
||||
}
|
||||
|
||||
/// Wraps a term in lambdas, so that the outermost lambda is the first given element.
|
||||
pub fn rfold_lams(term: Term, pats: impl DoubleEndedIterator<Item = Option<Name>>) -> Self {
|
||||
pats.into_iter().rfold(term, |bod, nam| Self::lam(Pattern::Var(nam), bod))
|
||||
}
|
||||
|
||||
pub fn var_or_era(nam: Option<Name>) -> Self {
|
||||
if let Some(nam) = nam { Term::Var { nam } } else { Term::Era }
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
diagnostics::Diagnostics,
|
||||
fun::{Ctx, Definition, Name, Pattern, Rule, Term},
|
||||
fun::{Ctx, Definition, Name, Rule, Term},
|
||||
maybe_grow,
|
||||
};
|
||||
|
||||
@ -74,9 +74,8 @@ impl Term {
|
||||
pred: Some(Name::new("_-1")),
|
||||
arms: vec![std::mem::take(base.as_mut()), std::mem::take(step.as_mut())],
|
||||
};
|
||||
let body = free_vars.iter().rfold(body, |acc, bind| Term::lam(Pattern::Var(Some(bind.clone())), acc));
|
||||
let body =
|
||||
bind.iter_mut().rfold(body, |acc, bind| Term::lam(Pattern::Var(std::mem::take(bind)), acc));
|
||||
let body = Term::rfold_lams(body, free_vars.iter().cloned().map(Some));
|
||||
let body = Term::rfold_lams(body, std::mem::take(bind).into_iter());
|
||||
let def =
|
||||
Definition { name: new_nam.clone(), rules: vec![Rule { pats: vec![], body }], builtin: false };
|
||||
new_defs.push(def);
|
||||
|
@ -45,7 +45,7 @@ impl Definition {
|
||||
let rules = std::mem::take(&mut self.rules);
|
||||
match simplify_rule_match(args.clone(), rules, vec![], ctrs, adts) {
|
||||
Ok(body) => {
|
||||
let body = args.into_iter().rfold(body, |body, arg| Term::lam(Pattern::Var(Some(arg)), body));
|
||||
let body = Term::rfold_lams(body, args.into_iter().map(Some));
|
||||
self.rules = vec![Rule { pats: vec![], body }];
|
||||
}
|
||||
Err(e) => errs.push(e),
|
||||
|
@ -14,20 +14,20 @@ impl Book {
|
||||
/// // Transforms to:
|
||||
/// (λx x λx x λx x)
|
||||
/// ```
|
||||
pub fn apply_use(&mut self) {
|
||||
pub fn desugar_use(&mut self) {
|
||||
for def in self.defs.values_mut() {
|
||||
for rule in def.rules.iter_mut() {
|
||||
rule.body.apply_use();
|
||||
rule.body.desugar_use();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Term {
|
||||
pub fn apply_use(&mut self) {
|
||||
pub fn desugar_use(&mut self) {
|
||||
maybe_grow(|| {
|
||||
for children in self.children_mut() {
|
||||
children.apply_use();
|
||||
children.desugar_use();
|
||||
}
|
||||
});
|
||||
|
@ -1,14 +1,20 @@
|
||||
use crate::fun::{Book, Definition, Name, Pattern, Rule, Tag, Term};
|
||||
use crate::{
|
||||
fun::{Book, Definition, Name, Num, Pattern, Rule, Term},
|
||||
AdtEncoding,
|
||||
};
|
||||
|
||||
impl Book {
|
||||
/// Defines a function for each constructor in each ADT in the book.
|
||||
pub fn encode_adts(&mut self) {
|
||||
pub fn encode_adts(&mut self, adt_encoding: AdtEncoding) {
|
||||
let mut defs = vec![];
|
||||
for adt in self.adts.values() {
|
||||
for (ctr_name, fields) in &adt.ctrs {
|
||||
for (ctr_idx, (ctr_name, fields)) in adt.ctrs.iter().enumerate() {
|
||||
let ctrs: Vec<_> = adt.ctrs.keys().cloned().collect();
|
||||
|
||||
let body = encode_ctr(fields.iter().map(|f| &f.nam), ctrs, ctr_name);
|
||||
let body = match adt_encoding {
|
||||
AdtEncoding::Scott => encode_ctr_scott(fields.iter().map(|f| &f.nam), ctrs, ctr_name),
|
||||
AdtEncoding::NumScott => encode_ctr_num_scott(fields.iter().map(|f| &f.nam), ctr_idx),
|
||||
};
|
||||
|
||||
let rules = vec![Rule { pats: vec![], body }];
|
||||
let def = Definition { name: ctr_name.clone(), rules, builtin: adt.builtin };
|
||||
@ -19,16 +25,27 @@ impl Book {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_ctr<'a>(
|
||||
fn encode_ctr_scott<'a>(
|
||||
ctr_args: impl DoubleEndedIterator<Item = &'a Name> + Clone,
|
||||
ctrs: Vec<Name>,
|
||||
ctr_name: &Name,
|
||||
) -> Term {
|
||||
let tag = Tag::Static;
|
||||
let ctr = Term::Var { nam: ctr_name.clone() };
|
||||
let app =
|
||||
ctr_args.clone().cloned().fold(ctr, |acc, nam| Term::tagged_app(tag.clone(), acc, Term::Var { nam }));
|
||||
let lam =
|
||||
ctrs.into_iter().rfold(app, |acc, arg| Term::tagged_lam(tag.clone(), Pattern::Var(Some(arg)), acc));
|
||||
let app = Term::call(ctr, ctr_args.clone().cloned().map(|nam| Term::Var { nam }));
|
||||
let lam = Term::rfold_lams(app, ctrs.into_iter().map(Some));
|
||||
ctr_args.cloned().rfold(lam, |acc, arg| Term::lam(Pattern::Var(Some(arg)), acc))
|
||||
}
|
||||
|
||||
fn encode_ctr_num_scott<'a>(
|
||||
ctr_args: impl DoubleEndedIterator<Item = &'a Name> + Clone,
|
||||
ctr_idx: usize,
|
||||
) -> Term {
|
||||
let nam = Name::new("%x");
|
||||
// λa1 .. λan λx (x TAG a1 .. an)
|
||||
let term = Term::Var { nam: nam.clone() };
|
||||
let tag = Term::Num { val: Num::U24(ctr_idx as u32) };
|
||||
let term = Term::app(term, tag);
|
||||
let term = Term::call(term, ctr_args.clone().cloned().map(|nam| Term::Var { nam }));
|
||||
let term = Term::lam(Pattern::Var(Some(nam)), term);
|
||||
Term::rfold_lams(term, ctr_args.cloned().map(Some))
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
fun::{Book, MatchRule, Name, Pattern, Tag, Term},
|
||||
maybe_grow,
|
||||
fun::{Book, MatchRule, Name, Pattern, Term},
|
||||
maybe_grow, AdtEncoding,
|
||||
};
|
||||
|
||||
impl Book {
|
||||
@ -12,27 +12,27 @@ impl Book {
|
||||
/// Num matches are encoded as a sequence of native num matches (on 0 and 1+).
|
||||
///
|
||||
/// Var and pair matches become a let expression.
|
||||
pub fn encode_matches(&mut self) {
|
||||
pub fn encode_matches(&mut self, adt_encoding: AdtEncoding) {
|
||||
for def in self.defs.values_mut() {
|
||||
for rule in &mut def.rules {
|
||||
rule.body.encode_matches();
|
||||
rule.body.encode_matches(adt_encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Term {
|
||||
pub fn encode_matches(&mut self) {
|
||||
pub fn encode_matches(&mut self, adt_encoding: AdtEncoding) {
|
||||
maybe_grow(|| {
|
||||
for child in self.children_mut() {
|
||||
child.encode_matches()
|
||||
child.encode_matches(adt_encoding)
|
||||
}
|
||||
|
||||
if let Term::Mat { arg, bnd: _, with, arms: rules } = self {
|
||||
assert!(with.is_empty());
|
||||
let arg = std::mem::take(arg.as_mut());
|
||||
let rules = std::mem::take(rules);
|
||||
*self = encode_match(arg, rules);
|
||||
*self = encode_match(arg, rules, adt_encoding);
|
||||
} else if let Term::Swt { arg, bnd: _, with, pred, arms: rules } = self {
|
||||
assert!(with.is_empty());
|
||||
let arg = std::mem::take(arg.as_mut());
|
||||
@ -44,15 +44,46 @@ impl Term {
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_match(arg: Term, rules: Vec<MatchRule>) -> Term {
|
||||
let tag = Tag::Static;
|
||||
let mut arms = vec![];
|
||||
for rule in rules.into_iter() {
|
||||
let body =
|
||||
rule.1.iter().cloned().rfold(rule.2, |bod, nam| Term::tagged_lam(tag.clone(), Pattern::Var(nam), bod));
|
||||
arms.push(body);
|
||||
fn encode_match(arg: Term, rules: Vec<MatchRule>, adt_encoding: AdtEncoding) -> Term {
|
||||
match adt_encoding {
|
||||
AdtEncoding::Scott => {
|
||||
let arms = rules.into_iter().map(|rule| Term::rfold_lams(rule.2, rule.1.into_iter()));
|
||||
Term::call(arg, arms)
|
||||
}
|
||||
AdtEncoding::NumScott => {
|
||||
fn make_switches(arms: &mut [Term]) -> Term {
|
||||
maybe_grow(|| match arms {
|
||||
[] => Term::Err,
|
||||
[arm] => Term::lam(Pattern::Var(None), std::mem::take(arm)),
|
||||
[arm, rest @ ..] => Term::lam(Pattern::Var(Some(Name::new("%tag"))), Term::Swt {
|
||||
arg: Box::new(Term::Var { nam: Name::new("%tag") }),
|
||||
bnd: None,
|
||||
with: vec![],
|
||||
pred: None,
|
||||
arms: vec![std::mem::take(arm), make_switches(rest)],
|
||||
}),
|
||||
})
|
||||
}
|
||||
let mut arms =
|
||||
rules.into_iter().map(|rule| Term::rfold_lams(rule.2, rule.1.into_iter())).collect::<Vec<_>>();
|
||||
let term = if arms.len() == 1 {
|
||||
// λx (x λtag switch tag {0: Ctr0; _: * })
|
||||
let arm = arms.pop().unwrap();
|
||||
let term = Term::Swt {
|
||||
arg: Box::new(Term::Var { nam: Name::new("%tag") }),
|
||||
bnd: None,
|
||||
with: vec![],
|
||||
pred: None,
|
||||
arms: vec![arm, Term::Era],
|
||||
};
|
||||
Term::lam(Pattern::Var(Some(Name::new("%tag"))), term)
|
||||
} else {
|
||||
// λx (x λtag switch tag {0: Ctr0; _: switch tag-1 { ... } })
|
||||
make_switches(arms.as_mut_slice())
|
||||
};
|
||||
Term::call(arg, [term])
|
||||
}
|
||||
}
|
||||
Term::tagged_call(tag.clone(), arg, arms)
|
||||
}
|
||||
|
||||
/// Convert into a sequence of native switches, decrementing by 1 each switch.
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub mod apply_args;
|
||||
pub mod apply_use;
|
||||
pub mod definition_merge;
|
||||
pub mod definition_pruning;
|
||||
pub mod desugar_bend;
|
||||
@ -7,6 +6,7 @@ pub mod desugar_do_blocks;
|
||||
pub mod desugar_fold;
|
||||
pub mod desugar_match_defs;
|
||||
pub mod desugar_open;
|
||||
pub mod desugar_use;
|
||||
pub mod encode_adts;
|
||||
pub mod encode_match_terms;
|
||||
pub mod expand_generated;
|
||||
|
@ -1,11 +1,20 @@
|
||||
use crate::{
|
||||
fun::{builtins, Pattern, Tag, Term},
|
||||
maybe_grow,
|
||||
fun::{builtins, Num, Pattern, Tag, Term},
|
||||
maybe_grow, AdtEncoding,
|
||||
};
|
||||
use builtins::LCONS_TAG;
|
||||
|
||||
impl Term {
|
||||
/// Converts lambda-encoded lists ending with List/Nil to list literals.
|
||||
pub fn resugar_lists(&mut self) {
|
||||
pub fn resugar_lists(&mut self, adt_encoding: AdtEncoding) {
|
||||
match adt_encoding {
|
||||
AdtEncoding::Scott => self.resugar_lists_scott(),
|
||||
AdtEncoding::NumScott => self.resugar_lists_num_scott(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts num-scott-encoded lists ending with List/Nil to list literals.
|
||||
fn resugar_lists_num_scott(&mut self) {
|
||||
maybe_grow(|| {
|
||||
// Search for a List/Cons pattern in the term and try to build a list from that point on.
|
||||
// If successful, replace the term with the list.
|
||||
@ -13,24 +22,29 @@ impl Term {
|
||||
match self {
|
||||
// Nil: List/nil
|
||||
Term::Ref { nam } if nam == builtins::LNIL => *self = Term::List { els: vec![] },
|
||||
// Cons: @a @* (a <term> <term>)
|
||||
// Cons: @x (x CONS_TAG <term> <term>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
pat: box Pattern::Var(Some(var_lam)),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::App { tag: Tag::Static, fun: box Term::Var { nam: nam_cons_app }, arg: head },
|
||||
arg: tail,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Var { nam: var_app },
|
||||
arg: box Term::Num { val: Num::U24(LCONS_TAG) },
|
||||
},
|
||||
arg: head,
|
||||
},
|
||||
arg: tail,
|
||||
},
|
||||
} if nam_cons_lam == nam_cons_app => {
|
||||
head.resugar_lists();
|
||||
if let Some(els) = build_list(tail, vec![head]) {
|
||||
} if var_lam == var_app => {
|
||||
head.resugar_lists_num_scott();
|
||||
if let Some(els) = build_list_num_scott(tail, vec![head]) {
|
||||
*self = Term::List { els };
|
||||
} else {
|
||||
// Not a list term, keep as-is.
|
||||
@ -42,7 +56,7 @@ impl Term {
|
||||
fun: box Term::App { tag: Tag::Static, fun: box Term::Ref { nam }, arg: head },
|
||||
arg: tail,
|
||||
} if nam == builtins::LCONS => {
|
||||
if let Some(els) = build_list(tail, vec![head]) {
|
||||
if let Some(els) = build_list_num_scott(tail, vec![head]) {
|
||||
*self = Term::List { els };
|
||||
} else {
|
||||
// Not a list term, keep as-is.
|
||||
@ -52,25 +66,126 @@ impl Term {
|
||||
}
|
||||
|
||||
for child in self.children_mut() {
|
||||
child.resugar_lists();
|
||||
child.resugar_lists_num_scott();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts scott-encoded lists ending with List/Nil to list literals.
|
||||
fn resugar_lists_scott(&mut self) {
|
||||
maybe_grow(|| {
|
||||
// Search for a List/Cons pattern in the term and try to build a list from that point on.
|
||||
// If successful, replace the term with the list.
|
||||
// If not, keep as-is.
|
||||
match self {
|
||||
// Nil: List/nil
|
||||
Term::Ref { nam } if nam == builtins::LNIL => *self = Term::List { els: vec![] },
|
||||
// Cons: @* @c (c <term> <term>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::App { tag: Tag::Static, fun: box Term::Var { nam: nam_cons_app }, arg: head },
|
||||
arg: tail,
|
||||
},
|
||||
},
|
||||
} if nam_cons_lam == nam_cons_app => {
|
||||
head.resugar_lists_scott();
|
||||
if let Some(els) = build_list_scott(tail, vec![head]) {
|
||||
*self = Term::List { els };
|
||||
} else {
|
||||
// Not a list term, keep as-is.
|
||||
}
|
||||
}
|
||||
// Cons: (List/Cons <term> <term>)
|
||||
Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::App { tag: Tag::Static, fun: box Term::Ref { nam }, arg: head },
|
||||
arg: tail,
|
||||
} if nam == builtins::LCONS => {
|
||||
if let Some(els) = build_list_scott(tail, vec![head]) {
|
||||
*self = Term::List { els };
|
||||
} else {
|
||||
// Not a list term, keep as-is.
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
for child in self.children_mut() {
|
||||
child.resugar_lists_scott();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn build_list(term: &mut Term, mut s: Vec<&mut Term>) -> Option<Vec<Term>> {
|
||||
fn build_list_num_scott(term: &mut Term, mut s: Vec<&mut Term>) -> Option<Vec<Term>> {
|
||||
maybe_grow(|| {
|
||||
match term {
|
||||
// Nil: List/Nil
|
||||
Term::Ref { nam } if nam == builtins::LNIL => Some(s.into_iter().map(std::mem::take).collect()),
|
||||
// Cons: @a @* (a <term> <term>)
|
||||
// Cons: @x (x CONS_TAG <term> <term>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
pat: box Pattern::Var(Some(var_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Var { nam: var_app },
|
||||
arg: box Term::Num { val: Num::U24(LCONS_TAG) },
|
||||
},
|
||||
arg: head,
|
||||
},
|
||||
arg: tail,
|
||||
},
|
||||
} if var_lam == var_app => {
|
||||
// New list element, append and recurse
|
||||
s.push(head.as_mut());
|
||||
build_list_num_scott(tail, s)
|
||||
}
|
||||
// Cons: (List/cons <term> <term>)
|
||||
Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::App { tag: Tag::Static, fun: box Term::Ref { nam }, arg: head },
|
||||
arg: tail,
|
||||
} if nam == builtins::LCONS => {
|
||||
// New list element, append and recurse
|
||||
s.push(head.as_mut());
|
||||
build_list_num_scott(tail, s)
|
||||
}
|
||||
_ => {
|
||||
// Not a list term, stop
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn build_list_scott(term: &mut Term, mut s: Vec<&mut Term>) -> Option<Vec<Term>> {
|
||||
maybe_grow(|| {
|
||||
match term {
|
||||
// Nil: List/Nil
|
||||
Term::Ref { nam } if nam == builtins::LNIL => Some(s.into_iter().map(std::mem::take).collect()),
|
||||
// Cons: @* @c (c <term> <term>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
@ -81,7 +196,7 @@ fn build_list(term: &mut Term, mut s: Vec<&mut Term>) -> Option<Vec<Term>> {
|
||||
} if nam_cons_lam == nam_cons_app => {
|
||||
// New list element, append and recurse
|
||||
s.push(head.as_mut());
|
||||
build_list(tail, s)
|
||||
build_list_scott(tail, s)
|
||||
}
|
||||
// Cons: (List/cons <term> <term>)
|
||||
Term::App {
|
||||
@ -91,7 +206,7 @@ fn build_list(term: &mut Term, mut s: Vec<&mut Term>) -> Option<Vec<Term>> {
|
||||
} if nam == builtins::LCONS => {
|
||||
// New list element, append and recurse
|
||||
s.push(head.as_mut());
|
||||
build_list(tail, s)
|
||||
build_list_scott(tail, s)
|
||||
}
|
||||
_ => {
|
||||
// Not a list term, stop
|
||||
|
@ -1,11 +1,21 @@
|
||||
use builtins::SCONS_TAG;
|
||||
|
||||
use crate::{
|
||||
fun::{builtins, Num, Pattern, Tag, Term},
|
||||
maybe_grow,
|
||||
maybe_grow, AdtEncoding,
|
||||
};
|
||||
|
||||
impl Term {
|
||||
/// Converts lambda-encoded strings ending with String/nil to a string literals.
|
||||
pub fn resugar_strings(&mut self) {
|
||||
pub fn resugar_strings(&mut self, adt_encoding: AdtEncoding) {
|
||||
match adt_encoding {
|
||||
AdtEncoding::Scott => self.resugar_strings_scott(),
|
||||
AdtEncoding::NumScott => self.resugar_strings_num_scott(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts num-scott-encoded strings ending with String/nil to a string literals.
|
||||
fn resugar_strings_num_scott(&mut self) {
|
||||
maybe_grow(|| {
|
||||
// Search for a String/cons pattern in the term and try to build a string from that point on.
|
||||
// If successful, replace the term with the string.
|
||||
@ -13,14 +23,78 @@ impl Term {
|
||||
match self {
|
||||
// Nil: String/nil
|
||||
Term::Ref { nam } if nam == builtins::SNIL => *self = Term::str(""),
|
||||
// Cons: @a @* (a <num> <str>)
|
||||
// Cons: @x (x CONS_TAG <num> <str>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
pat: box Pattern::Var(Some(var_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Var { nam: var_app },
|
||||
arg: box Term::Num { val: Num::U24(SCONS_TAG) },
|
||||
},
|
||||
arg: box Term::Num { val: Num::U24(head) },
|
||||
},
|
||||
arg: tail,
|
||||
},
|
||||
} if var_lam == var_app => {
|
||||
let head = char::from_u32(*head).unwrap_or('.');
|
||||
if let Some(str) = build_string_num_scott(tail, head.to_string()) {
|
||||
*self = Term::str(&str);
|
||||
} else {
|
||||
// Not a string term, keep as-is.
|
||||
}
|
||||
}
|
||||
// Cons: (String/cons <num> <str>)
|
||||
Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Ref { nam },
|
||||
arg: box Term::Num { val: Num::U24(head) },
|
||||
},
|
||||
arg: tail,
|
||||
} if nam == builtins::SCONS => {
|
||||
let head = char::from_u32(*head).unwrap_or('.');
|
||||
if let Some(str) = build_string_num_scott(tail, head.to_string()) {
|
||||
*self = Term::str(&str);
|
||||
} else {
|
||||
// Not a string term, keep as-is.
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
for child in self.children_mut() {
|
||||
child.resugar_strings_num_scott();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts scott-encoded strings ending with String/nil to a string literals.
|
||||
fn resugar_strings_scott(&mut self) {
|
||||
maybe_grow(|| {
|
||||
// Search for a String/cons pattern in the term and try to build a string from that point on.
|
||||
// If successful, replace the term with the string.
|
||||
// If not, keep as-is.
|
||||
match self {
|
||||
// Nil: String/nil
|
||||
Term::Ref { nam } if nam == builtins::SNIL => *self = Term::str(""),
|
||||
// Cons: @* @c (c <num> <str>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
@ -35,7 +109,7 @@ impl Term {
|
||||
},
|
||||
} if nam_cons_lam == nam_cons_app => {
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
if let Some(str) = build_string(nxt, head.to_string()) {
|
||||
if let Some(str) = build_string_scott(nxt, head.to_string()) {
|
||||
*self = Term::str(&str);
|
||||
} else {
|
||||
// Not a string term, keep as-is.
|
||||
@ -53,7 +127,7 @@ impl Term {
|
||||
arg: nxt,
|
||||
} if nam == builtins::SCONS => {
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
if let Some(str) = build_string(nxt, head.to_string()) {
|
||||
if let Some(str) = build_string_scott(nxt, head.to_string()) {
|
||||
*self = Term::str(&str);
|
||||
} else {
|
||||
// Not a string term, keep as-is.
|
||||
@ -63,25 +137,80 @@ impl Term {
|
||||
}
|
||||
|
||||
for child in self.children_mut() {
|
||||
child.resugar_strings();
|
||||
child.resugar_strings_scott();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn build_string(term: &Term, mut s: String) -> Option<String> {
|
||||
fn build_string_num_scott(term: &Term, mut s: String) -> Option<String> {
|
||||
maybe_grow(|| {
|
||||
match term {
|
||||
// Nil: String/nil
|
||||
Term::Ref { nam } if nam == builtins::SNIL => Some(s),
|
||||
// Cons: @a @* (a <num> <str>)
|
||||
// Cons: @x (x CONS_TAG <num> <str>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
pat: box Pattern::Var(Some(var_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Var { nam: var_app },
|
||||
arg: box Term::Num { val: Num::U24(SCONS_TAG) },
|
||||
},
|
||||
arg: box Term::Num { val: Num::U24(head) },
|
||||
},
|
||||
arg: tail,
|
||||
},
|
||||
} if var_lam == var_app => {
|
||||
// New string character, append and recurse
|
||||
let head = char::from_u32(*head).unwrap_or('.');
|
||||
s.push(head);
|
||||
build_string_num_scott(tail, s)
|
||||
}
|
||||
// Cons: (String/cons <num> <str>)
|
||||
Term::App {
|
||||
tag: Tag::Static,
|
||||
fun:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
fun: box Term::Ref { nam },
|
||||
arg: box Term::Num { val: Num::U24(head) },
|
||||
},
|
||||
arg: tail,
|
||||
} if nam == builtins::SCONS => {
|
||||
// New string character, append and recurse
|
||||
let head = char::from_u32(*head).unwrap_or('.');
|
||||
s.push(head);
|
||||
build_string_num_scott(tail, s)
|
||||
}
|
||||
_ => {
|
||||
// Not a string term, stop
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn build_string_scott(term: &Term, mut s: String) -> Option<String> {
|
||||
maybe_grow(|| {
|
||||
match term {
|
||||
// Nil: String/nil
|
||||
Term::Ref { nam } if nam == builtins::SNIL => Some(s),
|
||||
// Cons: @* @c (c <num> <str>)
|
||||
Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
bod:
|
||||
box Term::Lam {
|
||||
tag: Tag::Static,
|
||||
pat: box Pattern::Var(None),
|
||||
pat: box Pattern::Var(Some(nam_cons_lam)),
|
||||
bod:
|
||||
box Term::App {
|
||||
tag: Tag::Static,
|
||||
@ -98,7 +227,7 @@ fn build_string(term: &Term, mut s: String) -> Option<String> {
|
||||
// New string character, append and recurse
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
s.push(head);
|
||||
build_string(nxt, s)
|
||||
build_string_scott(nxt, s)
|
||||
}
|
||||
// Cons: (String/cons <num> <str>)
|
||||
Term::App {
|
||||
@ -114,7 +243,7 @@ fn build_string(term: &Term, mut s: String) -> Option<String> {
|
||||
// New string character, append and recurse
|
||||
let head = char::from_u32(*c).unwrap_or('.');
|
||||
s.push(head);
|
||||
build_string(nxt, s)
|
||||
build_string_scott(nxt, s)
|
||||
}
|
||||
_ => {
|
||||
// Not a string term, stop
|
||||
|
@ -36,7 +36,7 @@ fn add_priority_next_in_cycle(net: &mut Net, nxt: &String) {
|
||||
}
|
||||
}
|
||||
|
||||
// If there are more than one recursive ref, add a priority to the last (first to execute).
|
||||
// If there are more than one recursive ref, add a priority to them.
|
||||
if count > 1 {
|
||||
for (pri, a, b) in net.redexes.iter_mut().rev() {
|
||||
if let Tree::Ref { nam } = a {
|
||||
|
52
src/lib.rs
52
src/lib.rs
@ -86,7 +86,7 @@ pub fn desugar_book(
|
||||
|
||||
ctx.set_entrypoint();
|
||||
|
||||
ctx.book.encode_adts();
|
||||
ctx.book.encode_adts(opts.adt_encoding);
|
||||
|
||||
ctx.fix_match_defs()?;
|
||||
|
||||
@ -119,13 +119,13 @@ pub fn desugar_book(
|
||||
// Manual match linearization
|
||||
ctx.book.linearize_match_with();
|
||||
|
||||
ctx.book.encode_matches();
|
||||
ctx.book.encode_matches(opts.adt_encoding);
|
||||
|
||||
// sanity check
|
||||
ctx.check_unbound_vars()?;
|
||||
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.apply_use();
|
||||
ctx.book.desugar_use();
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.linearize_vars();
|
||||
|
||||
@ -198,27 +198,24 @@ pub fn run_book_with_fn(
|
||||
return Err(format!("Error reading result from hvm. Output :\n{}{}{}", err, status, out).into());
|
||||
};
|
||||
|
||||
let (term, diags) = readback_hvm_net(&net, &book, &labels, run_opts.linear_readback);
|
||||
let (term, diags) =
|
||||
readback_hvm_net(&net, &book, &labels, run_opts.linear_readback, compile_opts.adt_encoding);
|
||||
Ok(Some((term, stats.to_string(), diags)))
|
||||
}
|
||||
|
||||
pub fn run_book(
|
||||
book: Book,
|
||||
run_opts: RunOpts,
|
||||
compile_opts: CompileOpts,
|
||||
diagnostics_cfg: DiagnosticsConfig,
|
||||
args: Option<Vec<Term>>,
|
||||
) -> Result<(Term, String, Diagnostics), Diagnostics> {
|
||||
run_book_with_fn(book, run_opts, compile_opts, diagnostics_cfg, args, "run", false).map(Option::unwrap)
|
||||
}
|
||||
|
||||
pub fn readback_hvm_net(net: &Net, book: &Book, labels: &Labels, linear: bool) -> (Term, Diagnostics) {
|
||||
pub fn readback_hvm_net(
|
||||
net: &Net,
|
||||
book: &Book,
|
||||
labels: &Labels,
|
||||
linear: bool,
|
||||
adt_encoding: AdtEncoding,
|
||||
) -> (Term, Diagnostics) {
|
||||
let mut diags = Diagnostics::default();
|
||||
let net = hvmc_to_net(net);
|
||||
let mut term = net_to_term(&net, book, labels, linear, &mut diags);
|
||||
term.expand_generated(book);
|
||||
term.resugar_strings();
|
||||
term.resugar_lists();
|
||||
term.resugar_strings(adt_encoding);
|
||||
term.resugar_lists(adt_encoding);
|
||||
(term, diags)
|
||||
}
|
||||
|
||||
@ -268,6 +265,9 @@ pub struct CompileOpts {
|
||||
|
||||
/// Enables [hvm::check_net_size].
|
||||
pub check_net_size: bool,
|
||||
|
||||
/// Determines the encoding of constructors and matches.
|
||||
pub adt_encoding: AdtEncoding,
|
||||
}
|
||||
|
||||
impl CompileOpts {
|
||||
@ -282,6 +282,7 @@ impl CompileOpts {
|
||||
inline: true,
|
||||
linearize_matches: OptLevel::Enabled,
|
||||
check_net_size: self.check_net_size,
|
||||
adt_encoding: self.adt_encoding,
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,6 +297,7 @@ impl CompileOpts {
|
||||
merge: false,
|
||||
inline: false,
|
||||
check_net_size: self.check_net_size,
|
||||
adt_encoding: self.adt_encoding,
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,6 +326,22 @@ impl Default for CompileOpts {
|
||||
merge: false,
|
||||
inline: false,
|
||||
check_net_size: true,
|
||||
adt_encoding: AdtEncoding::NumScott,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum AdtEncoding {
|
||||
Scott,
|
||||
NumScott,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AdtEncoding {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AdtEncoding::Scott => write!(f, "Scott"),
|
||||
AdtEncoding::NumScott => write!(f, "NumScott"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use bend::{
|
||||
check_book, compile_book, desugar_book,
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
|
||||
fun::{Book, Name},
|
||||
load_file_to_book, run_book_with_fn, CompileOpts, OptLevel, RunOpts,
|
||||
load_file_to_book, run_book_with_fn, AdtEncoding, CompileOpts, OptLevel, RunOpts,
|
||||
};
|
||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||
use std::{
|
||||
@ -186,6 +186,8 @@ pub enum OptArgs {
|
||||
NoInline,
|
||||
CheckNetSize,
|
||||
NoCheckNetSize,
|
||||
AdtScott,
|
||||
AdtNumScott,
|
||||
}
|
||||
|
||||
fn compile_opts_from_cli(args: &Vec<OptArgs>) -> CompileOpts {
|
||||
@ -212,6 +214,9 @@ fn compile_opts_from_cli(args: &Vec<OptArgs>) -> CompileOpts {
|
||||
LinearizeMatches => opts.linearize_matches = OptLevel::Enabled,
|
||||
LinearizeMatchesAlt => opts.linearize_matches = OptLevel::Alt,
|
||||
NoLinearizeMatches => opts.linearize_matches = OptLevel::Disabled,
|
||||
|
||||
AdtScott => opts.adt_encoding = AdtEncoding::Scott,
|
||||
AdtNumScott => opts.adt_encoding = AdtEncoding::NumScott,
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +244,6 @@ fn main() -> ExitCode {
|
||||
eprint!("{diagnostics}");
|
||||
return ExitCode::FAILURE;
|
||||
}
|
||||
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
use bend::{
|
||||
compile_book, desugar_book,
|
||||
diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
|
||||
fun::{load_book::do_parse_book, net_to_term::net_to_term, term_to_net::Labels, Book, Ctx, Name},
|
||||
fun::{load_book::do_parse_book, net_to_term::net_to_term, term_to_net::Labels, Book, Ctx, Name, Term},
|
||||
net::hvmc_to_net::hvmc_to_net,
|
||||
run_book, CompileOpts, RunOpts,
|
||||
run_book_with_fn, AdtEncoding, CompileOpts, RunOpts,
|
||||
};
|
||||
use insta::assert_snapshot;
|
||||
use itertools::Itertools;
|
||||
@ -82,6 +82,16 @@ fn run_golden_test_dir_multiple(test_name: &str, run: &[&RunFn]) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_book(
|
||||
book: Book,
|
||||
run_opts: RunOpts,
|
||||
compile_opts: CompileOpts,
|
||||
diagnostics_cfg: DiagnosticsConfig,
|
||||
args: Option<Vec<Term>>,
|
||||
) -> Result<(Term, String, Diagnostics), Diagnostics> {
|
||||
run_book_with_fn(book, run_opts, compile_opts, diagnostics_cfg, args, "run", false).map(Option::unwrap)
|
||||
}
|
||||
|
||||
/* Snapshot/regression/golden tests
|
||||
|
||||
Each tests runs all the files in tests/golden_tests/<test name>.
|
||||
@ -153,15 +163,19 @@ fn run_file() {
|
||||
run_golden_test_dir_multiple(function_name!(), &[(&|code, path| {
|
||||
let _guard = RUN_MUTEX.lock().unwrap();
|
||||
let book = do_parse_book(code, path, Book::builtins())?;
|
||||
let compile_opts = CompileOpts::default();
|
||||
let diagnostics_cfg = DiagnosticsConfig {
|
||||
unused_definition: Severity::Allow,
|
||||
..DiagnosticsConfig::new(Severity::Error, true)
|
||||
};
|
||||
let run_opts = RunOpts::default();
|
||||
|
||||
let (term, _, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, None)?;
|
||||
let res = format!("{diags}{term}");
|
||||
let mut res = String::new();
|
||||
|
||||
for adt_encoding in [AdtEncoding::NumScott, AdtEncoding::Scott] {
|
||||
let compile_opts = CompileOpts { adt_encoding, ..CompileOpts::default() };
|
||||
let (term, _, diags) = run_book(book.clone(), run_opts, compile_opts, diagnostics_cfg, None)?;
|
||||
res.push_str(&format!("{adt_encoding}:\n{diags}{term}\n\n"));
|
||||
}
|
||||
Ok(res)
|
||||
})])
|
||||
}
|
||||
@ -208,7 +222,7 @@ fn simplify_matches() {
|
||||
|
||||
ctx.check_shared_names();
|
||||
ctx.set_entrypoint();
|
||||
ctx.book.encode_adts();
|
||||
ctx.book.encode_adts(AdtEncoding::NumScott);
|
||||
ctx.fix_match_defs()?;
|
||||
ctx.book.encode_builtins();
|
||||
ctx.resolve_refs()?;
|
||||
@ -220,7 +234,7 @@ fn simplify_matches() {
|
||||
ctx.book.linearize_match_with();
|
||||
ctx.check_unbound_vars()?;
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.apply_use();
|
||||
ctx.book.desugar_use();
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.prune(false);
|
||||
|
||||
@ -234,7 +248,7 @@ fn parse_file() {
|
||||
let mut book = do_parse_book(code, path, Book::builtins())?;
|
||||
let mut ctx = Ctx::new(&mut book, Default::default());
|
||||
ctx.set_entrypoint();
|
||||
ctx.book.encode_adts();
|
||||
ctx.book.encode_adts(AdtEncoding::NumScott);
|
||||
ctx.book.encode_builtins();
|
||||
ctx.resolve_refs().expect("Resolve refs");
|
||||
ctx.desugar_match_defs().expect("Desugar match defs");
|
||||
@ -247,30 +261,32 @@ fn parse_file() {
|
||||
fn encode_pattern_match() {
|
||||
run_golden_test_dir(function_name!(), &|code, path| {
|
||||
let mut result = String::new();
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let mut book = do_parse_book(code, path, Book::builtins())?;
|
||||
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
||||
ctx.check_shared_names();
|
||||
ctx.set_entrypoint();
|
||||
ctx.book.encode_adts();
|
||||
ctx.fix_match_defs()?;
|
||||
ctx.book.encode_builtins();
|
||||
ctx.resolve_refs()?;
|
||||
ctx.desugar_match_defs()?;
|
||||
ctx.fix_match_terms()?;
|
||||
ctx.check_unbound_vars()?;
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.linearize_match_binds();
|
||||
ctx.book.linearize_match_with();
|
||||
ctx.book.encode_matches();
|
||||
ctx.check_unbound_vars()?;
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.apply_use();
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.linearize_vars();
|
||||
ctx.prune(false);
|
||||
for adt_encoding in [AdtEncoding::Scott, AdtEncoding::NumScott] {
|
||||
let diagnostics_cfg = DiagnosticsConfig::default();
|
||||
let mut book = do_parse_book(code, path, Book::builtins())?;
|
||||
let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
|
||||
ctx.check_shared_names();
|
||||
ctx.set_entrypoint();
|
||||
ctx.book.encode_adts(adt_encoding);
|
||||
ctx.fix_match_defs()?;
|
||||
ctx.book.encode_builtins();
|
||||
ctx.resolve_refs()?;
|
||||
ctx.desugar_match_defs()?;
|
||||
ctx.fix_match_terms()?;
|
||||
ctx.check_unbound_vars()?;
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.linearize_match_binds();
|
||||
ctx.book.linearize_match_with();
|
||||
ctx.book.encode_matches(adt_encoding);
|
||||
ctx.check_unbound_vars()?;
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.desugar_use();
|
||||
ctx.book.make_var_names_unique();
|
||||
ctx.book.linearize_vars();
|
||||
ctx.prune(false);
|
||||
|
||||
writeln!(result, "{}\n", ctx.book).unwrap();
|
||||
writeln!(result, "{adt_encoding}\n{}\n", ctx.book).unwrap();
|
||||
}
|
||||
Ok(result)
|
||||
})
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
# Vectorizes if the adts are encoded with tagged scott encoding
|
||||
data Box = (New a)
|
||||
data Bool = T | F
|
||||
data List_ = (Cons x xs) | Nil
|
||||
data Pair = (Tup a b)
|
||||
|
||||
(Tup.and (Pair/Tup (Box/New Bool/T) (Box/New Bool/T))) = Bool/T
|
||||
(Tup.and (Pair/Tup a b)) = Bool/F
|
||||
|
||||
(Not Bool/T) = Bool/F
|
||||
(Not Bool/F) = Bool/T
|
||||
|
||||
main = (Not
|
||||
(Tup.and
|
||||
(List_/Cons
|
||||
(Pair/Tup (Box/New Bool/T) (Box/New Bool/F))
|
||||
(List_/Cons
|
||||
(Pair/Tup (Box/New Bool/F) (Box/New Bool/F))
|
||||
(List_/Cons
|
||||
(Pair/Tup (Box/New Bool/T) (Box/New Bool/T))
|
||||
(List_/Cons
|
||||
(Pair/Tup (Box/New Bool/F) (Box/New Bool/T))
|
||||
List_/Nil
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
@ -2,11 +2,13 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_all.bend
|
||||
---
|
||||
@Pair.get = (a ((@Pair.get__C0 (a b)) b))
|
||||
@Pair.get = (a ((@Pair.get__C1 (a b)) b))
|
||||
|
||||
@Pair.get__C0 = (a (b ((a (b c)) c)))
|
||||
|
||||
@Pair/Pair = (a (b ((a (b c)) c)))
|
||||
@Pair.get__C1 = (?((@Pair.get__C0 *) a) a)
|
||||
|
||||
@Pair/Pair = (a (b ((0 (a (b c))) c)))
|
||||
|
||||
@main = b
|
||||
& @Pair.get ~ (@main__C0 (a b))
|
||||
|
@ -3,6 +3,6 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_pre_reduce.bend
|
||||
---
|
||||
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, check-net-size, no-check-net-size]
|
||||
[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, adt-scott, adt-num-scott]
|
||||
|
||||
For more information, try '--help'.
|
||||
|
@ -2,12 +2,12 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_strict_loop.bend
|
||||
---
|
||||
@A = (((* (a b)) (0 c)) c)
|
||||
@A = (((?((0 (* (* (a b)))) c) c) d) d)
|
||||
& @A ~ (a b)
|
||||
|
||||
@List/Cons = (a (b ((a (b c)) (* c))))
|
||||
@List/Cons = (a (b ((1 (a (b c))) c)))
|
||||
|
||||
@List/Nil = (* (a a))
|
||||
@List/Nil = ((0 a) a)
|
||||
|
||||
@main = c
|
||||
& @A ~ (b c)
|
||||
|
@ -3,7 +3,7 @@ source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/compile_wrong_opt.bend
|
||||
---
|
||||
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, check-net-size, no-check-net-size]
|
||||
[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, adt-scott, adt-num-scott]
|
||||
|
||||
tip: a similar value exists: 'float-combinators'
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/cli/desugar_bool_scott.bend
|
||||
---
|
||||
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, check-net-size, no-check-net-size]
|
||||
(main) = Boolean/True
|
||||
|
||||
For more information, try '--help'.
|
||||
(Boolean/True) = λa λ* a
|
||||
|
||||
(Boolean/False) = λ* λa a
|
||||
|
@ -2,9 +2,9 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/huge_tree.bend
|
||||
---
|
||||
@Tree/Leaf = (a (* ((a b) b)))
|
||||
@Tree/Leaf = (a ((1 (a b)) b))
|
||||
|
||||
@Tree/Node = (a (b (c (d ((a (b (c (d e)))) (* e))))))
|
||||
@Tree/Node = (a (b (c (d ((0 (a (b (c (d e))))) e)))))
|
||||
|
||||
@main = e
|
||||
& @Tree/Node ~ (a (b (c (d e))))
|
||||
|
@ -4,76 +4,96 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend
|
||||
---
|
||||
@Foo = (a (b (c ((a (b (c d))) d))))
|
||||
|
||||
@List.concat = ((@List.concat__C0 ((a a) b)) b)
|
||||
@List.concat = ((@List.concat__C1 a) a)
|
||||
|
||||
@List.concat__C0 = (a (b (c e)))
|
||||
@List.concat__C0 = (* (a (b (c e))))
|
||||
& @List/Cons ~ (a (d e))
|
||||
& @List.concat ~ (b (c d))
|
||||
|
||||
@List.fold = ((@List.fold__C0 ((a (* a)) (b (c d)))) (c (b d)))
|
||||
@List.concat__C1 = (?(((a a) @List.concat__C0) b) b)
|
||||
|
||||
@List.fold__C0 = (a (b (d ({(a (e f)) c} f))))
|
||||
@List.fold = ((@List.fold__C1 (a (b c))) (b (a c)))
|
||||
|
||||
@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.fold__C1 = (?(((a (* a)) @List.fold__C0) b) b)
|
||||
|
||||
@List.len__C0 = (* (a c))
|
||||
@List.len = ((@List.len__C1 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__C1 = (?((0 @List.len__C0) a) a)
|
||||
|
||||
@List.len_tr__C0 = (* (a (b d)))
|
||||
@List.len_tr = ((@List.len_tr__C1 a) a)
|
||||
|
||||
@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.len_tr__C1 = (?(((a a) @List.len_tr__C0) b) b)
|
||||
|
||||
@List.map__C0 = (a (c ({(a b) d} f)))
|
||||
@List.map = ((@List.map__C1 a) a)
|
||||
|
||||
@List.map__C0 = (* (a (c ({(a b) d} f))))
|
||||
& @List/Cons ~ (b (e f))
|
||||
& @List.map ~ (c (d e))
|
||||
|
||||
@List.reduce = ((@List.reduce__C0 ((a (* a)) (b (c d)))) (c (b d)))
|
||||
@List.map__C1 = (?(((* @List/Nil) @List.map__C0) a) a)
|
||||
|
||||
@List.reduce__C0 = (d (a (c ({b (c (d e))} f))))
|
||||
@List.reduce = ((@List.reduce__C1 (a (b c))) (b (a c)))
|
||||
|
||||
@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.reduce__C1 = (?(((a (* a)) @List.reduce__C0) b) b)
|
||||
|
||||
@List.reverse_bad__C0 = (c (a e))
|
||||
@List.reverse_bad = ((@List.reverse_bad__C1 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_bad__C1 = (?((@List/Nil @List.reverse_bad__C0) a) a)
|
||||
|
||||
@List.reverse_over__C0 = (b (a (c e)))
|
||||
@List.reverse_over = ((@List.reverse_over__C1 a) a)
|
||||
|
||||
@List.reverse_over__C0 = (* (b (a (c e))))
|
||||
& @List.reverse_over ~ (a (d e))
|
||||
& @List/Cons ~ (b (c d))
|
||||
|
||||
@List.reverse_over__C1 = (?(((a a) @List.reverse_over__C0) b) b)
|
||||
|
||||
@List.reverse_tr = (a (* b))
|
||||
& @List.reverse_over ~ (a (@List/Nil b))
|
||||
|
||||
@List.sum = ((@List.sum__C0 ((a a) b)) b)
|
||||
@List.sum = ((@List.sum__C1 a) a)
|
||||
|
||||
@List.sum__C0 = ($(:[+] $(b c)) (a (b d)))
|
||||
@List.sum__C0 = (* ($(:[+] $(b c)) (a (b d))))
|
||||
& @List.sum ~ (a (c d))
|
||||
|
||||
@List/Cons = (a (b ((a (b c)) (* c))))
|
||||
@List.sum__C1 = (?(((a a) @List.sum__C0) b) b)
|
||||
|
||||
@List/Nil = (* (a a))
|
||||
@List/Cons = (a (b ((1 (a (b c))) c)))
|
||||
|
||||
@Tree.flip = ((@Tree.flip__C1 (@Tree.flip__C0 a)) a)
|
||||
@List/Nil = ((0 a) a)
|
||||
|
||||
@Tree.flip__C0 = a
|
||||
& @Tree/leaf ~ a
|
||||
@Tree.flip = ((@Tree.flip__C2 a) a)
|
||||
|
||||
@Tree.flip__C1 = (c (a e))
|
||||
@Tree.flip__C0 = (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.flip__C1 = (* a)
|
||||
& @Tree/leaf ~ a
|
||||
|
||||
@Tree.flip__C2 = (?((@Tree.flip__C0 @Tree.flip__C1) a) a)
|
||||
|
||||
@Tree.height = ((@Tree.height__C1 a) a)
|
||||
|
||||
@Tree.height__C0 = (a (c f))
|
||||
& $(e f) ~ [+1]
|
||||
@ -81,32 +101,40 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend
|
||||
&! @Tree.height ~ (a b)
|
||||
&! @Tree.height ~ (c d)
|
||||
|
||||
@Tree.leaves = ((@Tree.leaves__C0 ((* 1) a)) a)
|
||||
@Tree.height__C1 = (?((@Tree.height__C0 (* (* 0))) a) a)
|
||||
|
||||
@Tree.leaves = ((@Tree.leaves__C1 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.leaves__C1 = (?((@Tree.leaves__C0 (* (* 1))) a) a)
|
||||
|
||||
@Tree.map__C0 = (a ((a b) c))
|
||||
& @Tree/leaf ~ (b c)
|
||||
@Tree.map = ((@Tree.map__C2 a) a)
|
||||
|
||||
@Tree.map__C1 = (a (d ({b e} g)))
|
||||
@Tree.map__C0 = (a (d ({b e} g)))
|
||||
& @Tree/node ~ (c (f g))
|
||||
&! @Tree.map ~ (a (b c))
|
||||
&! @Tree.map ~ (d (e f))
|
||||
|
||||
@Tree.nodes = ((@Tree.nodes__C0 ((* 0) a)) a)
|
||||
@Tree.map__C1 = (* (a ((a b) c)))
|
||||
& @Tree/leaf ~ (b c)
|
||||
|
||||
@Tree.map__C2 = (?((@Tree.map__C0 @Tree.map__C1) a) a)
|
||||
|
||||
@Tree.nodes = ((@Tree.nodes__C1 a) a)
|
||||
|
||||
@Tree.nodes__C0 = (a (b e))
|
||||
& $(d e) ~ [+1]
|
||||
&! @Tree.nodes ~ (a $(:[+] $(c d)))
|
||||
&! @Tree.nodes ~ (b c)
|
||||
|
||||
@Tree/leaf = (a (* ((a b) b)))
|
||||
@Tree.nodes__C1 = (?((@Tree.nodes__C0 (* (* 0))) a) a)
|
||||
|
||||
@Tree/node = (a (b ((a (b c)) (* c))))
|
||||
@Tree/leaf = (a ((1 (a b)) b))
|
||||
|
||||
@Tree/node = (a (b ((0 (a (b c))) c)))
|
||||
|
||||
@add = ((@add__C0 ((a a) b)) b)
|
||||
|
||||
|
@ -2,16 +2,20 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/adt_option_and.bend
|
||||
---
|
||||
@Option/None = (* (a a))
|
||||
@Option/None = ((1 a) a)
|
||||
|
||||
@Option/Some = (a ((a b) (* b)))
|
||||
@Option/Some = (a ((0 (a b)) b))
|
||||
|
||||
@Option/and = ((@Option/and__C1 ((* @Option/None) a)) a)
|
||||
@Option/and = ((@Option/and__C3 a) a)
|
||||
|
||||
@Option/and__C0 = (b (a c))
|
||||
& @Option/Some ~ ((a b) c)
|
||||
|
||||
@Option/and__C1 = (a ((@Option/and__C0 ((* @Option/None) (a b))) b))
|
||||
@Option/and__C1 = (?((@Option/and__C0 (* (* @Option/None))) a) a)
|
||||
|
||||
@Option/and__C2 = (a ((@Option/and__C1 (a b)) b))
|
||||
|
||||
@Option/and__C3 = (?((@Option/and__C2 (* (* @Option/None))) a) a)
|
||||
|
||||
@main = c
|
||||
& @Option/and ~ (a (b c))
|
||||
|
@ -2,11 +2,13 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/and.bend
|
||||
---
|
||||
@and = (b (((a a) ((* @bool/false) (b c))) c))
|
||||
@and = (a ((@and__C0 (a b)) b))
|
||||
|
||||
@bool/false = (* (a a))
|
||||
@and__C0 = (?(((a a) (* (* @bool/false))) b) b)
|
||||
|
||||
@bool/true = (a (* a))
|
||||
@bool/false = ((1 a) a)
|
||||
|
||||
@bool/true = ((0 a) a)
|
||||
|
||||
@main = a
|
||||
& @and ~ (@bool/true (@bool/false a))
|
||||
|
@ -2,21 +2,21 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/expr.bend
|
||||
---
|
||||
@Expr/App = (a (b (* (* ((a (b c)) (* (* (* (* (* (* c)))))))))))
|
||||
@Expr/App = (a (b ((2 (a (b c))) c)))
|
||||
|
||||
@Expr/Dup = (a (b (c (d (* (* (* (* (* (* ((a (b (c (d e)))) (* (* e)))))))))))))
|
||||
@Expr/Dup = (a (b (c (d ((6 (a (b (c (d e))))) e)))))
|
||||
|
||||
@Expr/Let = (a (b (c (* (* (* (* (* ((a (b (c d))) (* (* (* d))))))))))))
|
||||
@Expr/Let = (a (b (c ((5 (a (b (c d)))) d))))
|
||||
|
||||
@Expr/Num = (a (* ((a b) (* (* (* (* (* (* (* b))))))))))
|
||||
@Expr/Num = (a ((1 (a b)) b))
|
||||
|
||||
@Expr/Op2 = (a (b (c (* (* (* (* (* (* (* (* ((a (b (c d))) d))))))))))))
|
||||
@Expr/Op2 = (a (b (c ((8 (a (b (c d)))) d))))
|
||||
|
||||
@Expr/Var = (a ((a b) (* (* (* (* (* (* (* (* b))))))))))
|
||||
@Expr/Var = (a ((0 (a b)) b))
|
||||
|
||||
@Op/Mul = (* (* (a (* a))))
|
||||
@Op/Mul = ((2 a) a)
|
||||
|
||||
@Op/Sub = (* (a (* (* a))))
|
||||
@Op/Sub = ((1 a) a)
|
||||
|
||||
@main = n
|
||||
& @Expr/Let ~ (a (f (m n)))
|
||||
|
@ -2,40 +2,45 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.bend
|
||||
---
|
||||
@Bool/False__M_List_/Nil = (* (a a))
|
||||
@Bool/False__M_List_/Nil = ((1 a) a)
|
||||
|
||||
@If = (((a (* a)) ((* (b b)) c)) c)
|
||||
@If = ((@If__C0 a) a)
|
||||
|
||||
@List_/Cons = (a (b ((a (b c)) (* c))))
|
||||
@If__C0 = (?(((a (* a)) (* (* (b b)))) c) c)
|
||||
|
||||
@Map = ((@Map__C0 ((* @Bool/False__M_List_/Nil) a)) a)
|
||||
@List_/Cons = (a (b ((0 (a (b c))) c)))
|
||||
|
||||
@Map = ((@Map__C1 a) a)
|
||||
|
||||
@Map__C0 = (a (c ({(a b) d} f)))
|
||||
& @List_/Cons ~ (b (e f))
|
||||
& @Map ~ (c (d e))
|
||||
|
||||
@Merge = (b ((@Merge__C2 ((* (a a)) (b c))) c))
|
||||
@Map__C1 = (?((@Map__C0 (* (* @Bool/False__M_List_/Nil))) a) a)
|
||||
|
||||
@MergePair = (a ((@MergePair__C2 ((* @Bool/False__M_List_/Nil) (a b))) b))
|
||||
@Merge = (a ((@Merge__C4 (a b)) b))
|
||||
|
||||
@MergePair__C0 = (* (a b))
|
||||
& @List_/Cons ~ (a (@Bool/False__M_List_/Nil b))
|
||||
@MergePair = (a ((@MergePair__C4 (a b)) b))
|
||||
|
||||
@MergePair__C1 = (c (f ({a e} (b h))))
|
||||
@MergePair__C0 = (c (f ({a e} (b h))))
|
||||
& @List_/Cons ~ (d (g h))
|
||||
& @Merge ~ (a (b (c d)))
|
||||
& @MergePair ~ (e (f g))
|
||||
|
||||
@MergePair__C2 = (b ((@MergePair__C1 (@MergePair__C0 (a (b c)))) (a c)))
|
||||
@MergePair__C1 = (* (* (a b)))
|
||||
& @List_/Cons ~ (a (@Bool/False__M_List_/Nil b))
|
||||
|
||||
@MergePair__C2 = (?((@MergePair__C0 @MergePair__C1) a) a)
|
||||
|
||||
@MergePair__C3 = (b ((@MergePair__C2 (a (b c))) (a c)))
|
||||
|
||||
@MergePair__C4 = (?((@MergePair__C3 (* (* @Bool/False__M_List_/Nil))) a) a)
|
||||
|
||||
@MergeSort = (a (b d))
|
||||
& @Unpack ~ (a (c d))
|
||||
& @Map ~ (b (@Pure c))
|
||||
|
||||
@Merge__C0 = (* a)
|
||||
& @List_/Cons ~ a
|
||||
|
||||
@Merge__C1 = ({b {g l}} ({h q} ({(a (b c)) {e m}} ({a {d n}} ({f o} t)))))
|
||||
@Merge__C0 = ({b {g l}} ({h q} ({(a (b c)) {e m}} ({a {d n}} ({f o} t)))))
|
||||
& @If ~ (c (k (s t)))
|
||||
& @List_/Cons ~ (d (j k))
|
||||
&! @Merge ~ (e (f (i j)))
|
||||
@ -44,12 +49,19 @@ input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.bend
|
||||
&! @Merge ~ (m (p (q r)))
|
||||
& @List_/Cons ~ (n (o p))
|
||||
|
||||
@Merge__C2 = (b (c (a ((@Merge__C1 (@Merge__C0 (a (b (c d))))) d))))
|
||||
@Merge__C1 = (* (* a))
|
||||
& @List_/Cons ~ a
|
||||
|
||||
@Merge__C2 = (?((@Merge__C0 @Merge__C1) a) a)
|
||||
|
||||
@Merge__C3 = (b (c (a ((@Merge__C2 (a (b (c d)))) d))))
|
||||
|
||||
@Merge__C4 = (?((@Merge__C3 (* (* (a a)))) b) b)
|
||||
|
||||
@Pure = (a b)
|
||||
& @List_/Cons ~ (a (@Bool/False__M_List_/Nil b))
|
||||
|
||||
@Unpack = (a ((@Unpack__C1 ((* @Bool/False__M_List_/Nil) (a b))) b))
|
||||
@Unpack = (a ((@Unpack__C3 (a b)) b))
|
||||
|
||||
@Unpack__C0 = (d (e ({a b} (c i))))
|
||||
& @Unpack ~ (a (h i))
|
||||
@ -57,6 +69,10 @@ input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.bend
|
||||
& @List_/Cons ~ (c (f g))
|
||||
& @List_/Cons ~ (d (e f))
|
||||
|
||||
@Unpack__C1 = (c ((@Unpack__C0 ((* (a a)) (b (c d)))) (b d)))
|
||||
@Unpack__C1 = (?((@Unpack__C0 (* (* (a a)))) b) b)
|
||||
|
||||
@Unpack__C2 = (b ((@Unpack__C1 (a (b c))) (a c)))
|
||||
|
||||
@Unpack__C3 = (?((@Unpack__C2 (* (* @Bool/False__M_List_/Nil))) a) a)
|
||||
|
||||
@main = @MergeSort
|
||||
|
@ -2,15 +2,17 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/list_reverse.bend
|
||||
---
|
||||
@concat = ((@concat__C0 ((a a) b)) b)
|
||||
@concat = ((@concat__C1 a) a)
|
||||
|
||||
@concat__C0 = (a (b (c e)))
|
||||
& @list/cons ~ (a (d e))
|
||||
& @concat ~ (b (c d))
|
||||
|
||||
@list/cons = (a (b ((a (b c)) (* c))))
|
||||
@concat__C1 = (?((@concat__C0 (* (a a))) b) b)
|
||||
|
||||
@list/nil = (* (a a))
|
||||
@list/cons = (a (b ((0 (a (b c))) c)))
|
||||
|
||||
@list/nil = ((1 a) a)
|
||||
|
||||
@main = d
|
||||
& @reverse ~ (c d)
|
||||
@ -18,9 +20,11 @@ input_file: tests/golden_tests/compile_file_o_all/list_reverse.bend
|
||||
& @list/cons ~ (2 (a b))
|
||||
& @list/cons ~ (1 (@list/nil a))
|
||||
|
||||
@reverse = ((@reverse__C0 (@list/nil a)) a)
|
||||
@reverse = ((@reverse__C1 a) a)
|
||||
|
||||
@reverse__C0 = (c (a e))
|
||||
& @concat ~ (b (d e))
|
||||
& @reverse ~ (a b)
|
||||
& @list/cons ~ (c (@list/nil d))
|
||||
|
||||
@reverse__C1 = (?((@reverse__C0 (* @list/nil)) a) a)
|
||||
|
@ -2,9 +2,9 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/long_str_file.bend
|
||||
---
|
||||
@String/Cons = (a (b ((a (b c)) (* c))))
|
||||
@String/Cons = (a (b ((1 (a (b c))) c)))
|
||||
|
||||
@String/Nil = (* (a a))
|
||||
@String/Nil = ((0 a) a)
|
||||
|
||||
@main = r
|
||||
& @String/Cons ~ (40 (q r))
|
||||
|
@ -2,13 +2,15 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/match_dup_and_reconstruction.bend
|
||||
---
|
||||
@Box/Boxed = (a ((a b) b))
|
||||
@Box/Boxed = (a ((0 (a b)) b))
|
||||
|
||||
@Got = ((@Got__C0 a) a)
|
||||
@Got = ((@Got__C1 a) a)
|
||||
|
||||
@Got__C0 = ({a c} (b c))
|
||||
& @Box/Boxed ~ (a b)
|
||||
|
||||
@Got__C1 = (?((@Got__C0 *) a) a)
|
||||
|
||||
@main = b
|
||||
& @Got ~ (a b)
|
||||
& @Box/Boxed ~ (10 a)
|
||||
|
@ -2,13 +2,15 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/num_pattern_with_var.bend
|
||||
---
|
||||
@Foo = (((* 0) (@Foo__C1 a)) a)
|
||||
@Foo = ((@Foo__C2 a) a)
|
||||
|
||||
@Foo__C0 = ($([+1] a) a)
|
||||
|
||||
@Foo__C1 = (?((0 @Foo__C0) a) a)
|
||||
@Foo__C1 = (* (?((0 @Foo__C0) a) a))
|
||||
|
||||
@bool/true = (* (a a))
|
||||
@Foo__C2 = (?(((* 0) @Foo__C1) a) a)
|
||||
|
||||
@bool/true = ((1 a) a)
|
||||
|
||||
@main = a
|
||||
& @Foo ~ (@bool/true (3 a))
|
||||
|
@ -2,15 +2,17 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/scrutinee_reconstruction.bend
|
||||
---
|
||||
@Option/None = (* (a a))
|
||||
@Option/None = ((1 a) a)
|
||||
|
||||
@Option/Some = (a ((a b) (* b)))
|
||||
@Option/Some = (a ((0 (a b)) b))
|
||||
|
||||
@Option/or = ((@Option/or__C0 ((a a) b)) b)
|
||||
@Option/or = ((@Option/or__C1 a) a)
|
||||
|
||||
@Option/or__C0 = (a (* b))
|
||||
& @Option/Some ~ (a b)
|
||||
|
||||
@Option/or__C1 = (?((@Option/or__C0 (* (a a))) b) b)
|
||||
|
||||
@main = b
|
||||
& @Option/or ~ (a (@Option/None b))
|
||||
& @Option/Some ~ (5 a)
|
||||
|
@ -2,9 +2,9 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/str.bend
|
||||
---
|
||||
@String/Cons = (a (b ((a (b c)) (* c))))
|
||||
@String/Cons = (a (b ((1 (a (b c))) c)))
|
||||
|
||||
@String/Nil = (* (a a))
|
||||
@String/Nil = ((0 a) a)
|
||||
|
||||
@main = f
|
||||
& @String/Cons ~ (109 (e f))
|
||||
|
@ -2,7 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file_o_all/weekday.bend
|
||||
---
|
||||
@Weekday/Saturday = (* (* (* (* (* (a (* a)))))))
|
||||
@Weekday/Saturday = ((5 a) a)
|
||||
|
||||
@main = b
|
||||
& (a a) ~ (@Weekday/Saturday b)
|
||||
|
@ -2,7 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/desugar_file/bind_syntax.bend
|
||||
---
|
||||
(Result/bind) = λa λb (a Result/bind__C1 Result/bind__C0 b)
|
||||
(Result/bind) = λa λb (a Result/bind__C2 b)
|
||||
|
||||
(safe_div) = λa λb (switch b { 0: λ* (Result/Err (String/Cons 68 (String/Cons 105 (String/Cons 118 (String/Cons 32 (String/Cons 98 (String/Cons 121 (String/Cons 32 (String/Cons 48 String/Nil))))))))); _: safe_div__C0; } a)
|
||||
|
||||
@ -10,21 +10,23 @@ input_file: tests/golden_tests/desugar_file/bind_syntax.bend
|
||||
|
||||
(Main) = (Result/bind Main__C1 Main__C0)
|
||||
|
||||
(String/Cons) = λa λb λc λ* (c a b)
|
||||
(String/Nil) = λa (a 0)
|
||||
|
||||
(String/Nil) = λ* λa a
|
||||
(String/Cons) = λa λb λc (c 1 a b)
|
||||
|
||||
(Result/Ok) = λa λb λ* (b a)
|
||||
(Result/Ok) = λa λb (b 0 a)
|
||||
|
||||
(Result/Err) = λa λ* λb (b a)
|
||||
(Result/Err) = λa λb (b 1 a)
|
||||
|
||||
(Main__C0) = λa (Result/bind (safe_rem a 0) λb b)
|
||||
|
||||
(Main__C1) = (safe_div 3 2)
|
||||
|
||||
(Result/bind__C0) = λa λ* (Result/Err a)
|
||||
(Result/bind__C0) = λa λb (b a)
|
||||
|
||||
(Result/bind__C1) = λa λb (b a)
|
||||
(Result/bind__C1) = λ* λa λ* (Result/Err a)
|
||||
|
||||
(Result/bind__C2) = λa switch a { 0: Result/bind__C0; _: Result/bind__C1; }
|
||||
|
||||
(safe_div__C0) = λa λb (Result/Ok (/ b (+ a 1)))
|
||||
|
||||
|
@ -6,7 +6,7 @@ input_file: tests/golden_tests/desugar_file/combinators.bend
|
||||
|
||||
(bar) = λa λb (a bar b)
|
||||
|
||||
(List/ignore) = λa λ* (a List/ignore__C0 0)
|
||||
(List/ignore) = λa λ* (a List/ignore__C1)
|
||||
|
||||
(baz) = {0 1 2 3 λa a foo}
|
||||
|
||||
@ -24,15 +24,17 @@ input_file: tests/golden_tests/desugar_file/combinators.bend
|
||||
|
||||
(Main) = list
|
||||
|
||||
(List/Cons) = λa λb λc λ* (c a b)
|
||||
(List/Nil) = λa (a 0)
|
||||
|
||||
(List/Nil) = λ* λa a
|
||||
(List/Cons) = λa λb λc (c 1 a b)
|
||||
|
||||
(A__C0) = let {a b} = A; λc (a b c)
|
||||
|
||||
(B__C0) = let (a, b) = B; λc (a b c)
|
||||
|
||||
(List/ignore__C0) = λ* λa (List/ignore a List/ignore)
|
||||
(List/ignore__C0) = λ* λ* λa (List/ignore a List/ignore)
|
||||
|
||||
(List/ignore__C1) = λa switch a { 0: 0; _: List/ignore__C0; }
|
||||
|
||||
(clax__C0) = λ* λ* λ* λa (clax a)
|
||||
|
||||
|
@ -2,14 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/desugar_file/deref_loop.bend
|
||||
---
|
||||
(foo) = λa (a λb b foo__C0)
|
||||
(foo) = λa (a foo__C1)
|
||||
|
||||
(bar) = (foo 1)
|
||||
|
||||
(main) = (foo 0)
|
||||
|
||||
(nat/succ) = λa λb λ* (b a)
|
||||
(nat/succ) = λa λb (b 0 a)
|
||||
|
||||
(nat/zero) = λ* λa a
|
||||
(nat/zero) = λa (a 1)
|
||||
|
||||
(foo__C0) = (bar 0)
|
||||
(foo__C0) = λ* (bar 0)
|
||||
|
||||
(foo__C1) = λa switch a { 0: λb b; _: foo__C0; }
|
||||
|
@ -2,8 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/adt_tup_era.bend
|
||||
---
|
||||
Scott
|
||||
(Foo) = λa (a λb λc (b λd λ* λ* d c))
|
||||
|
||||
(Main) = (Foo (Tuple/Pair 1 5))
|
||||
|
||||
(Tuple/Pair) = λa λb λc (c a b)
|
||||
|
||||
NumScott
|
||||
(Foo) = λa (a λb switch b { 0: λc λd (c λe switch e { 0: λf λ* λ* f; _: *; } d); _: *; })
|
||||
|
||||
(Main) = (Foo (Tuple/Pair 1 5))
|
||||
|
||||
(Tuple/Pair) = λa λb λc (c 0 a b)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/and3.bend
|
||||
---
|
||||
Scott
|
||||
(And) = λa let (b, c, d) = a; (b λe λf (e λg (g Bool/T Bool/F) λ* Bool/F f) λ* λ* Bool/F c d)
|
||||
|
||||
(main) = (And (Bool/F, Bool/T, Bool/F))
|
||||
@ -9,3 +10,12 @@ input_file: tests/golden_tests/encode_pattern_match/and3.bend
|
||||
(Bool/T) = λa λ* a
|
||||
|
||||
(Bool/F) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(And) = λa let (b, c, d) = a; (b λe switch e { 0: λf λg (f λh switch h { 0: λi (i λj switch j { 0: Bool/T; _: λ* Bool/F; }); _: λ* λ* Bool/F; } g); _: λ* λ* λ* Bool/F; } c d)
|
||||
|
||||
(main) = (And (Bool/F, Bool/T, Bool/F))
|
||||
|
||||
(Bool/T) = λa (a 0)
|
||||
|
||||
(Bool/F) = λa (a 1)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/bool.bend
|
||||
---
|
||||
Scott
|
||||
(not) = λa (a bool/false bool/true)
|
||||
|
||||
(and) = λa (a λb (b bool/true bool/false) λc (c bool/false bool/false))
|
||||
@ -15,3 +16,18 @@ input_file: tests/golden_tests/encode_pattern_match/bool.bend
|
||||
(bool/true) = λa λ* a
|
||||
|
||||
(bool/false) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(not) = λa (a λb switch b { 0: bool/false; _: λ* bool/true; })
|
||||
|
||||
(and) = λa (a λb switch b { 0: λc (c λd switch d { 0: bool/true; _: λ* bool/false; }); _: λ* λe (e λf switch f { 0: bool/false; _: λ* bool/false; }); })
|
||||
|
||||
(and2) = λa (a λb switch b { 0: λc c; _: λ* λ* bool/false; })
|
||||
|
||||
(and3) = λa (a λb switch b { 0: λc (c λd switch d { 0: bool/true; _: λ* bool/false; }); _: λ* λ* bool/false; })
|
||||
|
||||
(and4) = λa (a λb switch b { 0: λc (c λd switch d { 0: bool/true; _: λ* bool/false; }); _: λ* λ* bool/false; })
|
||||
|
||||
(bool/true) = λa (a 0)
|
||||
|
||||
(bool/false) = λa (a 1)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/bool_tup.bend
|
||||
---
|
||||
Scott
|
||||
(foo) = λa let (b, c) = a; (b λd d λ* Bool/F c)
|
||||
|
||||
(main) = (foo (Bool/F, Bool/T))
|
||||
@ -9,3 +10,12 @@ input_file: tests/golden_tests/encode_pattern_match/bool_tup.bend
|
||||
(Bool/T) = λa λ* a
|
||||
|
||||
(Bool/F) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(foo) = λa let (b, c) = a; (b λd switch d { 0: λe e; _: λ* λ* Bool/F; } c)
|
||||
|
||||
(main) = (foo (Bool/F, Bool/T))
|
||||
|
||||
(Bool/T) = λa (a 0)
|
||||
|
||||
(Bool/F) = λa (a 1)
|
||||
|
@ -2,6 +2,12 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/box.bend
|
||||
---
|
||||
Scott
|
||||
(unbox) = λa (a λb b)
|
||||
|
||||
(box/new) = λa λb (b a)
|
||||
|
||||
NumScott
|
||||
(unbox) = λa (a λb switch b { 0: λc c; _: *; })
|
||||
|
||||
(box/new) = λa λb (b 0 a)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/common.bend
|
||||
---
|
||||
Scott
|
||||
(Box/Filled) = λa λb λ* (b a)
|
||||
|
||||
(Box/Empty) = λ* λb b
|
||||
@ -35,3 +36,38 @@ input_file: tests/golden_tests/encode_pattern_match/common.bend
|
||||
(Direction/East) = λ* λ* λc λ* c
|
||||
|
||||
(Direction/West) = λ* λ* λ* λd d
|
||||
|
||||
NumScott
|
||||
(Box/Filled) = λa λb (b 0 a)
|
||||
|
||||
(Box/Empty) = λa (a 1)
|
||||
|
||||
(Option/Some) = λa λb (b 0 a)
|
||||
|
||||
(Option/None) = λa (a 1)
|
||||
|
||||
(Result_/Ok) = λa λb (b 0 a)
|
||||
|
||||
(Result_/Err) = λa λb (b 1 a)
|
||||
|
||||
(List_/Cons) = λa λb λc (c 0 a b)
|
||||
|
||||
(List_/Nil) = λa (a 1)
|
||||
|
||||
(Bool/True) = λa (a 0)
|
||||
|
||||
(Bool/False) = λa (a 1)
|
||||
|
||||
(Light/Red) = λa (a 0)
|
||||
|
||||
(Light/Yellow) = λa (a 1)
|
||||
|
||||
(Light/Green) = λa (a 2)
|
||||
|
||||
(Direction/North) = λa (a 0)
|
||||
|
||||
(Direction/South) = λa (a 1)
|
||||
|
||||
(Direction/East) = λa (a 2)
|
||||
|
||||
(Direction/West) = λa (a 3)
|
||||
|
@ -2,10 +2,20 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/concat.bend
|
||||
---
|
||||
Scott
|
||||
(String/concat) = λ* λb b
|
||||
|
||||
(main) = (String/concat (String/Cons 97 (String/Cons 98 String/Nil)) (String/Cons 99 (String/Cons 100 String/Nil)))
|
||||
|
||||
(String/Cons) = λa λb λc λ* (c a b)
|
||||
(String/Nil) = λa λ* a
|
||||
|
||||
(String/Nil) = λ* λb b
|
||||
(String/Cons) = λa λb λ* λd (d a b)
|
||||
|
||||
NumScott
|
||||
(String/concat) = λ* λb b
|
||||
|
||||
(main) = (String/concat (String/Cons 97 (String/Cons 98 String/Nil)) (String/Cons 99 (String/Cons 100 String/Nil)))
|
||||
|
||||
(String/Nil) = λa (a 0)
|
||||
|
||||
(String/Cons) = λa λb λc (c 1 a b)
|
||||
|
@ -2,10 +2,20 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/concat_def.bend
|
||||
---
|
||||
(concat) = λa (a λb λc λd (String/Cons b (concat c d)) λe e)
|
||||
Scott
|
||||
(concat) = λa (a λb b λc λd λe (String/Cons c (concat d e)))
|
||||
|
||||
(main) = (concat (String/Cons 97 (String/Cons 98 String/Nil)) (String/Cons 99 (String/Cons 100 String/Nil)))
|
||||
|
||||
(String/Cons) = λa λb λc λ* (c a b)
|
||||
(String/Nil) = λa λ* a
|
||||
|
||||
(String/Nil) = λ* λb b
|
||||
(String/Cons) = λa λb λ* λd (d a b)
|
||||
|
||||
NumScott
|
||||
(concat) = λa (a λb switch b { 0: λc c; _: λ* λd λe λf (String/Cons d (concat e f)); })
|
||||
|
||||
(main) = (concat (String/Cons 97 (String/Cons 98 String/Nil)) (String/Cons 99 (String/Cons 100 String/Nil)))
|
||||
|
||||
(String/Nil) = λa (a 0)
|
||||
|
||||
(String/Cons) = λa λb λc (c 1 a b)
|
||||
|
@ -2,6 +2,12 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/def_tups.bend
|
||||
---
|
||||
Scott
|
||||
(go) = λa let (b, c) = a; let (d, e) = c; let (f, g) = e; let (h, i) = g; (+ (+ (+ (+ i h) f) d) b)
|
||||
|
||||
(main) = (go (1, (2, (3, (4, 5)))))
|
||||
|
||||
NumScott
|
||||
(go) = λa let (b, c) = a; let (d, e) = c; let (f, g) = e; let (h, i) = g; (+ (+ (+ (+ i h) f) d) b)
|
||||
|
||||
(main) = (go (1, (2, (3, (4, 5)))))
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/definition_merge.bend
|
||||
---
|
||||
Scott
|
||||
(Foo) = λa (a λ* λc (c λ* 1 λ* 2) λ* λg (g λ* 3 λ* 3))
|
||||
|
||||
(Either/Left) = λa λb λ* (b a)
|
||||
@ -11,3 +12,14 @@ input_file: tests/golden_tests/encode_pattern_match/definition_merge.bend
|
||||
(Bool/Bool/True) = λa λ* a
|
||||
|
||||
(Bool/Bool/False) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(Foo) = λa (a λb switch b { 0: λ* λd (d λe switch e { 0: λ* 1; _: λ* λ* 2; }); _: λ* λ* λi (i λj switch j { 0: λ* 3; _: λ* λ* 3; }); })
|
||||
|
||||
(Either/Left) = λa λb (b 0 a)
|
||||
|
||||
(Either/Right) = λa λb (b 1 a)
|
||||
|
||||
(Bool/Bool/True) = λa (a 0)
|
||||
|
||||
(Bool/Bool/False) = λa (a 1)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/expr.bend
|
||||
---
|
||||
Scott
|
||||
(Expr/Var) = λa λb λ* λ* λ* λ* λ* λ* λ* λ* (b a)
|
||||
|
||||
(Expr/Num) = λa λ* λc λ* λ* λ* λ* λ* λ* λ* (c a)
|
||||
@ -27,3 +28,30 @@ input_file: tests/golden_tests/encode_pattern_match/expr.bend
|
||||
(Op/Mul) = λ* λ* λc λ* c
|
||||
|
||||
(Op/Div) = λ* λ* λ* λd d
|
||||
|
||||
NumScott
|
||||
(Expr/Var) = λa λb (b 0 a)
|
||||
|
||||
(Expr/Num) = λa λb (b 1 a)
|
||||
|
||||
(Expr/App) = λa λb λc (c 2 a b)
|
||||
|
||||
(Expr/Fun) = λa λb λc (c 3 a b)
|
||||
|
||||
(Expr/If) = λa λb λc λd (d 4 a b c)
|
||||
|
||||
(Expr/Let) = λa λb λc λd (d 5 a b c)
|
||||
|
||||
(Expr/Dup) = λa λb λc λd λe (e 6 a b c d)
|
||||
|
||||
(Expr/Tup) = λa λb λc (c 7 a b)
|
||||
|
||||
(Expr/Op2) = λa λb λc λd (d 8 a b c)
|
||||
|
||||
(Op/Add) = λa (a 0)
|
||||
|
||||
(Op/Sub) = λa (a 1)
|
||||
|
||||
(Op/Mul) = λa (a 2)
|
||||
|
||||
(Op/Div) = λa (a 3)
|
||||
|
@ -2,6 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/flatten_era_pat.bend
|
||||
---
|
||||
Scott
|
||||
(Fn1) = λa λ* let (*, d) = a; let (e, *) = d; e
|
||||
|
||||
(Fn2) = λa let (*, c) = a; let (*, e) = c; let (f, *) = e; f
|
||||
|
||||
(Fn3) = λa let (b, *) = a; switch b { 0: λ* 0; _: λe λ* (+ e 1); }
|
||||
|
||||
(main) = (Fn2 ((1, 2), (3, (4, (5, 6)))) 0)
|
||||
|
||||
NumScott
|
||||
(Fn1) = λa λ* let (*, d) = a; let (e, *) = d; e
|
||||
|
||||
(Fn2) = λa let (*, c) = a; let (*, e) = c; let (f, *) = e; f
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/is_some_some.bend
|
||||
---
|
||||
Scott
|
||||
(some_some) = λa (a λb (b λ* 1 0) 0)
|
||||
|
||||
(main) = (some_some (Option/Some 1))
|
||||
@ -9,3 +10,12 @@ input_file: tests/golden_tests/encode_pattern_match/is_some_some.bend
|
||||
(Option/Some) = λa λb λ* (b a)
|
||||
|
||||
(Option/None) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(some_some) = λa (a λb switch b { 0: λc (c λd switch d { 0: λ* 1; _: λ* 0; }); _: λ* 0; })
|
||||
|
||||
(main) = (some_some (Option/Some 1))
|
||||
|
||||
(Option/Some) = λa λb (b 0 a)
|
||||
|
||||
(Option/None) = λa (a 1)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/list_merge_sort.bend
|
||||
---
|
||||
Scott
|
||||
(If) = λa (a λb λ* b λ* λe e)
|
||||
|
||||
(Pure) = λa (List_/Cons a List_/Nil)
|
||||
@ -23,3 +24,26 @@ input_file: tests/golden_tests/encode_pattern_match/list_merge_sort.bend
|
||||
(List_/Cons) = λa λb λc λ* (c a b)
|
||||
|
||||
(List_/Nil) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(If) = λa (a λb switch b { 0: λc λ* c; _: λ* λ* λf f; })
|
||||
|
||||
(Pure) = λa (List_/Cons a List_/Nil)
|
||||
|
||||
(Map) = λa (a λb switch b { 0: λc λd λe let {e e_2} = e; (List_/Cons (e c) (Map d e_2)); _: λ* λ* List_/Nil; })
|
||||
|
||||
(MergeSort) = λa λb (Unpack a (Map b Pure))
|
||||
|
||||
(Unpack) = λa λb (b λc switch c { 0: λd λe λf (e λg switch g { 0: λh λi λj let {j j_2} = j; λk (Unpack j (MergePair j_2 (List_/Cons k (List_/Cons h i)))); _: λ* λ* λm m; } f d); _: λ* λ* List_/Nil; } a)
|
||||
|
||||
(MergePair) = λa λb (b λc switch c { 0: λd λe λf (e λg switch g { 0: λh λi λj let {j j_2} = j; λk (List_/Cons (Merge j k h) (MergePair j_2 i)); _: λ* λ* λm (List_/Cons m List_/Nil); } f d); _: λ* λ* List_/Nil; } a)
|
||||
|
||||
(Merge) = λa λb (b λc switch c { 0: λd λe λf λg (g λh switch h { 0: λi let {i i_2 i_3} = i; λj let {j j_2} = j; λk let {k k_2 k_3} = k; λl let {l l_2 l_3} = l; λm let {m m_2} = m; (If (k l i) (List_/Cons l_2 (Merge k_2 m (List_/Cons i_2 j))) (List_/Cons i_3 (Merge k_3 (List_/Cons l_3 m_2) j_2))); _: λ* λ* λq λr (List_/Cons q r); } f d e); _: λ* λ* λt t; } a)
|
||||
|
||||
(Bool/True) = λa (a 0)
|
||||
|
||||
(Bool/False) = λa (a 1)
|
||||
|
||||
(List_/Cons) = λa λb λc (c 0 a b)
|
||||
|
||||
(List_/Nil) = λa (a 1)
|
||||
|
@ -2,8 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/list_str_encoding_undeclared_fn.bend
|
||||
---
|
||||
Scott
|
||||
(main) = *
|
||||
|
||||
(Foo) = λa (a λ* λ* 1 0)
|
||||
(Foo) = λa (a 0 λ* λ* 1)
|
||||
|
||||
(Bar) = λa (a λ* λ* 0 1)
|
||||
(Bar) = λa (a 1 λ* λ* 0)
|
||||
|
||||
NumScott
|
||||
(main) = *
|
||||
|
||||
(Foo) = λa (a λb switch b { 0: 0; _: λ* λ* λ* 1; })
|
||||
|
||||
(Bar) = λa (a λb switch b { 0: 1; _: λ* λ* λ* 0; })
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/list_str_encoding_undeclared_map.bend
|
||||
---
|
||||
(main) = λa λb ((a λ* λ* 1 2), (b λ* λ* 1 2))
|
||||
Scott
|
||||
(main) = λa λb ((a 2 λ* λ* 1), (b 2 λ* λ* 1))
|
||||
|
||||
NumScott
|
||||
(main) = λa λb ((a λc switch c { 0: 2; _: λ* λ* λ* 1; }), (b λg switch g { 0: 2; _: λ* λ* λ* 1; }))
|
||||
|
@ -2,8 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_in_arm.bend
|
||||
---
|
||||
Scott
|
||||
(main) = λ* λ$x $x
|
||||
|
||||
(bool/T) = λa λ* a
|
||||
|
||||
(bool/F) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(main) = λ* λ$x $x
|
||||
|
||||
(bool/T) = λa (a 0)
|
||||
|
||||
(bool/F) = λa (a 1)
|
||||
|
@ -2,8 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_lambda.bend
|
||||
---
|
||||
Scott
|
||||
(main) = (Maybe/Some 1 λ$x * λa a $x)
|
||||
|
||||
(Maybe/None) = λa λ* a
|
||||
|
||||
(Maybe/Some) = λa λ* λc (c a)
|
||||
|
||||
NumScott
|
||||
(main) = (Maybe/Some 1 λa switch a { 0: λ$x *; _: λ* λb b; } $x)
|
||||
|
||||
(Maybe/None) = λa (a 0)
|
||||
|
||||
(Maybe/Some) = λa λb (b 1 a)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_var.bend
|
||||
---
|
||||
Scott
|
||||
(Foo) = λ$x (Maybe/Some 1 $x λa a)
|
||||
|
||||
(Bar) = (Maybe/Some 1 $x λa a λ$x *)
|
||||
@ -11,3 +12,14 @@ input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_var.bend
|
||||
(Maybe/None) = λa λ* a
|
||||
|
||||
(Maybe/Some) = λa λ* λc (c a)
|
||||
|
||||
NumScott
|
||||
(Foo) = λ$x (Maybe/Some 1 λa switch a { 0: $x; _: λ* λb b; })
|
||||
|
||||
(Bar) = (Maybe/Some 1 λa switch a { 0: $x; _: λ* λb b; } λ$x *)
|
||||
|
||||
(main) = *
|
||||
|
||||
(Maybe/None) = λa (a 0)
|
||||
|
||||
(Maybe/Some) = λa λb (b 1 a)
|
||||
|
@ -2,14 +2,28 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_auto_linearization.bend
|
||||
---
|
||||
Scott
|
||||
(switch_linearization) = λa let {a a_2 a_3 a_4} = a; λb let {b b_2 b_3 b_4 b_5} = b; let (c, d) = (a, b); let {d d_2} = d; let {c c_2} = c; switch a_2 { 0: let {e e_2} = 2; let {f g} = e; (b_2 e_2 f g (a_3, b_3) c d); _: λh let {i i_2} = 2; let {j k} = i; (h b_4 i_2 j k (a_4, b_5) c_2 d_2); }
|
||||
|
||||
(match_linearization) = λa let {a a_2 a_3 a_4} = a; λb let {b b_2 b_3 b_4 b_5} = b; let (c, d) = (a, b); let {d d_2} = d; let {c c_2} = c; (a_2 λe let {f f_2} = 2; let {g h} = f; (e b_2 f_2 g h (a_3, b_3) c d) let {i i_2} = 2; let {j k} = i; (b_4 i_2 j k (a_4, b_5) c_2 d_2))
|
||||
|
||||
(switch_shadowed_field) = λa switch a { 0: λb b; _: λc λ* c; }
|
||||
|
||||
(match_shadowed_field) = λa (a λb λc λ* λ* (List/Cons b c) λf λg (List/Cons f g))
|
||||
(match_shadowed_field) = λa (a λb λc (List/Cons b c) λd λe λ* λ* (List/Cons d e))
|
||||
|
||||
(List/Cons) = λa λb λc λ* (c a b)
|
||||
(List/Nil) = λa λ* a
|
||||
|
||||
(List/Nil) = λ* λb b
|
||||
(List/Cons) = λa λb λ* λd (d a b)
|
||||
|
||||
NumScott
|
||||
(switch_linearization) = λa let {a a_2 a_3 a_4} = a; λb let {b b_2 b_3 b_4 b_5} = b; let (c, d) = (a, b); let {d d_2} = d; let {c c_2} = c; switch a_2 { 0: let {e e_2} = 2; let {f g} = e; (b_2 e_2 f g (a_3, b_3) c d); _: λh let {i i_2} = 2; let {j k} = i; (h b_4 i_2 j k (a_4, b_5) c_2 d_2); }
|
||||
|
||||
(match_linearization) = λa let {a a_2 a_3 a_4} = a; λb let {b b_2 b_3 b_4 b_5} = b; let (c, d) = (a, b); let {d d_2} = d; let {c c_2} = c; (a_2 λe switch e { 0: λf let {g g_2} = 2; let {h i} = g; (f b_2 g_2 h i (a_3, b_3) c d); _: λ* let {j j_2} = 2; let {k l} = j; (b_4 j_2 k l (a_4, b_5) c_2 d_2); })
|
||||
|
||||
(switch_shadowed_field) = λa switch a { 0: λb b; _: λc λ* c; }
|
||||
|
||||
(match_shadowed_field) = λa (a λb switch b { 0: λc λd (List/Cons c d); _: λ* λe λf λ* λ* (List/Cons e f); })
|
||||
|
||||
(List/Nil) = λa (a 0)
|
||||
|
||||
(List/Cons) = λa λb λc (c 1 a b)
|
||||
|
@ -2,6 +2,12 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_bind.bend
|
||||
---
|
||||
Scott
|
||||
(cheese) = switch (+ 2 3) { 0: 653323; _: λa let {a a_2} = a; (+ (+ a 1) a_2); }
|
||||
|
||||
(main) = cheese
|
||||
|
||||
NumScott
|
||||
(cheese) = switch (+ 2 3) { 0: 653323; _: λa let {a a_2} = a; (+ (+ a 1) a_2); }
|
||||
|
||||
(main) = cheese
|
||||
|
@ -2,14 +2,28 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_num_adt_tup_parser.bend
|
||||
---
|
||||
(Parse) = λa λb (b λc λd λe (switch (- c 10) { 0: λf λg (Result_/Ok (0, g, f)); _: λh λi λj (switch (- h 29) { 0: λk λl (Result_/Ok (40, l, k)); _: λm λn λo (switch m { 0: λp λq (Result_/Ok (41, q, p)); _: λr λs λt (Result_/Err ((String/Cons (+ r 42) t), s)); } n o); } i j); } e d) λu (Result_/Err (String/Nil, u)) a)
|
||||
Scott
|
||||
(Parse) = λa λb (b λc (Result_/Err (String/Nil, c)) λd λe λf (switch (- d 10) { 0: λg λh (Result_/Ok (0, h, g)); _: λi λj λk (switch (- i 29) { 0: λl λm (Result_/Ok (40, m, l)); _: λn λo λp (switch n { 0: λq λr (Result_/Ok (41, r, q)); _: λs λt λu (Result_/Err ((String/Cons (+ s 42) u), t)); } o p); } j k); } f e) a)
|
||||
|
||||
(main) = (Parse * (String/Cons 40 (String/Cons 43 String/Nil)) λc let (d, e, f) = c; (d, (Parse f e)) λg (Result_/Err g))
|
||||
|
||||
(String/Cons) = λa λb λc λ* (c a b)
|
||||
(String/Nil) = λa λ* a
|
||||
|
||||
(String/Nil) = λ* λb b
|
||||
(String/Cons) = λa λb λ* λd (d a b)
|
||||
|
||||
(Result_/Ok) = λa λb λ* (b a)
|
||||
|
||||
(Result_/Err) = λa λ* λc (c a)
|
||||
|
||||
NumScott
|
||||
(Parse) = λa λb (b λc switch c { 0: λd (Result_/Err (String/Nil, d)); _: λ* λe λf λg (switch (- e 10) { 0: λh λi (Result_/Ok (0, i, h)); _: λj λk λl (switch (- j 29) { 0: λm λn (Result_/Ok (40, n, m)); _: λo λp λq (switch o { 0: λr λs (Result_/Ok (41, s, r)); _: λt λu λv (Result_/Err ((String/Cons (+ t 42) v), u)); } p q); } k l); } g f); } a)
|
||||
|
||||
(main) = (Parse * (String/Cons 40 (String/Cons 43 String/Nil)) λc switch c { 0: λd let (e, f, g) = d; (e, (Parse g f)); _: λ* λh (Result_/Err h); })
|
||||
|
||||
(String/Nil) = λa (a 0)
|
||||
|
||||
(String/Cons) = λa λb λc (c 1 a b)
|
||||
|
||||
(Result_/Ok) = λa λb (b 0 a)
|
||||
|
||||
(Result_/Err) = λa λb (b 1 a)
|
||||
|
@ -2,6 +2,18 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_num_pred.bend
|
||||
---
|
||||
Scott
|
||||
(pred) = λa switch a { 0: 0; _: λb b; }
|
||||
|
||||
(pred2) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc c; }; }
|
||||
|
||||
(pred3) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc switch c { 0: 0; _: λd (- (+ d 3) 3); }; }; }
|
||||
|
||||
(zero) = λa switch a { 0: 1; _: λb switch b { 0: 0; _: λ* 0; }; }
|
||||
|
||||
(main) = *
|
||||
|
||||
NumScott
|
||||
(pred) = λa switch a { 0: 0; _: λb b; }
|
||||
|
||||
(pred2) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc c; }; }
|
||||
|
@ -2,8 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/match_syntax.bend
|
||||
---
|
||||
Scott
|
||||
(head) = λa (a λb λ* b List_/Nil)
|
||||
|
||||
(List_/Cons) = λa λb λc λ* (c a b)
|
||||
|
||||
(List_/Nil) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(head) = λa (a λb switch b { 0: λc λ* c; _: λ* List_/Nil; })
|
||||
|
||||
(List_/Cons) = λa λb λc (c 0 a b)
|
||||
|
||||
(List_/Nil) = λa (a 1)
|
||||
|
@ -2,6 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/merge_recursive.bend
|
||||
---
|
||||
Scott
|
||||
(foo_1) = λa (a foo_2)
|
||||
|
||||
(foo_2) = λa λb (a, b)
|
||||
|
||||
(bar_1) = λa (a bar_2)
|
||||
|
||||
(bar_2) = λa λb (a, b)
|
||||
|
||||
NumScott
|
||||
(foo_1) = λa (a foo_2)
|
||||
|
||||
(foo_2) = λa λb (a, b)
|
||||
|
@ -2,6 +2,14 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/no_patterns.bend
|
||||
---
|
||||
Scott
|
||||
(Id) = λa a
|
||||
|
||||
(Id2) = λa a
|
||||
|
||||
(Pair) = λa λb (a, b)
|
||||
|
||||
NumScott
|
||||
(Id) = λa a
|
||||
|
||||
(Id2) = λa a
|
||||
|
@ -2,8 +2,16 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/non_matching_fst_arg.bend
|
||||
---
|
||||
Scott
|
||||
(Foo) = λa λb (b λc let {c c_2} = c; (Foo c c_2) λd d a)
|
||||
|
||||
(bool/true) = λa λ* a
|
||||
|
||||
(bool/false) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(Foo) = λa λb (b λc switch c { 0: λd let {d d_2} = d; (Foo d d_2); _: λ* λe e; } a)
|
||||
|
||||
(bool/true) = λa (a 0)
|
||||
|
||||
(bool/false) = λa (a 1)
|
||||
|
@ -2,6 +2,12 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/ntup_sum.bend
|
||||
---
|
||||
Scott
|
||||
(ntupSum) = λa let (b, c, d, e, f) = a; (+ b (+ c (+ d (+ e f))))
|
||||
|
||||
(main) = (ntupSum (1, 3, 3, 2, 1))
|
||||
|
||||
NumScott
|
||||
(ntupSum) = λa let (b, c, d, e, f) = a; (+ b (+ c (+ d (+ e f))))
|
||||
|
||||
(main) = (ntupSum (1, 3, 3, 2, 1))
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/pattern_match_encoding.bend
|
||||
---
|
||||
Scott
|
||||
(Foo) = λa (a λ* 100 λ* 200 λ* 200 λ* λ* 200 λ* λ* 200)
|
||||
|
||||
(main) = (Foo MyType/A 2)
|
||||
@ -15,3 +16,18 @@ input_file: tests/golden_tests/encode_pattern_match/pattern_match_encoding.bend
|
||||
(MyType/D) = λa λb λ* λ* λ* λf λ* (f a b)
|
||||
|
||||
(MyType/E) = λa λb λ* λ* λ* λ* λg (g a b)
|
||||
|
||||
NumScott
|
||||
(Foo) = λa (a λb switch b { 0: λ* 100; _: λd switch d { 0: λ* 200; _: λf switch f { 0: λ* 200; _: λh switch h { 0: λ* λ* 200; _: λ* λ* λ* 200; }; }; }; })
|
||||
|
||||
(main) = (Foo MyType/A 2)
|
||||
|
||||
(MyType/A) = λa λb (b 0 a)
|
||||
|
||||
(MyType/B) = λa λb (b 1 a)
|
||||
|
||||
(MyType/C) = λa λb (b 2 a)
|
||||
|
||||
(MyType/D) = λa λb λc (c 3 a b)
|
||||
|
||||
(MyType/E) = λa λb λc (c 4 a b)
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/switch_in_switch_arg.bend
|
||||
---
|
||||
Scott
|
||||
(main) = λa switch switch a { 0: 0; _: λb b; } { 0: 0; _: λc (+ c 1); }
|
||||
|
||||
NumScott
|
||||
(main) = λa switch switch a { 0: 0; _: λb b; } { 0: 0; _: λc (+ c 1); }
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/var_only.bend
|
||||
---
|
||||
Scott
|
||||
(Foo) = λa λ* λc (c a)
|
||||
|
||||
(main) = λ* Foo
|
||||
@ -9,3 +10,12 @@ input_file: tests/golden_tests/encode_pattern_match/var_only.bend
|
||||
(Bool/False) = λa λ* a
|
||||
|
||||
(Bool/True) = λ* λb b
|
||||
|
||||
NumScott
|
||||
(Foo) = λa λ* λc (c a)
|
||||
|
||||
(main) = λ* Foo
|
||||
|
||||
(Bool/False) = λa (a 0)
|
||||
|
||||
(Bool/True) = λa (a 1)
|
||||
|
@ -2,6 +2,7 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/encode_pattern_match/weekday.bend
|
||||
---
|
||||
Scott
|
||||
(main) = (λa a Weekday/Saturday)
|
||||
|
||||
(Weekday/Monday) = λa λ* λ* λ* λ* λ* λ* a
|
||||
@ -17,3 +18,20 @@ input_file: tests/golden_tests/encode_pattern_match/weekday.bend
|
||||
(Weekday/Saturday) = λ* λ* λ* λ* λ* λf λ* f
|
||||
|
||||
(Weekday/Sunday) = λ* λ* λ* λ* λ* λ* λg g
|
||||
|
||||
NumScott
|
||||
(main) = (λa a Weekday/Saturday)
|
||||
|
||||
(Weekday/Monday) = λa (a 0)
|
||||
|
||||
(Weekday/Tuesday) = λa (a 1)
|
||||
|
||||
(Weekday/Wednesday) = λa (a 2)
|
||||
|
||||
(Weekday/Thursday) = λa (a 3)
|
||||
|
||||
(Weekday/Friday) = λa (a 4)
|
||||
|
||||
(Weekday/Saturday) = λa (a 5)
|
||||
|
||||
(Weekday/Sunday) = λa (a 6)
|
||||
|
@ -2,15 +2,17 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/mutual_recursion/len.bend
|
||||
---
|
||||
@Len = ((@Len__C0 (0 a)) a)
|
||||
@Len = ((@Len__C1 a) a)
|
||||
|
||||
@Len__C0 = (* (a c))
|
||||
@Len__C0 = (* (* (a c)))
|
||||
& $(b c) ~ [+1]
|
||||
& @Len ~ (a b)
|
||||
|
||||
@List/Cons = (a (b ((a (b c)) (* c))))
|
||||
@Len__C1 = (?((0 @Len__C0) a) a)
|
||||
|
||||
@List/Nil = (* (a a))
|
||||
@List/Cons = (a (b ((1 (a (b c))) c)))
|
||||
|
||||
@List/Nil = ((0 a) a)
|
||||
|
||||
@main = g
|
||||
& @Len ~ (f g)
|
||||
|
@ -10,6 +10,6 @@ input_file: tests/golden_tests/parse_file/imp_map.bend
|
||||
|
||||
(main) = let x = (Map/set (Map/set Map/empty 2 1) 3 2); let (map/get%1, x) = (Map/get x 2); let y = (id map/get%1); let z = 4; let x = (Map/set x z 4); let (map/get%0, x) = (Map/get x z); (+ y map/get%0)
|
||||
|
||||
(Map/Node) = λvalue λleft λright λMap/Node λMap/Leaf (Map/Node value left right)
|
||||
(Map/Node) = λvalue λleft λright λ%x (%x 0 value left right)
|
||||
|
||||
(Map/Leaf) = λMap/Node λMap/Leaf Map/Leaf
|
||||
(Map/Leaf) = λ%x (%x 1)
|
||||
|
@ -36,16 +36,16 @@ input_file: tests/golden_tests/parse_file/imp_program.bend
|
||||
|
||||
(main) = do IO { ask x = IO.read; x }
|
||||
|
||||
(List/Cons) = λhead λtail λList/Cons λList/Nil (List/Cons head tail)
|
||||
(List/Nil) = λ%x (%x 0)
|
||||
|
||||
(List/Nil) = λList/Cons λList/Nil List/Nil
|
||||
(List/Cons) = λhead λtail λ%x (%x 1 head tail)
|
||||
|
||||
(Map/Node) = λvalue λleft λright λMap/Node λMap/Leaf (Map/Node value left right)
|
||||
(Map/Node) = λvalue λleft λright λ%x (%x 0 value left right)
|
||||
|
||||
(Map/Leaf) = λMap/Node λMap/Leaf Map/Leaf
|
||||
(Map/Leaf) = λ%x (%x 1)
|
||||
|
||||
(Point/Point) = λx λy λPoint/Point (Point/Point x y)
|
||||
(Point/Point) = λx λy λ%x (%x 0 x y)
|
||||
|
||||
(Bool/True) = λBool/True λBool/False Bool/True
|
||||
(Bool/True) = λ%x (%x 0)
|
||||
|
||||
(Bool/False) = λBool/True λBool/False Bool/False
|
||||
(Bool/False) = λ%x (%x 1)
|
||||
|
@ -4,6 +4,6 @@ input_file: tests/golden_tests/parse_file/scape_chars.bend
|
||||
---
|
||||
(main) = (String/Cons 92 (String/Cons 32 (String/Cons 10 (String/Cons 32 (String/Cons 9 (String/Cons 32 (String/Cons 34 String/Nil)))))))
|
||||
|
||||
(String/Cons) = λhead λtail λString/Cons λString/Nil (String/Cons head tail)
|
||||
(String/Nil) = λ%x (%x 0)
|
||||
|
||||
(String/Nil) = λString/Cons λString/Nil String/Nil
|
||||
(String/Cons) = λhead λtail λ%x (%x 1 head tail)
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/addition.bend
|
||||
---
|
||||
NumScott:
|
||||
10
|
||||
|
||||
Scott:
|
||||
10
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/adt_match.bend
|
||||
---
|
||||
NumScott:
|
||||
λa (a 0 2)
|
||||
|
||||
Scott:
|
||||
λa λ* (a 2)
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/adt_option_and.bend
|
||||
---
|
||||
NumScott:
|
||||
λa (a λa switch a { 0: λa λb (b λa switch a { 0: λa λb (Option/Some (b, a)); _: λ* λ* Option/None; } a); _: λ* λ* Option/None; })
|
||||
|
||||
Scott:
|
||||
λa (a λa λb (b λa λb (Option/Some (b, a)) λ* Option/None a) λ* Option/None)
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/and.bend
|
||||
---
|
||||
NumScott:
|
||||
bool/false
|
||||
|
||||
Scott:
|
||||
bool/false
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/bend_fold.bend
|
||||
---
|
||||
NumScott:
|
||||
24
|
||||
|
||||
Scott:
|
||||
24
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/bitonic_sort.bend
|
||||
---
|
||||
NumScott:
|
||||
120
|
||||
|
||||
Scott:
|
||||
120
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/bitonic_sort_lam.bend
|
||||
---
|
||||
NumScott:
|
||||
32640
|
||||
|
||||
Scott:
|
||||
32640
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/box.bend
|
||||
---
|
||||
NumScott:
|
||||
λa (a 0 λb (b 0 10))
|
||||
|
||||
Scott:
|
||||
λa (a λb (b 10))
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/branch_statements_assignment.bend
|
||||
---
|
||||
NumScott:
|
||||
6
|
||||
|
||||
Scott:
|
||||
6
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/callcc.bend
|
||||
---
|
||||
NumScott:
|
||||
52
|
||||
|
||||
Scott:
|
||||
52
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/chars.bend
|
||||
---
|
||||
NumScott:
|
||||
"ሴ!7"
|
||||
|
||||
Scott:
|
||||
"ሴ!7"
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/chars_forall.bend
|
||||
---
|
||||
NumScott:
|
||||
8704
|
||||
|
||||
Scott:
|
||||
8704
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/chars_lambda.bend
|
||||
---
|
||||
NumScott:
|
||||
955
|
||||
|
||||
Scott:
|
||||
955
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/def_tups.bend
|
||||
---
|
||||
NumScott:
|
||||
15
|
||||
|
||||
Scott:
|
||||
15
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/do_block_mixed.bend
|
||||
---
|
||||
NumScott:
|
||||
λa (a 0 1)
|
||||
|
||||
Scott:
|
||||
λa λ* (a 1)
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/dup_global_lam.bend
|
||||
---
|
||||
NumScott:
|
||||
λa a
|
||||
|
||||
Scott:
|
||||
λa a
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/erased_side_effect.bend
|
||||
---
|
||||
NumScott:
|
||||
123
|
||||
|
||||
Scott:
|
||||
123
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/escape_sequences.bend
|
||||
---
|
||||
NumScott:
|
||||
"\n\r\t\0\"'\u{afe}\\\n\r\t\0\"'\u{afe}\\"
|
||||
|
||||
Scott:
|
||||
"\n\r\t\0\"'\u{afe}\\\n\r\t\0\"'\u{afe}\\"
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/eta.bend
|
||||
---
|
||||
NumScott:
|
||||
Id
|
||||
|
||||
Scott:
|
||||
Id
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/example.bend
|
||||
---
|
||||
NumScott:
|
||||
8
|
||||
|
||||
Scott:
|
||||
8
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/extracted_match_pred.bend
|
||||
---
|
||||
NumScott:
|
||||
valZ
|
||||
|
||||
Scott:
|
||||
valZ
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/fold_with_state.bend
|
||||
---
|
||||
NumScott:
|
||||
[1, 2, 3]
|
||||
|
||||
Scott:
|
||||
[1, 2, 3]
|
||||
|
@ -2,4 +2,8 @@
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/id_underscore.bend
|
||||
---
|
||||
NumScott:
|
||||
{2 3}
|
||||
|
||||
Scott:
|
||||
{2 3}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user