[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 return default
``` ```
### Folding ### Folding and bending
We use `~` to indicate that a field is recursive. 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`. 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) 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`. 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. 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): def main(x1, x2, x3):
return MainBody(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) 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. 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. You can even pass more arguments than the function expects, although that can lead to unexpected results.
```rust ```py
// Expects 2 CLI arguments # Expects 2 CLI arguments
def main(x, y): def main(x, y):
return {x - y, y - x} return {x - y, y - x}
``` ```

View File

@ -11,6 +11,7 @@
| `-Omerge` `-Ono-merge` | Disabled | [definition-merging](#definition-merging) | | `-Omerge` `-Ono-merge` | Disabled | [definition-merging](#definition-merging) |
| `-Oinline` `-Ono-inline` | Disabled | [inline](#inline) | | `-Oinline` `-Ono-inline` | Disabled | [inline](#inline) |
| `-Ocheck-net-size` `-Ono-check-net-size` | Enabled | [check-net-size](#check-net-size) | | `-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 ## Eta-reduction
@ -130,7 +131,7 @@ These automatic linearization passes are done before the manual linearization fr
# These variables are only linearized once # These variables are only linearized once
λa λb λc switch a with b c { 0: (b c); _: (a-1 b c) } λ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) λa λb λc (switch a { 0: λb λc (b c); _: λb λc (a-1 b c) } b c)
# And not # And not
@ -160,21 +161,26 @@ fold = λinit λf λxs (xs λh λt (fold (f init h) f t) init)
# Inline # 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: Example:
```py ```py
foo = (2, 3) # program
foo = 2
id = λx x id = λx x
main = (id foo) main = (id foo)
# -Oinline, compilation output # -Ono-inline, compilation output
@foo = [#2 #3] @foo = 2
@id = (a a) @id = (a a)
@main = 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 ## Check-net-size
@ -213,4 +219,30 @@ Example:
let r = (Swap (& n 4194304) r Map_/Free) let r = (Swap (& n 4194304) r Map_/Free)
let r = (Swap (& n 8388608) r Map_/Free) let r = (Swap (& n 8388608) r Map_/Free)
r 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 ```python
def Result/bind(res, nxt): def Result/bind(res, nxt):
match res: match res:
case Result/ok: case Result/Ok:
return nxt(res.value) return nxt(res.value)
case Result/err: case Result/Err:
return res return res
``` ```
@ -915,17 +915,17 @@ match x {
### Monadic bind blocks ### Monadic bind blocks
```rust ```rust
Result/bind (Result.ok val) f = (f val) Result/bind (Result/Ok val) f = (f val)
Result/bind err _ = err Result/bind err _ = err
div a b = switch b { div a b = switch b {
0: (Result.err "Div by 0") 0: (Result/Err "Div by 0")
_: (Result.ok (/ a b)) _: (Result/Ok (/ a b))
} }
rem a b = switch b { rem a b = switch b {
0: (Result.err "Mod by 0") 0: (Result/Err "Mod by 0")
_: (Result.ok (% a b)) _: (Result/Ok (% a b))
} }
Main = do Result { Main = do Result {

View File

@ -1,5 +1,5 @@
data String = (Cons head ~tail) | (Nil) data String = (Nil) | (Cons head ~tail)
data List = (Cons head ~tail) | (Nil) data List = (Nil) | (Cons head ~tail)
data Result = (Ok val) | (Err val) data Result = (Ok val) | (Err val)
data Nat = (Succ ~pred) | (Zero) data Nat = (Succ ~pred) | (Zero)
@ -69,32 +69,3 @@ data IO
| (GetTime cont) | (GetTime cont)
| (Sleep time cont) | (Sleep time cont)
| (DrawImage tree 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 LIST: &str = "List";
pub const LCONS: &str = "List/Cons"; pub const LCONS: &str = "List/Cons";
pub const LNIL: &str = "List/Nil"; pub const LNIL: &str = "List/Nil";
pub const LCONS_TAG: u32 = 1;
pub const HEAD: &str = "head"; pub const HEAD: &str = "head";
pub const TAIL: &str = "tail"; pub const TAIL: &str = "tail";
@ -13,14 +14,12 @@ pub const TAIL: &str = "tail";
pub const STRING: &str = "String"; pub const STRING: &str = "String";
pub const SCONS: &str = "String/Cons"; pub const SCONS: &str = "String/Cons";
pub const SNIL: &str = "String/Nil"; pub const SNIL: &str = "String/Nil";
pub const SCONS_TAG: u32 = 1;
pub const RESULT: &str = "Result";
pub const RESULT_OK: &str = "Result/Ok";
pub const RESULT_ERR: &str = "Result/Err";
pub const NAT: &str = "Nat"; pub const NAT: &str = "Nat";
pub const NAT_SUCC: &str = "Nat/Succ"; pub const NAT_SUCC: &str = "Nat/Succ";
pub const NAT_ZERO: &str = "Nat/Zero"; pub const NAT_ZERO: &str = "Nat/Zero";
pub const NAT_SUCC_TAG: u32 = 0;
impl Book { impl Book {
pub fn builtins() -> Book { pub fn builtins() -> Book {
@ -69,14 +68,6 @@ impl Term {
pub fn encode_nat(val: u32) -> 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)) (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 { impl Pattern {

View File

@ -429,14 +429,22 @@ impl From<Option<Name>> for Pattern {
impl Term { impl Term {
/* Common construction patterns */ /* Common construction patterns */
/// Lambda with a static tag
pub fn lam(pat: Pattern, bod: Term) -> Self { pub fn lam(pat: Pattern, bod: Term) -> Self {
Self::tagged_lam(Tag::Static, pat, bod) Self::tagged_lam(Tag::Static, pat, bod)
} }
/// Lambda with any tag
pub fn tagged_lam(tag: Tag, pat: Pattern, bod: Term) -> Self { pub fn tagged_lam(tag: Tag, pat: Pattern, bod: Term) -> Self {
Term::Lam { tag, pat: Box::new(pat), bod: Box::new(bod) } 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 { pub fn var_or_era(nam: Option<Name>) -> Self {
if let Some(nam) = nam { Term::Var { nam } } else { Term::Era } if let Some(nam) = nam { Term::Var { nam } } else { Term::Era }
} }

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
diagnostics::Diagnostics, diagnostics::Diagnostics,
fun::{Ctx, Definition, Name, Pattern, Rule, Term}, fun::{Ctx, Definition, Name, Rule, Term},
maybe_grow, maybe_grow,
}; };
@ -74,9 +74,8 @@ impl Term {
pred: Some(Name::new("_-1")), pred: Some(Name::new("_-1")),
arms: vec![std::mem::take(base.as_mut()), std::mem::take(step.as_mut())], 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 = Term::rfold_lams(body, free_vars.iter().cloned().map(Some));
let body = let body = Term::rfold_lams(body, std::mem::take(bind).into_iter());
bind.iter_mut().rfold(body, |acc, bind| Term::lam(Pattern::Var(std::mem::take(bind)), acc));
let def = let def =
Definition { name: new_nam.clone(), rules: vec![Rule { pats: vec![], body }], builtin: false }; Definition { name: new_nam.clone(), rules: vec![Rule { pats: vec![], body }], builtin: false };
new_defs.push(def); new_defs.push(def);

View File

@ -45,7 +45,7 @@ impl Definition {
let rules = std::mem::take(&mut self.rules); let rules = std::mem::take(&mut self.rules);
match simplify_rule_match(args.clone(), rules, vec![], ctrs, adts) { match simplify_rule_match(args.clone(), rules, vec![], ctrs, adts) {
Ok(body) => { 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 }]; self.rules = vec![Rule { pats: vec![], body }];
} }
Err(e) => errs.push(e), Err(e) => errs.push(e),

View File

@ -14,20 +14,20 @@ impl Book {
/// // Transforms to: /// // Transforms to:
/// (λx x λx x λx x) /// (λ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 def in self.defs.values_mut() {
for rule in def.rules.iter_mut() { for rule in def.rules.iter_mut() {
rule.body.apply_use(); rule.body.desugar_use();
} }
} }
} }
} }
impl Term { impl Term {
pub fn apply_use(&mut self) { pub fn desugar_use(&mut self) {
maybe_grow(|| { maybe_grow(|| {
for children in self.children_mut() { 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 { impl Book {
/// Defines a function for each constructor in each ADT in the 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![]; let mut defs = vec![];
for adt in self.adts.values() { 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 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 rules = vec![Rule { pats: vec![], body }];
let def = Definition { name: ctr_name.clone(), rules, builtin: adt.builtin }; 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, ctr_args: impl DoubleEndedIterator<Item = &'a Name> + Clone,
ctrs: Vec<Name>, ctrs: Vec<Name>,
ctr_name: &Name, ctr_name: &Name,
) -> Term { ) -> Term {
let tag = Tag::Static;
let ctr = Term::Var { nam: ctr_name.clone() }; let ctr = Term::Var { nam: ctr_name.clone() };
let app = let app = Term::call(ctr, ctr_args.clone().cloned().map(|nam| Term::Var { nam }));
ctr_args.clone().cloned().fold(ctr, |acc, nam| Term::tagged_app(tag.clone(), acc, Term::Var { nam })); let lam = Term::rfold_lams(app, ctrs.into_iter().map(Some));
let lam =
ctrs.into_iter().rfold(app, |acc, arg| Term::tagged_lam(tag.clone(), Pattern::Var(Some(arg)), acc));
ctr_args.cloned().rfold(lam, |acc, arg| Term::lam(Pattern::Var(Some(arg)), acc)) 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::{ use crate::{
fun::{Book, MatchRule, Name, Pattern, Tag, Term}, fun::{Book, MatchRule, Name, Pattern, Term},
maybe_grow, maybe_grow, AdtEncoding,
}; };
impl Book { impl Book {
@ -12,27 +12,27 @@ impl Book {
/// Num matches are encoded as a sequence of native num matches (on 0 and 1+). /// Num matches are encoded as a sequence of native num matches (on 0 and 1+).
/// ///
/// Var and pair matches become a let expression. /// 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 def in self.defs.values_mut() {
for rule in &mut def.rules { for rule in &mut def.rules {
rule.body.encode_matches(); rule.body.encode_matches(adt_encoding);
} }
} }
} }
} }
impl Term { impl Term {
pub fn encode_matches(&mut self) { pub fn encode_matches(&mut self, adt_encoding: AdtEncoding) {
maybe_grow(|| { maybe_grow(|| {
for child in self.children_mut() { for child in self.children_mut() {
child.encode_matches() child.encode_matches(adt_encoding)
} }
if let Term::Mat { arg, bnd: _, with, arms: rules } = self { if let Term::Mat { arg, bnd: _, with, arms: rules } = self {
assert!(with.is_empty()); assert!(with.is_empty());
let arg = std::mem::take(arg.as_mut()); let arg = std::mem::take(arg.as_mut());
let rules = std::mem::take(rules); 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 { } else if let Term::Swt { arg, bnd: _, with, pred, arms: rules } = self {
assert!(with.is_empty()); assert!(with.is_empty());
let arg = std::mem::take(arg.as_mut()); let arg = std::mem::take(arg.as_mut());
@ -44,15 +44,46 @@ impl Term {
} }
} }
fn encode_match(arg: Term, rules: Vec<MatchRule>) -> Term { fn encode_match(arg: Term, rules: Vec<MatchRule>, adt_encoding: AdtEncoding) -> Term {
let tag = Tag::Static; match adt_encoding {
let mut arms = vec![]; AdtEncoding::Scott => {
for rule in rules.into_iter() { let arms = rules.into_iter().map(|rule| Term::rfold_lams(rule.2, rule.1.into_iter()));
let body = Term::call(arg, arms)
rule.1.iter().cloned().rfold(rule.2, |bod, nam| Term::tagged_lam(tag.clone(), Pattern::Var(nam), bod)); }
arms.push(body); 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. /// 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_args;
pub mod apply_use;
pub mod definition_merge; pub mod definition_merge;
pub mod definition_pruning; pub mod definition_pruning;
pub mod desugar_bend; pub mod desugar_bend;
@ -7,6 +6,7 @@ pub mod desugar_do_blocks;
pub mod desugar_fold; pub mod desugar_fold;
pub mod desugar_match_defs; pub mod desugar_match_defs;
pub mod desugar_open; pub mod desugar_open;
pub mod desugar_use;
pub mod encode_adts; pub mod encode_adts;
pub mod encode_match_terms; pub mod encode_match_terms;
pub mod expand_generated; pub mod expand_generated;

View File

@ -1,11 +1,20 @@
use crate::{ use crate::{
fun::{builtins, Pattern, Tag, Term}, fun::{builtins, Num, Pattern, Tag, Term},
maybe_grow, maybe_grow, AdtEncoding,
}; };
use builtins::LCONS_TAG;
impl Term { impl Term {
/// Converts lambda-encoded lists ending with List/Nil to list literals. /// 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(|| { maybe_grow(|| {
// Search for a List/Cons pattern in the term and try to build a list from that point on. // 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 successful, replace the term with the list.
@ -13,24 +22,29 @@ impl Term {
match self { match self {
// Nil: List/nil // Nil: List/nil
Term::Ref { nam } if nam == builtins::LNIL => *self = Term::List { els: vec![] }, 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 { Term::Lam {
tag: Tag::Static, tag: Tag::Static,
pat: box Pattern::Var(Some(nam_cons_lam)), pat: box Pattern::Var(Some(var_lam)),
bod: bod:
box Term::Lam { box Term::App {
tag: Tag::Static, tag: Tag::Static,
pat: box Pattern::Var(None), fun:
bod:
box Term::App { box Term::App {
tag: Tag::Static, tag: Tag::Static,
fun: box Term::App { tag: Tag::Static, fun: box Term::Var { nam: nam_cons_app }, arg: head }, fun:
arg: tail, 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 => { } if var_lam == var_app => {
head.resugar_lists(); head.resugar_lists_num_scott();
if let Some(els) = build_list(tail, vec![head]) { if let Some(els) = build_list_num_scott(tail, vec![head]) {
*self = Term::List { els }; *self = Term::List { els };
} else { } else {
// Not a list term, keep as-is. // 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 }, fun: box Term::App { tag: Tag::Static, fun: box Term::Ref { nam }, arg: head },
arg: tail, arg: tail,
} if nam == builtins::LCONS => { } 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 }; *self = Term::List { els };
} else { } else {
// Not a list term, keep as-is. // Not a list term, keep as-is.
@ -52,25 +66,126 @@ impl Term {
} }
for child in self.children_mut() { 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(|| { maybe_grow(|| {
match term { match term {
// Nil: List/Nil // Nil: List/Nil
Term::Ref { nam } if nam == builtins::LNIL => Some(s.into_iter().map(std::mem::take).collect()), 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 { Term::Lam {
tag: Tag::Static, 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: bod:
box Term::Lam { box Term::Lam {
tag: Tag::Static, tag: Tag::Static,
pat: box Pattern::Var(None), pat: box Pattern::Var(Some(nam_cons_lam)),
bod: bod:
box Term::App { box Term::App {
tag: Tag::Static, 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 => { } if nam_cons_lam == nam_cons_app => {
// New list element, append and recurse // New list element, append and recurse
s.push(head.as_mut()); s.push(head.as_mut());
build_list(tail, s) build_list_scott(tail, s)
} }
// Cons: (List/cons <term> <term>) // Cons: (List/cons <term> <term>)
Term::App { Term::App {
@ -91,7 +206,7 @@ fn build_list(term: &mut Term, mut s: Vec<&mut Term>) -> Option<Vec<Term>> {
} if nam == builtins::LCONS => { } if nam == builtins::LCONS => {
// New list element, append and recurse // New list element, append and recurse
s.push(head.as_mut()); s.push(head.as_mut());
build_list(tail, s) build_list_scott(tail, s)
} }
_ => { _ => {
// Not a list term, stop // Not a list term, stop

View File

@ -1,11 +1,21 @@
use builtins::SCONS_TAG;
use crate::{ use crate::{
fun::{builtins, Num, Pattern, Tag, Term}, fun::{builtins, Num, Pattern, Tag, Term},
maybe_grow, maybe_grow, AdtEncoding,
}; };
impl Term { impl Term {
/// Converts lambda-encoded strings ending with String/nil to a string literals. /// 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(|| { maybe_grow(|| {
// Search for a String/cons pattern in the term and try to build a string from that point on. // 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 successful, replace the term with the string.
@ -13,14 +23,78 @@ impl Term {
match self { match self {
// Nil: String/nil // Nil: String/nil
Term::Ref { nam } if nam == builtins::SNIL => *self = Term::str(""), Term::Ref { nam } if nam == builtins::SNIL => *self = Term::str(""),
// Cons: @a @* (a <num> <str>) // Cons: @x (x CONS_TAG <num> <str>)
Term::Lam { Term::Lam {
tag: Tag::Static, 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: bod:
box Term::Lam { box Term::Lam {
tag: Tag::Static, tag: Tag::Static,
pat: box Pattern::Var(None), pat: box Pattern::Var(Some(nam_cons_lam)),
bod: bod:
box Term::App { box Term::App {
tag: Tag::Static, tag: Tag::Static,
@ -35,7 +109,7 @@ impl Term {
}, },
} if nam_cons_lam == nam_cons_app => { } if nam_cons_lam == nam_cons_app => {
let head = char::from_u32(*c).unwrap_or('.'); 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); *self = Term::str(&str);
} else { } else {
// Not a string term, keep as-is. // Not a string term, keep as-is.
@ -53,7 +127,7 @@ impl Term {
arg: nxt, arg: nxt,
} if nam == builtins::SCONS => { } if nam == builtins::SCONS => {
let head = char::from_u32(*c).unwrap_or('.'); 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); *self = Term::str(&str);
} else { } else {
// Not a string term, keep as-is. // Not a string term, keep as-is.
@ -63,25 +137,80 @@ impl Term {
} }
for child in self.children_mut() { 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(|| { maybe_grow(|| {
match term { match term {
// Nil: String/nil // Nil: String/nil
Term::Ref { nam } if nam == builtins::SNIL => Some(s), Term::Ref { nam } if nam == builtins::SNIL => Some(s),
// Cons: @a @* (a <num> <str>) // Cons: @x (x CONS_TAG <num> <str>)
Term::Lam { Term::Lam {
tag: Tag::Static, 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: bod:
box Term::Lam { box Term::Lam {
tag: Tag::Static, tag: Tag::Static,
pat: box Pattern::Var(None), pat: box Pattern::Var(Some(nam_cons_lam)),
bod: bod:
box Term::App { box Term::App {
tag: Tag::Static, tag: Tag::Static,
@ -98,7 +227,7 @@ fn build_string(term: &Term, mut s: String) -> Option<String> {
// New string character, append and recurse // New string character, append and recurse
let head = char::from_u32(*c).unwrap_or('.'); let head = char::from_u32(*c).unwrap_or('.');
s.push(head); s.push(head);
build_string(nxt, s) build_string_scott(nxt, s)
} }
// Cons: (String/cons <num> <str>) // Cons: (String/cons <num> <str>)
Term::App { Term::App {
@ -114,7 +243,7 @@ fn build_string(term: &Term, mut s: String) -> Option<String> {
// New string character, append and recurse // New string character, append and recurse
let head = char::from_u32(*c).unwrap_or('.'); let head = char::from_u32(*c).unwrap_or('.');
s.push(head); s.push(head);
build_string(nxt, s) build_string_scott(nxt, s)
} }
_ => { _ => {
// Not a string term, stop // 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 { if count > 1 {
for (pri, a, b) in net.redexes.iter_mut().rev() { for (pri, a, b) in net.redexes.iter_mut().rev() {
if let Tree::Ref { nam } = a { if let Tree::Ref { nam } = a {

View File

@ -86,7 +86,7 @@ pub fn desugar_book(
ctx.set_entrypoint(); ctx.set_entrypoint();
ctx.book.encode_adts(); ctx.book.encode_adts(opts.adt_encoding);
ctx.fix_match_defs()?; ctx.fix_match_defs()?;
@ -119,13 +119,13 @@ pub fn desugar_book(
// Manual match linearization // Manual match linearization
ctx.book.linearize_match_with(); ctx.book.linearize_match_with();
ctx.book.encode_matches(); ctx.book.encode_matches(opts.adt_encoding);
// sanity check // sanity check
ctx.check_unbound_vars()?; ctx.check_unbound_vars()?;
ctx.book.make_var_names_unique(); ctx.book.make_var_names_unique();
ctx.book.apply_use(); ctx.book.desugar_use();
ctx.book.make_var_names_unique(); ctx.book.make_var_names_unique();
ctx.book.linearize_vars(); 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()); 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))) Ok(Some((term, stats.to_string(), diags)))
} }
pub fn run_book( pub fn readback_hvm_net(
book: Book, net: &Net,
run_opts: RunOpts, book: &Book,
compile_opts: CompileOpts, labels: &Labels,
diagnostics_cfg: DiagnosticsConfig, linear: bool,
args: Option<Vec<Term>>, adt_encoding: AdtEncoding,
) -> Result<(Term, String, Diagnostics), Diagnostics> { ) -> (Term, 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) {
let mut diags = Diagnostics::default(); let mut diags = Diagnostics::default();
let net = hvmc_to_net(net); let net = hvmc_to_net(net);
let mut term = net_to_term(&net, book, labels, linear, &mut diags); let mut term = net_to_term(&net, book, labels, linear, &mut diags);
term.expand_generated(book); term.expand_generated(book);
term.resugar_strings(); term.resugar_strings(adt_encoding);
term.resugar_lists(); term.resugar_lists(adt_encoding);
(term, diags) (term, diags)
} }
@ -268,6 +265,9 @@ pub struct CompileOpts {
/// Enables [hvm::check_net_size]. /// Enables [hvm::check_net_size].
pub check_net_size: bool, pub check_net_size: bool,
/// Determines the encoding of constructors and matches.
pub adt_encoding: AdtEncoding,
} }
impl CompileOpts { impl CompileOpts {
@ -282,6 +282,7 @@ impl CompileOpts {
inline: true, inline: true,
linearize_matches: OptLevel::Enabled, linearize_matches: OptLevel::Enabled,
check_net_size: self.check_net_size, check_net_size: self.check_net_size,
adt_encoding: self.adt_encoding,
} }
} }
@ -296,6 +297,7 @@ impl CompileOpts {
merge: false, merge: false,
inline: false, inline: false,
check_net_size: self.check_net_size, check_net_size: self.check_net_size,
adt_encoding: self.adt_encoding,
} }
} }
@ -324,6 +326,22 @@ impl Default for CompileOpts {
merge: false, merge: false,
inline: false, inline: false,
check_net_size: true, 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, check_book, compile_book, desugar_book,
diagnostics::{Diagnostics, DiagnosticsConfig, Severity}, diagnostics::{Diagnostics, DiagnosticsConfig, Severity},
fun::{Book, Name}, 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 clap::{Args, CommandFactory, Parser, Subcommand};
use std::{ use std::{
@ -186,6 +186,8 @@ pub enum OptArgs {
NoInline, NoInline,
CheckNetSize, CheckNetSize,
NoCheckNetSize, NoCheckNetSize,
AdtScott,
AdtNumScott,
} }
fn compile_opts_from_cli(args: &Vec<OptArgs>) -> CompileOpts { 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, LinearizeMatches => opts.linearize_matches = OptLevel::Enabled,
LinearizeMatchesAlt => opts.linearize_matches = OptLevel::Alt, LinearizeMatchesAlt => opts.linearize_matches = OptLevel::Alt,
NoLinearizeMatches => opts.linearize_matches = OptLevel::Disabled, 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}"); eprint!("{diagnostics}");
return ExitCode::FAILURE; return ExitCode::FAILURE;
} }
ExitCode::SUCCESS ExitCode::SUCCESS
} }

View File

@ -1,9 +1,9 @@
use bend::{ use bend::{
compile_book, desugar_book, compile_book, desugar_book,
diagnostics::{Diagnostics, DiagnosticsConfig, Severity}, 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, net::hvmc_to_net::hvmc_to_net,
run_book, CompileOpts, RunOpts, run_book_with_fn, AdtEncoding, CompileOpts, RunOpts,
}; };
use insta::assert_snapshot; use insta::assert_snapshot;
use itertools::Itertools; 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 /* Snapshot/regression/golden tests
Each tests runs all the files in tests/golden_tests/<test name>. 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| { run_golden_test_dir_multiple(function_name!(), &[(&|code, path| {
let _guard = RUN_MUTEX.lock().unwrap(); let _guard = RUN_MUTEX.lock().unwrap();
let book = do_parse_book(code, path, Book::builtins())?; let book = do_parse_book(code, path, Book::builtins())?;
let compile_opts = CompileOpts::default();
let diagnostics_cfg = DiagnosticsConfig { let diagnostics_cfg = DiagnosticsConfig {
unused_definition: Severity::Allow, unused_definition: Severity::Allow,
..DiagnosticsConfig::new(Severity::Error, true) ..DiagnosticsConfig::new(Severity::Error, true)
}; };
let run_opts = RunOpts::default(); let run_opts = RunOpts::default();
let (term, _, diags) = run_book(book, run_opts, compile_opts, diagnostics_cfg, None)?; let mut res = String::new();
let res = format!("{diags}{term}");
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) Ok(res)
})]) })])
} }
@ -208,7 +222,7 @@ fn simplify_matches() {
ctx.check_shared_names(); ctx.check_shared_names();
ctx.set_entrypoint(); ctx.set_entrypoint();
ctx.book.encode_adts(); ctx.book.encode_adts(AdtEncoding::NumScott);
ctx.fix_match_defs()?; ctx.fix_match_defs()?;
ctx.book.encode_builtins(); ctx.book.encode_builtins();
ctx.resolve_refs()?; ctx.resolve_refs()?;
@ -220,7 +234,7 @@ fn simplify_matches() {
ctx.book.linearize_match_with(); ctx.book.linearize_match_with();
ctx.check_unbound_vars()?; ctx.check_unbound_vars()?;
ctx.book.make_var_names_unique(); ctx.book.make_var_names_unique();
ctx.book.apply_use(); ctx.book.desugar_use();
ctx.book.make_var_names_unique(); ctx.book.make_var_names_unique();
ctx.prune(false); ctx.prune(false);
@ -234,7 +248,7 @@ fn parse_file() {
let mut book = do_parse_book(code, path, Book::builtins())?; let mut book = do_parse_book(code, path, Book::builtins())?;
let mut ctx = Ctx::new(&mut book, Default::default()); let mut ctx = Ctx::new(&mut book, Default::default());
ctx.set_entrypoint(); ctx.set_entrypoint();
ctx.book.encode_adts(); ctx.book.encode_adts(AdtEncoding::NumScott);
ctx.book.encode_builtins(); ctx.book.encode_builtins();
ctx.resolve_refs().expect("Resolve refs"); ctx.resolve_refs().expect("Resolve refs");
ctx.desugar_match_defs().expect("Desugar match defs"); ctx.desugar_match_defs().expect("Desugar match defs");
@ -247,30 +261,32 @@ fn parse_file() {
fn encode_pattern_match() { fn encode_pattern_match() {
run_golden_test_dir(function_name!(), &|code, path| { run_golden_test_dir(function_name!(), &|code, path| {
let mut result = String::new(); let mut result = String::new();
let diagnostics_cfg = DiagnosticsConfig::default(); for adt_encoding in [AdtEncoding::Scott, AdtEncoding::NumScott] {
let mut book = do_parse_book(code, path, Book::builtins())?; let diagnostics_cfg = DiagnosticsConfig::default();
let mut ctx = Ctx::new(&mut book, diagnostics_cfg); let mut book = do_parse_book(code, path, Book::builtins())?;
ctx.check_shared_names(); let mut ctx = Ctx::new(&mut book, diagnostics_cfg);
ctx.set_entrypoint(); ctx.check_shared_names();
ctx.book.encode_adts(); ctx.set_entrypoint();
ctx.fix_match_defs()?; ctx.book.encode_adts(adt_encoding);
ctx.book.encode_builtins(); ctx.fix_match_defs()?;
ctx.resolve_refs()?; ctx.book.encode_builtins();
ctx.desugar_match_defs()?; ctx.resolve_refs()?;
ctx.fix_match_terms()?; ctx.desugar_match_defs()?;
ctx.check_unbound_vars()?; ctx.fix_match_terms()?;
ctx.book.make_var_names_unique(); ctx.check_unbound_vars()?;
ctx.book.linearize_match_binds(); ctx.book.make_var_names_unique();
ctx.book.linearize_match_with(); ctx.book.linearize_match_binds();
ctx.book.encode_matches(); ctx.book.linearize_match_with();
ctx.check_unbound_vars()?; ctx.book.encode_matches(adt_encoding);
ctx.book.make_var_names_unique(); ctx.check_unbound_vars()?;
ctx.book.apply_use(); ctx.book.make_var_names_unique();
ctx.book.make_var_names_unique(); ctx.book.desugar_use();
ctx.book.linearize_vars(); ctx.book.make_var_names_unique();
ctx.prune(false); ctx.book.linearize_vars();
ctx.prune(false);
writeln!(result, "{}\n", ctx.book).unwrap(); writeln!(result, "{adt_encoding}\n{}\n", ctx.book).unwrap();
}
Ok(result) 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/cli/compile_all.bend 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.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 @main = b
& @Pair.get ~ (@main__C0 (a 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 input_file: tests/golden_tests/cli/compile_pre_reduce.bend
--- ---
error: invalid value 'pre-reduce' for '-O <COMP_OPTS>' 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'. For more information, try '--help'.

View File

@ -2,12 +2,12 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/cli/compile_strict_loop.bend 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) & @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 @main = c
& @A ~ (b 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 input_file: tests/golden_tests/cli/compile_wrong_opt.bend
--- ---
error: invalid value 'foo' for '-O <COMP_OPTS>' 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' tip: a similar value exists: 'float-combinators'

View File

@ -2,7 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/cli/desugar_bool_scott.bend input_file: tests/golden_tests/cli/desugar_bool_scott.bend
--- ---
error: invalid value 'adt-scott' for '-O <COMP_OPTS>' (main) = Boolean/True
[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]
For more information, try '--help'. (Boolean/True) = λa λ* a
(Boolean/False) = λ* λa a

View File

@ -2,9 +2,9 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file/huge_tree.bend 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 @main = e
& @Tree/Node ~ (a (b (c (d 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)))) @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/Cons ~ (a (d e))
& @List.concat ~ (b (c d)) & @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.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] & $(b c) ~ [+1]
& @List.len ~ (a b) & @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)) & @List.len_tr ~ (a (c d))
& $(b c) ~ [+1] & $(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/Cons ~ (b (e f))
& @List.map ~ (c (d e)) & @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.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.concat ~ (b (d e))
& @List.reverse_bad ~ (a b) & @List.reverse_bad ~ (a b)
& @List/Cons ~ (c (@List/Nil d)) & @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.reverse_over ~ (a (d e))
& @List/Cons ~ (b (c d)) & @List/Cons ~ (b (c d))
@List.reverse_over__C1 = (?(((a a) @List.reverse_over__C0) b) b)
@List.reverse_tr = (a (* b)) @List.reverse_tr = (a (* b))
& @List.reverse_over ~ (a (@List/Nil 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.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.flip = ((@Tree.flip__C2 a) a)
& @Tree/leaf ~ a
@Tree.flip__C1 = (c (a e)) @Tree.flip__C0 = (c (a e))
& @Tree/node ~ (b (d e)) & @Tree/node ~ (b (d e))
&! @Tree.flip ~ (a b) &! @Tree.flip ~ (a b)
&! @Tree.flip ~ (c d) &! @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)) @Tree.height__C0 = (a (c f))
& $(e f) ~ [+1] & $(e f) ~ [+1]
@ -81,32 +101,40 @@ input_file: tests/golden_tests/compile_file/redex_order_recursive.bend
&! @Tree.height ~ (a b) &! @Tree.height ~ (a b)
&! @Tree.height ~ (c d) &! @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__C0 = (a (b d))
&! @Tree.leaves ~ (a $(:[+] $(c d))) &! @Tree.leaves ~ (a $(:[+] $(c d)))
&! @Tree.leaves ~ (b c) &! @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.map = ((@Tree.map__C2 a) a)
& @Tree/leaf ~ (b c)
@Tree.map__C1 = (a (d ({b e} g))) @Tree.map__C0 = (a (d ({b e} g)))
& @Tree/node ~ (c (f g)) & @Tree/node ~ (c (f g))
&! @Tree.map ~ (a (b c)) &! @Tree.map ~ (a (b c))
&! @Tree.map ~ (d (e f)) &! @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)) @Tree.nodes__C0 = (a (b e))
& $(d e) ~ [+1] & $(d e) ~ [+1]
&! @Tree.nodes ~ (a $(:[+] $(c d))) &! @Tree.nodes ~ (a $(:[+] $(c d)))
&! @Tree.nodes ~ (b c) &! @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) @add = ((@add__C0 ((a a) b)) b)

View File

@ -2,16 +2,20 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/adt_option_and.bend 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/and__C0 = (b (a c))
& @Option/Some ~ ((a b) 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 @main = c
& @Option/and ~ (a (b c)) & @Option/and ~ (a (b c))

View File

@ -2,11 +2,13 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/and.bend 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 @main = a
& @and ~ (@bool/true (@bool/false a)) & @and ~ (@bool/true (@bool/false a))

View File

@ -2,21 +2,21 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/expr.bend 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 @main = n
& @Expr/Let ~ (a (f (m n))) & @Expr/Let ~ (a (f (m n)))

View File

@ -2,40 +2,45 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/list_merge_sort.bend 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))) @Map__C0 = (a (c ({(a b) d} f)))
& @List_/Cons ~ (b (e f)) & @List_/Cons ~ (b (e f))
& @Map ~ (c (d e)) & @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)) @MergePair = (a ((@MergePair__C4 (a b)) b))
& @List_/Cons ~ (a (@Bool/False__M_List_/Nil b))
@MergePair__C1 = (c (f ({a e} (b h)))) @MergePair__C0 = (c (f ({a e} (b h))))
& @List_/Cons ~ (d (g h)) & @List_/Cons ~ (d (g h))
& @Merge ~ (a (b (c d))) & @Merge ~ (a (b (c d)))
& @MergePair ~ (e (f g)) & @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)) @MergeSort = (a (b d))
& @Unpack ~ (a (c d)) & @Unpack ~ (a (c d))
& @Map ~ (b (@Pure c)) & @Map ~ (b (@Pure c))
@Merge__C0 = (* a) @Merge__C0 = ({b {g l}} ({h q} ({(a (b c)) {e m}} ({a {d n}} ({f o} t)))))
& @List_/Cons ~ a
@Merge__C1 = ({b {g l}} ({h q} ({(a (b c)) {e m}} ({a {d n}} ({f o} t)))))
& @If ~ (c (k (s t))) & @If ~ (c (k (s t)))
& @List_/Cons ~ (d (j k)) & @List_/Cons ~ (d (j k))
&! @Merge ~ (e (f (i j))) &! @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))) &! @Merge ~ (m (p (q r)))
& @List_/Cons ~ (n (o p)) & @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) @Pure = (a b)
& @List_/Cons ~ (a (@Bool/False__M_List_/Nil 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__C0 = (d (e ({a b} (c i))))
& @Unpack ~ (a (h 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 ~ (c (f g))
& @List_/Cons ~ (d (e f)) & @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 @main = @MergeSort

View File

@ -2,15 +2,17 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/list_reverse.bend 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))) @concat__C0 = (a (b (c e)))
& @list/cons ~ (a (d e)) & @list/cons ~ (a (d e))
& @concat ~ (b (c d)) & @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 @main = d
& @reverse ~ (c 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 ~ (2 (a b))
& @list/cons ~ (1 (@list/nil a)) & @list/cons ~ (1 (@list/nil a))
@reverse = ((@reverse__C0 (@list/nil a)) a) @reverse = ((@reverse__C1 a) a)
@reverse__C0 = (c (a e)) @reverse__C0 = (c (a e))
& @concat ~ (b (d e)) & @concat ~ (b (d e))
& @reverse ~ (a b) & @reverse ~ (a b)
& @list/cons ~ (c (@list/nil d)) & @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 source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/long_str_file.bend 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 @main = r
& @String/Cons ~ (40 (q r)) & @String/Cons ~ (40 (q r))

View File

@ -2,13 +2,15 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/match_dup_and_reconstruction.bend 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)) @Got__C0 = ({a c} (b c))
& @Box/Boxed ~ (a b) & @Box/Boxed ~ (a b)
@Got__C1 = (?((@Got__C0 *) a) a)
@main = b @main = b
& @Got ~ (a b) & @Got ~ (a b)
& @Box/Boxed ~ (10 a) & @Box/Boxed ~ (10 a)

View File

@ -2,13 +2,15 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/num_pattern_with_var.bend 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__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 @main = a
& @Foo ~ (@bool/true (3 a)) & @Foo ~ (@bool/true (3 a))

View File

@ -2,15 +2,17 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/scrutinee_reconstruction.bend 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/or__C0 = (a (* b))
& @Option/Some ~ (a b) & @Option/Some ~ (a b)
@Option/or__C1 = (?((@Option/or__C0 (* (a a))) b) b)
@main = b @main = b
& @Option/or ~ (a (@Option/None b)) & @Option/or ~ (a (@Option/None b))
& @Option/Some ~ (5 a) & @Option/Some ~ (5 a)

View File

@ -2,9 +2,9 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/str.bend 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 @main = f
& @String/Cons ~ (109 (e f)) & @String/Cons ~ (109 (e f))

View File

@ -2,7 +2,7 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/compile_file_o_all/weekday.bend input_file: tests/golden_tests/compile_file_o_all/weekday.bend
--- ---
@Weekday/Saturday = (* (* (* (* (* (a (* a))))))) @Weekday/Saturday = ((5 a) a)
@main = b @main = b
& (a a) ~ (@Weekday/Saturday b) & (a a) ~ (@Weekday/Saturday b)

View File

@ -2,7 +2,7 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/desugar_file/bind_syntax.bend 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) (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) (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__C0) = λa (Result/bind (safe_rem a 0) λb b)
(Main__C1) = (safe_div 3 2) (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))) (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) (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} (baz) = {0 1 2 3 λa a foo}
@ -24,15 +24,17 @@ input_file: tests/golden_tests/desugar_file/combinators.bend
(Main) = list (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) (A__C0) = let {a b} = A; λc (a b c)
(B__C0) = let (a, b) = B; λ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) (clax__C0) = λ* λ* λ* λa (clax a)

View File

@ -2,14 +2,16 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/desugar_file/deref_loop.bend 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) (bar) = (foo 1)
(main) = (foo 0) (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/adt_tup_era.bend input_file: tests/golden_tests/encode_pattern_match/adt_tup_era.bend
--- ---
Scott
(Foo) = λa (a λb λc (b λd λ* λ* d c)) (Foo) = λa (a λb λc (b λd λ* λ* d c))
(Main) = (Foo (Tuple/Pair 1 5)) (Main) = (Foo (Tuple/Pair 1 5))
(Tuple/Pair) = λa λb λc (c a b) (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/and3.bend 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) (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)) (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/T) = λa λ* a
(Bool/F) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/bool.bend input_file: tests/golden_tests/encode_pattern_match/bool.bend
--- ---
Scott
(not) = λa (a bool/false bool/true) (not) = λa (a bool/false bool/true)
(and) = λa (a λb (b bool/true bool/false) λc (c bool/false bool/false)) (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/true) = λa λ* a
(bool/false) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/bool_tup.bend input_file: tests/golden_tests/encode_pattern_match/bool_tup.bend
--- ---
Scott
(foo) = λa let (b, c) = a; (b λd d λ* Bool/F c) (foo) = λa let (b, c) = a; (b λd d λ* Bool/F c)
(main) = (foo (Bool/F, Bool/T)) (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/T) = λa λ* a
(Bool/F) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/box.bend input_file: tests/golden_tests/encode_pattern_match/box.bend
--- ---
Scott
(unbox) = λa (a λb b) (unbox) = λa (a λb b)
(box/new) = λa λb (b a) (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/common.bend input_file: tests/golden_tests/encode_pattern_match/common.bend
--- ---
Scott
(Box/Filled) = λa λb λ* (b a) (Box/Filled) = λa λb λ* (b a)
(Box/Empty) = λ* λb b (Box/Empty) = λ* λb b
@ -35,3 +36,38 @@ input_file: tests/golden_tests/encode_pattern_match/common.bend
(Direction/East) = λ* λ* λc λ* c (Direction/East) = λ* λ* λc λ* c
(Direction/West) = λ* λ* λ* λd d (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/concat.bend input_file: tests/golden_tests/encode_pattern_match/concat.bend
--- ---
Scott
(String/concat) = λ* λb b (String/concat) = λ* λb b
(main) = (String/concat (String/Cons 97 (String/Cons 98 String/Nil)) (String/Cons 99 (String/Cons 100 String/Nil))) (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/concat_def.bend 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))) (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/def_tups.bend 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) (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))))) (main) = (go (1, (2, (3, (4, 5)))))

View File

@ -2,6 +2,7 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/definition_merge.bend input_file: tests/golden_tests/encode_pattern_match/definition_merge.bend
--- ---
Scott
(Foo) = λa (a λ* λc (c λ* 1 λ* 2) λ* λg (g λ* 3 λ* 3)) (Foo) = λa (a λ* λc (c λ* 1 λ* 2) λ* λg (g λ* 3 λ* 3))
(Either/Left) = λa λb λ* (b a) (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/True) = λa λ* a
(Bool/Bool/False) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/expr.bend input_file: tests/golden_tests/encode_pattern_match/expr.bend
--- ---
Scott
(Expr/Var) = λa λb λ* λ* λ* λ* λ* λ* λ* λ* (b a) (Expr/Var) = λa λb λ* λ* λ* λ* λ* λ* λ* λ* (b a)
(Expr/Num) = λa λ* λc λ* λ* λ* λ* λ* λ* λ* (c 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/Mul) = λ* λ* λc λ* c
(Op/Div) = λ* λ* λ* λd d (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/flatten_era_pat.bend 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 (Fn1) = λa λ* let (*, d) = a; let (e, *) = d; e
(Fn2) = λa let (*, c) = a; let (*, e) = c; let (f, *) = e; f (Fn2) = λa let (*, c) = a; let (*, e) = c; let (f, *) = e; f

View File

@ -2,6 +2,7 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/is_some_some.bend input_file: tests/golden_tests/encode_pattern_match/is_some_some.bend
--- ---
Scott
(some_some) = λa (a λb (b λ* 1 0) 0) (some_some) = λa (a λb (b λ* 1 0) 0)
(main) = (some_some (Option/Some 1)) (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/Some) = λa λb λ* (b a)
(Option/None) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/list_merge_sort.bend input_file: tests/golden_tests/encode_pattern_match/list_merge_sort.bend
--- ---
Scott
(If) = λa (a λb λ* b λ* λe e) (If) = λa (a λb λ* b λ* λe e)
(Pure) = λa (List_/Cons a List_/Nil) (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_/Cons) = λa λb λc λ* (c a b)
(List_/Nil) = λ* λb 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/list_str_encoding_undeclared_fn.bend input_file: tests/golden_tests/encode_pattern_match/list_str_encoding_undeclared_fn.bend
--- ---
Scott
(main) = * (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/list_str_encoding_undeclared_map.bend 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_in_arm.bend input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_in_arm.bend
--- ---
Scott
(main) = λ* λ$x $x (main) = λ* λ$x $x
(bool/T) = λa λ* a (bool/T) = λa λ* a
(bool/F) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_lambda.bend input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_lambda.bend
--- ---
Scott
(main) = (Maybe/Some 1 λ$x * λa a $x) (main) = (Maybe/Some 1 λ$x * λa a $x)
(Maybe/None) = λa λ* a (Maybe/None) = λa λ* a
(Maybe/Some) = λa λ* λc (c 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_var.bend input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_var.bend
--- ---
Scott
(Foo) = λ$x (Maybe/Some 1 $x λa a) (Foo) = λ$x (Maybe/Some 1 $x λa a)
(Bar) = (Maybe/Some 1 $x λa a λ$x *) (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/None) = λa λ* a
(Maybe/Some) = λa λ* λc (c 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_auto_linearization.bend 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); } (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)) (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; } (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_bind.bend 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); } (cheese) = switch (+ 2 3) { 0: 653323; _: λa let {a a_2} = a; (+ (+ a 1) a_2); }
(main) = cheese (main) = cheese

View File

@ -2,14 +2,28 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_num_adt_tup_parser.bend 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)) (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_/Ok) = λa λb λ* (b a)
(Result_/Err) = λa λ* λc (c 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_num_pred.bend 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; } (pred) = λa switch a { 0: 0; _: λb b; }
(pred2) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc c; }; } (pred2) = λa switch a { 0: 0; _: λb switch b { 0: 0; _: λc c; }; }

View File

@ -2,8 +2,16 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/match_syntax.bend input_file: tests/golden_tests/encode_pattern_match/match_syntax.bend
--- ---
Scott
(head) = λa (a λb λ* b List_/Nil) (head) = λa (a λb λ* b List_/Nil)
(List_/Cons) = λa λb λc λ* (c a b) (List_/Cons) = λa λb λc λ* (c a b)
(List_/Nil) = λ* λb 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/merge_recursive.bend 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_1) = λa (a foo_2)
(foo_2) = λa λb (a, b) (foo_2) = λa λb (a, b)

View File

@ -2,6 +2,14 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/no_patterns.bend 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 (Id) = λa a
(Id2) = λa a (Id2) = λa a

View File

@ -2,8 +2,16 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/non_matching_fst_arg.bend 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) (Foo) = λa λb (b λc let {c c_2} = c; (Foo c c_2) λd d a)
(bool/true) = λa λ* a (bool/true) = λa λ* a
(bool/false) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/ntup_sum.bend 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)))) (ntupSum) = λa let (b, c, d, e, f) = a; (+ b (+ c (+ d (+ e f))))
(main) = (ntupSum (1, 3, 3, 2, 1)) (main) = (ntupSum (1, 3, 3, 2, 1))

View File

@ -2,6 +2,7 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/pattern_match_encoding.bend input_file: tests/golden_tests/encode_pattern_match/pattern_match_encoding.bend
--- ---
Scott
(Foo) = λa (a λ* 100 λ* 200 λ* 200 λ* λ* 200 λ* λ* 200) (Foo) = λa (a λ* 100 λ* 200 λ* 200 λ* λ* 200 λ* λ* 200)
(main) = (Foo MyType/A 2) (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/D) = λa λb λ* λ* λ* λf λ* (f a b)
(MyType/E) = λa λb λ* λ* λ* λ* λg (g 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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/switch_in_switch_arg.bend 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); } (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/var_only.bend input_file: tests/golden_tests/encode_pattern_match/var_only.bend
--- ---
Scott
(Foo) = λa λ* λc (c a) (Foo) = λa λ* λc (c a)
(main) = λ* Foo (main) = λ* Foo
@ -9,3 +10,12 @@ input_file: tests/golden_tests/encode_pattern_match/var_only.bend
(Bool/False) = λa λ* a (Bool/False) = λa λ* a
(Bool/True) = λ* λb b (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/weekday.bend input_file: tests/golden_tests/encode_pattern_match/weekday.bend
--- ---
Scott
(main) = (λa a Weekday/Saturday) (main) = (λa a Weekday/Saturday)
(Weekday/Monday) = λa λ* λ* λ* λ* λ* λ* a (Weekday/Monday) = λa λ* λ* λ* λ* λ* λ* a
@ -17,3 +18,20 @@ input_file: tests/golden_tests/encode_pattern_match/weekday.bend
(Weekday/Saturday) = λ* λ* λ* λ* λ* λf λ* f (Weekday/Saturday) = λ* λ* λ* λ* λ* λf λ* f
(Weekday/Sunday) = λ* λ* λ* λ* λ* λ* λg g (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/mutual_recursion/len.bend 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] & $(b c) ~ [+1]
& @Len ~ (a b) & @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 @main = g
& @Len ~ (f 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) (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 } (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))))))) (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 source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/addition.bend input_file: tests/golden_tests/run_file/addition.bend
--- ---
NumScott:
10
Scott:
10 10

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/adt_match.bend input_file: tests/golden_tests/run_file/adt_match.bend
--- ---
NumScott:
λa (a 0 2)
Scott:
λa λ* (a 2) λa λ* (a 2)

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/adt_option_and.bend 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) λ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 source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/and.bend input_file: tests/golden_tests/run_file/and.bend
--- ---
NumScott:
bool/false
Scott:
bool/false bool/false

View File

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

View File

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

View File

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

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/box.bend input_file: tests/golden_tests/run_file/box.bend
--- ---
NumScott:
λa (a 0 λb (b 0 10))
Scott:
λa (a λb (b 10)) λa (a λb (b 10))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/do_block_mixed.bend input_file: tests/golden_tests/run_file/do_block_mixed.bend
--- ---
NumScott:
λa (a 0 1)
Scott:
λa λ* (a 1) λa λ* (a 1)

View File

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

View File

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

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/escape_sequences.bend 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}\\" "\n\r\t\0\"'\u{afe}\\\n\r\t\0\"'\u{afe}\\"

View File

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

View File

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

View File

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

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/fold_with_state.bend input_file: tests/golden_tests/run_file/fold_with_state.bend
--- ---
NumScott:
[1, 2, 3]
Scott:
[1, 2, 3] [1, 2, 3]

View File

@ -2,4 +2,8 @@
source: tests/golden_tests.rs source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/id_underscore.bend input_file: tests/golden_tests/run_file/id_underscore.bend
--- ---
NumScott:
{2 3}
Scott:
{2 3} {2 3}

Some files were not shown because too many files have changed in this diff Show More