Skip to content

Commit

Permalink
Updates builtin type Map so that it stores Maybes in its nodes.
Browse files Browse the repository at this point in the history
  • Loading branch information
In-Veritas committed Dec 9, 2024
1 parent e195a55 commit 0ad7503
Show file tree
Hide file tree
Showing 22 changed files with 192 additions and 125 deletions.
8 changes: 4 additions & 4 deletions src/fun/builtins.bend
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,17 @@ def Map/set (map: Map(T), key: u24, value: T) -> Map(T):
return Map/Node(Maybe/None, Map/Leaf, Map/set(Map/Leaf, (key / 2),value))

# Checks if a Map contains a given key
def Map/contains (map: Map(T), key: u24) -> Bool:
def Map/contains (map: Map(T), key: u24) -> u24:
match map:
case Map/Leaf:
return Bool/False
return 0
case Map/Node:
if (0 == key):
match map.value:
case Maybe/Some:
return Bool/True
return 1
case Maybe/None:
return Bool/False
return 0
elif ((key % 2) == 0):
return Map/contains(map.left, (key / 2))
else:
Expand Down
15 changes: 15 additions & 0 deletions tests/golden_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,21 @@ fn io() {
})
}

/// Runs a file that uses the prelude.
#[test]
fn prelude() {
run_golden_test_dir(function_name!(), &|code, path| {
let _guard = RUN_MUTEX.lock().unwrap();
let book = parse_book_single_file(code, path)?;
let compile_opts = CompileOpts::default();
let diagnostics_cfg = DiagnosticsConfig::default();
let (term, _, diags) =
run_book(book, RunOpts::default(), compile_opts, diagnostics_cfg, None, "run-c")?.unwrap();
let res = format!("{diags}{term}");
Ok(format!("Strict mode:\n{res}"))
})
}

/// Runs all examples in the examples folder.
#[test]
fn examples() -> Result<(), Diagnostics> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
type Maybe = (Some val) | None
type Maybe_ = (Some val) | None

