[sc-663] Add num-scott adt encoding, it a cli opt

This commit is contained in:
Nicolas Abril 2024-05-18 14:01:20 +02:00
parent add15416db
commit f7a238c58a
163 changed files with 1447 additions and 394 deletions

View File

@ -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.

View File

@ -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}
```

View File

@ -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
@ -213,4 +219,30 @@ Example:
let r = (Swap (& n 4194304) r Map_/Free)
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`.

View File

@ -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 {

View File

@ -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))
_: *
})

View File

@ -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 {

View File

@ -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 }
}

View File

@ -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);

View File

@ -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),

View File

@ -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();
}
});

View File

@ -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))
}

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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"),
}
}
}

View File

@ -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
}

View File

@ -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)
})
}

View File

@ -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
)
)
)
)
)
)

View File

@ -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))

View File

@ -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'.

View File

@ -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)

View File

@ -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'

View File

@ -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

View File

@ -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))))

View File

@ -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)

View File

@ -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))

View File

@ -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))

View File

@ -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)))

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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)))

View File

@ -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)

View File

@ -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; }

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)))))

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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; })

View File

@ -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; }))

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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; }; }

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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)

View File

@ -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); }

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/addition.bend
---
NumScott:
10
Scott:
10

View File

@ -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)

View File

@ -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)

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/and.bend
---
NumScott:
bool/false
Scott:
bool/false

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/bend_fold.bend
---
NumScott:
24
Scott:
24

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/bitonic_sort.bend
---
NumScott:
120
Scott:
120

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/bitonic_sort_lam.bend
---
NumScott:
32640
Scott:
32640

View File

@ -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))

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/branch_statements_assignment.bend
---
NumScott:
6
Scott:
6

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/callcc.bend
---
NumScott:
52
Scott:
52

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/chars.bend
---
NumScott:
"ሴ!7"
Scott:
"ሴ!7"

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/chars_forall.bend
---
NumScott:
8704
Scott:
8704

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/chars_lambda.bend
---
NumScott:
955
Scott:
955

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/def_tups.bend
---
NumScott:
15
Scott:
15

View File

@ -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)

View File

@ -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

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/erased_side_effect.bend
---
NumScott:
123
Scott:
123

View File

@ -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}\\"

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/eta.bend
---
NumScott:
Id
Scott:
Id

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/example.bend
---
NumScott:
8
Scott:
8

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/extracted_match_pred.bend
---
NumScott:
valZ
Scott:
valZ

View File

@ -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]

View File

@ -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