main = @maybe
match maybe {
Maybe/None: 0
Maybe/Some: match maybe.val {
Maybe/None: 0
Maybe_/None: 0
Maybe_/Some: match maybe.val {
Maybe_/None: 0
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
type Maybe = None | (Some val)
type Maybe_ = None | (Some val)

main = (match x = (Maybe/Some 1) {
Maybe/None: @$x *
Maybe/Some: x.val
main = (match x = (Maybe_/Some 1) {
Maybe_/None: @$x *
Maybe_/Some: x.val
} $x)
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
type Maybe = None | (Some val)
type Maybe_ = None | (Some val)

Foo = @$x match x = (Maybe/Some 1) {
Maybe/None: $x
Maybe/Some: x.val
Foo = @$x match x = (Maybe_/Some 1) {
Maybe_/None: $x
Maybe_/Some: x.val
}

Bar = (match x = (Maybe/Some 1) {
Maybe/None: $x
Maybe/Some: x.val
Bar = (match x = (Maybe_/Some 1) {
Maybe_/None: $x
Maybe_/Some: x.val
} @$x *)

main = *
4 changes: 0 additions & 4 deletions tests/golden_tests/parse_file/imp_program.bend
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
type Point:
Point { x, y }

type Bool:
True
False


def symbols():
x = { `x`: 5, 2: 3 };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#This test aims to see if every builtin Map function behaves correctly and returns the expected result

type Bool:
True
False
False

# Returns values from a map
def test1() -> (u24, u24):
Expand Down Expand Up @@ -30,30 +32,30 @@ def test3(m: Map(T), x: u24, v: T) -> Map(T):
# Checks if a map contains a given key, and if it does, returns the assigned to the key, otherwise it returns the given value
def test4(m: Map(T), x: u24, v: T) -> T:
match Map/contains(m, x):
case Bool/True:
case 1:
(value, map) = Map/get(m, x)
return value
case Bool/False:
case 0:
return v

#Checks if a generic map contains a given key, and if it does, applies a function to the value, otherwise it returns the map
def test5(m: Map(T), key: u24) -> Map(T):
def self (x: T) -> T:
return x
match Map/contains(m, key):
case Bool/True:
case 1:
return Map/map(m, key, self())
case Bool/False:
case 0:
return m

#Checks if a u24 map contains a given key, and if it does, applies a function to the value, otherwise it returns the map
def test6(m: Map(u24), key: u24) -> Map(u24):
def addtwo (x: u24) -> u24:
return x + 2
return (x + 2)
match Map/contains(m, key):
case Bool/True:
case 1:
return Map/map(m, key, addtwo())
case Bool/False:
case 0:
return m


Expand Down
10 changes: 5 additions & 5 deletions tests/golden_tests/run_file/unbound_wrap.bend
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
type Maybe = (Some x) | None
type Maybe_ = (Some x) | None

Maybe/bind val nxt = match val {
Maybe/Some: (nxt val.x)
Maybe/None: Maybe/None
Maybe_/bind val nxt = match val {
Maybe_/Some: (nxt val.x)
Maybe_/None: Maybe/None
}

main = with Maybe {
main = with Maybe_ {
(wrap 1)
}
6 changes: 3 additions & 3 deletions tests/golden_tests/simplify_matches/double_unwrap_maybe.bend
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# We want to make sure that the default value is not mistakenly erased in the first level of flattening.
type Maybe = (Some x) | None
type Maybe_ = (Some x) | None

(DoubleUnwrap (Maybe/Some (Maybe/Some x)) *) = x
(DoubleUnwrap (Maybe_/Some (Maybe_/Some x)) *) = x
(DoubleUnwrap * x) = x

Main = (DoubleUnwrap (Maybe/Some Maybe/None) 5)
Main = (DoubleUnwrap (Maybe_/Some Maybe_/None) 5)
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ input_file: tests/golden_tests/compile_file_o_all/match_adt_non_exhaustive.bend
Errors:
In tests/golden_tests/compile_file_o_all/match_adt_non_exhaustive.bend :
In definition 'main':
Non-exhaustive 'match' expression of type 'Maybe'. Case 'Maybe/Some' not covered.
Non-exhaustive 'match' expression of type 'Maybe_'. Case 'Maybe_/Some' not covered.
54 changes: 36 additions & 18 deletions tests/snapshots/desugar_file__mapper_syntax.bend.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
source: tests/golden_tests.rs
input_file: tests/golden_tests/desugar_file/mapper_syntax.bend
---
Maybe/unwrap: ((Maybe a) -> a)
(Maybe/unwrap) = λa (a Maybe/unwrap__C0)

Map/empty: (Map a)
(Map/empty) = Map/Leaf

Expand All @@ -20,10 +23,22 @@ unreachable: Any
unchecked main: Any
(main) = let (c, d) = (Map/get (Map/map (Map/map (Map/set (Map/set Map/empty 0 3) 1 4) 1 λa (+ a 1)) 1 λb (* b 2)) 1); let (e, *) = (Map/get d 0); ((λf (+ f 1) 1), c, e)

Maybe/Some/tag: u24
(Maybe/Some/tag) = 0

Maybe/Some: (a -> (Maybe a))
(Maybe/Some) = λa λb (b Maybe/Some/tag a)

Maybe/None/tag: u24
(Maybe/None/tag) = 1

Maybe/None: (Maybe a)
(Maybe/None) = λa (a Maybe/None/tag)

Map/Node/tag: u24
(Map/Node/tag) = 0

Map/Node: (a -> (Map a) -> (Map a) -> (Map a))
Map/Node: ((Maybe a) -> (Map a) -> (Map a) -> (Map a))
(Map/Node) = λa λb λc λd (d Map/Node/tag a b c)

Map/Leaf/tag: u24
Expand All @@ -33,16 +48,16 @@ Map/Leaf: (Map a)
(Map/Leaf) = λa (a Map/Leaf/tag)

Map/get__C0: _
(Map/get__C0) = λa λb λc λd let (e, f) = (Map/get c (/ a 2)); (e, (Map/Node b f d))
(Map/get__C0) = λa λb λc λd let (e, f) = (Map/get d (/ a 2)); (e, (Map/Node b f c))

Map/get__C1: _
(Map/get__C1) = λ* λa λb λc λd let (e, f) = (Map/get d (/ a 2)); (e, (Map/Node b c f))
(Map/get__C1) = λ* λa λb λc λd let (e, f) = (Map/get c (/ a 2)); (e, (Map/Node b f d))

Map/get__C2: _
(Map/get__C2) = λa let {b c} = a; λd λe λf (switch (% b 2) { 0: Map/get__C0; _: Map/get__C1; } c d e f)
(Map/get__C2) = λa let {b c} = a; λd λe λf (switch (== (% b 2) 0) { 0: Map/get__C0; _: Map/get__C1; } c d e f)

Map/get__C3: _
(Map/get__C3) = λ* λ* λa let {b c} = a; λd λe (b, (Map/Node c d e))
(Map/get__C3) = λ* λ* λa let {b c} = a; λd λe ((Maybe/unwrap b), (Map/Node c d e))

Map/get__C4: _
(Map/get__C4) = λa λb λc λd let {e f} = d; (switch (== 0 e) { 0: Map/get__C2; _: Map/get__C3; } f a b c)
Expand All @@ -51,52 +66,55 @@ Map/get__C5: _
(Map/get__C5) = λa switch a { 0: Map/get__C4; _: λ* λ* (unreachable, Map/Leaf); }

Map/map__C0: _
(Map/map__C0) = λa λb λc λd λe (Map/Node c (Map/map d (/ a 2) b) e)
(Map/map__C0) = λa λb λc λd λe (Map/Node c d (Map/map e (/ a 2) b))

Map/map__C1: _
(Map/map__C1) = λ* λa λb λc λd λe (Map/Node c d (Map/map e (/ a 2) b))
(Map/map__C1) = λ* λa λb λc λd λe (Map/Node c (Map/map d (/ a 2) b) e)

Map/map__C2: _
(Map/map__C2) = λa let {b c} = a; λd λe λf λg (switch (% b 2) { 0: Map/map__C0; _: Map/map__C1; } c d e f g)
(Map/map__C2) = λa let {b c} = a; λd λe λf λg (switch (== (% b 2) 0) { 0: Map/map__C0; _: Map/map__C1; } c d e f g)

Map/map__C3: _
(Map/map__C3) = λ* λ* λa λb λc λd (Map/Node (a b) c d)
(Map/map__C3) = λ* λ* λa λb λc λd (Map/Node (Maybe/Some (a (Maybe/unwrap b))) c d)

Map/map__C4: _
(Map/map__C4) = λa λb λc λd let {e f} = d; λg (switch (== 0 e) { 0: Map/map__C2; _: Map/map__C3; } f g a b c)

Map/map__C5: _
(Map/map__C5) = λa switch a { 0: Map/map__C4; _: λ* λ* λ* Map/Leaf; }
(Map/map__C5) = λa switch a { 0: Map/map__C4; _: λ* λ* λ* unreachable; }

Map/set__C0: _
(Map/set__C0) = λa λb λc λd λe (Map/Node c (Map/set d (/ a 2) b) e)
(Map/set__C0) = λa λb λc λd λe (Map/Node c d (Map/set e (/ a 2) b))

Map/set__C1: _
(Map/set__C1) = λ* λa λb λc λd λe (Map/Node c d (Map/set e (/ a 2) b))
(Map/set__C1) = λ* λa λb λc λd λe (Map/Node c (Map/set d (/ a 2) b) e)

Map/set__C10: _
(Map/set__C10) = λa switch a { 0: Map/set__C8; _: Map/set__C9; }

Map/set__C2: _
(Map/set__C2) = λa let {b c} = a; λd λe λf λg (switch (% b 2) { 0: Map/set__C0; _: Map/set__C1; } c d e f g)
(Map/set__C2) = λa let {b c} = a; λd λe λf λg (switch (== (% b 2) 0) { 0: Map/set__C0; _: Map/set__C1; } c d e f g)

Map/set__C3: _
(Map/set__C3) = λ* λ* λa λ* λb λc (Map/Node a b c)
(Map/set__C3) = λ* λ* λa λ* λb λc (Map/Node (Maybe/Some a) b c)

Map/set__C4: _
(Map/set__C4) = λa λb (Map/Node unreachable (Map/set Map/Leaf (/ a 2) b) Map/Leaf)
(Map/set__C4) = λa λb (Map/Node Maybe/None Map/Leaf (Map/set Map/Leaf (/ a 2) b))

Map/set__C5: _
(Map/set__C5) = λ* λa λb (Map/Node unreachable Map/Leaf (Map/set Map/Leaf (/ a 2) b))
(Map/set__C5) = λ* λa λb (Map/Node Maybe/None (Map/set Map/Leaf (/ a 2) b) Map/Leaf)

Map/set__C6: _
(Map/set__C6) = λa let {b c} = a; λd (switch (% b 2) { 0: Map/set__C4; _: Map/set__C5; } c d)
(Map/set__C6) = λa let {b c} = a; λd (switch (== (% b 2) 0) { 0: Map/set__C4; _: Map/set__C5; } c d)

Map/set__C7: _
(Map/set__C7) = λ* λ* λa (Map/Node a Map/Leaf Map/Leaf)
(Map/set__C7) = λ* λ* λa (Map/Node (Maybe/Some a) Map/Leaf Map/Leaf)

Map/set__C8: _
(Map/set__C8) = λa λb λc λd let {e f} = d; λg (switch (== 0 e) { 0: Map/set__C2; _: Map/set__C3; } f g a b c)

Map/set__C9: _
(Map/set__C9) = λ* λa let {b c} = a; λd (switch (== 0 b) { 0: Map/set__C6; _: Map/set__C7; } c d)

Maybe/unwrap__C0: _
(Maybe/unwrap__C0) = λa switch a { 0: λb b; _: λ* unreachable; }
14 changes: 10 additions & 4 deletions tests/snapshots/encode_pattern_match__full_map.bend.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ source: tests/golden_tests.rs
input_file: tests/golden_tests/encode_pattern_match/full_map.bend
---
Scott
Maybe/unwrap: ((Maybe T) -> T)
(Maybe/unwrap) = λa (a λb b unreachable)

Map/get: ((Map T) -> u24 -> (T, (Map T)))
(Map/get) = λa (a λb let {b b_2 b_3 b_4} = b; λc let {c c_2 c_3} = c; λd let {d d_2 d_3} = d; λe let {e e_2 e_3 e_4} = e; switch (== 0 e) { 0: switch (% e_2 2) { 0: let (f, g) = (Map/get c (/ e_3 2)); (f, (Map/Node b g d)); _: λ* let (i, j) = (Map/get d_2 (/ e_4 2)); (i, (Map/Node b_2 c_2 j)); }; _: λ* (b_3, (Map/Node b_4 c_3 d_3)); } λ* (unreachable, Map/Leaf))
(Map/get) = λa (a λb let {b b_2 b_3 b_4} = b; λc let {c c_2 c_3} = c; λd let {d d_2 d_3} = d; λe let {e e_2 e_3 e_4} = e; switch (== 0 e) { 0: switch (== (% e_2 2) 0) { 0: let (f, g) = (Map/get d (/ e_3 2)); (f, (Map/Node b g c)); _: λ* let (i, j) = (Map/get c_2 (/ e_4 2)); (i, (Map/Node b_2 j d_2)); }; _: λ* ((Maybe/unwrap b_3), (Map/Node b_4 c_3 d_3)); } λ* (unreachable, Map/Leaf))

unreachable: Any
(unreachable) = *
Expand All @@ -21,7 +24,7 @@ unchecked test: (Any -> Any)
unchecked main: Any
(main) = (test fullMap)

Map/Node: (T -> (Map T) -> (Map T) -> (Map T))
Map/Node: ((Maybe T) -> (Map T) -> (Map T) -> (Map T))
(Map/Node) = λa λb λc λd λ* (d a b c)

Map/Leaf: (Map T)
Expand All @@ -34,8 +37,11 @@ unchecked test__bend0: _
(test__bend0) = λa let {a a_2 a_3} = a; switch (< a 1000) { 0: λ* 0; _: λ* λd let (e, f) = (Map/get d (% (prng a_2) 4096)); (+ e (test__bend0 (+ a_3 1) f)); }

NumScott
Maybe/unwrap: ((Maybe T) -> T)
(Maybe/unwrap) = λa (a λb switch b { 0: λc c; _: λ* unreachable; })

Map/get: ((Map T) -> u24 -> (T, (Map T)))
(Map/get) = λa (a λb switch b { 0: λc let {c c_2 c_3 c_4} = c; λd let {d d_2 d_3} = d; λe let {e e_2 e_3} = e; λf let {f f_2 f_3 f_4} = f; switch (== 0 f) { 0: switch (% f_2 2) { 0: let (g, h) = (Map/get d (/ f_3 2)); (g, (Map/Node c h e)); _: λ* let (j, k) = (Map/get e_2 (/ f_4 2)); (j, (Map/Node c_2 d_2 k)); }; _: λ* (c_3, (Map/Node c_4 d_3 e_3)); }; _: λ* λ* (unreachable, Map/Leaf); })
(Map/get) = λa (a λb switch b { 0: λc let {c c_2 c_3 c_4} = c; λd let {d d_2 d_3} = d; λe let {e e_2 e_3} = e; λf let {f f_2 f_3 f_4} = f; switch (== 0 f) { 0: switch (== (% f_2 2) 0) { 0: let (g, h) = (Map/get e (/ f_3 2)); (g, (Map/Node c h d)); _: λ* let (j, k) = (Map/get d_2 (/ f_4 2)); (j, (Map/Node c_2 k e_2)); }; _: λ* ((Maybe/unwrap c_3), (Map/Node c_4 d_3 e_3)); }; _: λ* λ* (unreachable, Map/Leaf); })

unreachable: Any
(unreachable) = *
Expand All @@ -55,7 +61,7 @@ unchecked main: Any
Map/Node/tag: _
(Map/Node/tag) = 0

Map/Node: (T -> (Map T) -> (Map T) -> (Map T))
Map/Node: ((Maybe T) -> (Map T) -> (Map T) -> (Map T))
(Map/Node) = λa λb λc λd (d Map/Node/tag a b c)

Map/Leaf/tag: _
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ input_file: tests/golden_tests/encode_pattern_match/match_adt_unscoped_lambda.be
---
Scott
unchecked main: Any
(main) = (Maybe/Some 1 λ$x * λa a $x)
(main) = (Maybe_/Some 1 λ$x * λa a $x)

Maybe/None: Maybe
(Maybe/None) = λa λ* a
Maybe_/None: Maybe_
(Maybe_/None) = λa λ* a

Maybe/Some: (Any -> Maybe)
(Maybe/Some) = λa λ* λc (c a)
Maybe_/Some: (Any -> Maybe_)
(Maybe_/Some) = λa λ* λc (c a)

NumScott
unchecked main: Any
(main) = (Maybe/Some 1 λa switch a { 0: λ$x *; _: λ* λb b; } $x)
(main) = (Maybe_/Some 1 λa switch a { 0: λ$x *; _: λ* λb b; } $x)

Maybe/None/tag: _
(Maybe/None/tag) = 0
Maybe_/None/tag: _
(Maybe_/None/tag) = 0

Maybe/None: Maybe
(Maybe/None) = λa (a Maybe/None/tag)
Maybe_/None: Maybe_
(Maybe_/None) = λa (a Maybe_/None/tag)

Maybe/Some/tag: _
(Maybe/Some/tag) = 1
Maybe_/Some/tag: _
(Maybe_/Some/tag) = 1

Maybe/Some: (Any -> Maybe)
(Maybe/Some) = λa λb (b Maybe/Some/tag a)
Maybe_/Some: (Any -> Maybe_)
(Maybe_/Some) = λa λb (b Maybe_/Some/tag a)
Loading

0 comments on commit 0ad7503

Please sign in to comment.