Skip to content

Commit

Permalink
Merge pull request #5929 from roc-lang/list-appendif
Browse files Browse the repository at this point in the history
Add List.appendIfOk and List.prependIfOk
  • Loading branch information
rtfeldman authored Nov 6, 2023
2 parents f0e3d65 + abff41c commit 0252a11
Show file tree
Hide file tree
Showing 42 changed files with 1,928 additions and 1,889 deletions.
34 changes: 33 additions & 1 deletion crates/compiler/builtins/roc/List.roc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ interface List
replace,
update,
append,
appendIfOk,
prepend,
prependIfOk,
map,
len,
withCapacity,
Expand All @@ -15,7 +18,6 @@ interface List
single,
repeat,
reverse,
prepend,
join,
keepIf,
contains,
Expand Down Expand Up @@ -320,6 +322,21 @@ append = \list, element ->
|> List.reserve 1
|> List.appendUnsafe element

## If the given [Result] is `Ok`, add it to the end of a list.
## Otherwise, return the list unmodified.
##
## ```
## List.appendIfOk [1, 2, 3] (Ok 4)
##
## [0, 1, 2]
## |> List.appendIfOk (Err 3)
## ```
appendIfOk : List a, Result a * -> List a
appendIfOk = \list, result ->
when result is
Ok elem -> append list elem
Err _ -> list

## Writes the element after the current last element unconditionally.
## In other words, it is assumed that
##
Expand All @@ -336,6 +353,21 @@ appendUnsafe : List a, a -> List a
## ```
prepend : List a, a -> List a

## If the given [Result] is `Ok`, add it to the beginning of a list.
## Otherwise, return the list unmodified.
##
## ```
## List.prepend [1, 2, 3] (Ok 0)
##
## [2, 3, 4]
## |> List.prepend (Err 1)
## ```
prependIfOk : List a, Result a * -> List a
prependIfOk = \list, result ->
when result is
Ok elem -> prepend list elem
Err _ -> list

## Returns the length of the list - the number of elements it contains.
##
## One [List] can store up to 2,147,483,648 elements (just over 2 billion), which
Expand Down
7 changes: 6 additions & 1 deletion crates/compiler/gen_dev/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1941,7 +1941,12 @@ trait Backend<'a> {
self.build_eq(sym, &args[0], &Symbol::DEV_TMP, &arg_layouts[0]);
self.free_symbol(&Symbol::DEV_TMP)
}
Symbol::LIST_GET | Symbol::LIST_SET | Symbol::LIST_REPLACE | Symbol::LIST_APPEND => {
Symbol::LIST_GET
| Symbol::LIST_SET
| Symbol::LIST_REPLACE
| Symbol::LIST_APPEND
| Symbol::LIST_APPEND_IF_OK
| Symbol::LIST_PREPEND_IF_OK => {
// TODO: This is probably simple enough to be worth inlining.
let fn_name = self.lambda_name_to_string(
func_name,
Expand Down
2 changes: 2 additions & 0 deletions crates/compiler/module/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,8 @@ define_builtins! {
81 LIST_RELEASE_EXCESS_CAPACITY: "releaseExcessCapacity"
82 LIST_UPDATE: "update"
83 LIST_WALK_WITH_INDEX: "walkWithIndex"
84 LIST_APPEND_IF_OK: "appendIfOk"
85 LIST_PREPEND_IF_OK: "prependIfOk"
}
7 RESULT: "Result" => {
0 RESULT_RESULT: "Result" exposed_type=true // the Result.Result type alias
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,88 +2,88 @@ procedure Bool.11 (#Attr.2, #Attr.3):
let Bool.24 : Int1 = lowlevel Eq #Attr.2 #Attr.3;
ret Bool.24;

procedure List.26 (List.173, List.174, List.175):
let List.560 : [C U64, C U64] = CallByName List.97 List.173 List.174 List.175;
let List.563 : U8 = 1i64;
let List.564 : U8 = GetTagId List.560;
let List.565 : Int1 = lowlevel Eq List.563 List.564;
if List.565 then
let List.176 : U64 = UnionAtIndex (Id 1) (Index 0) List.560;
ret List.176;
procedure List.26 (List.181, List.182, List.183):
let List.568 : [C U64, C U64] = CallByName List.99 List.181 List.182 List.183;
let List.571 : U8 = 1i64;
let List.572 : U8 = GetTagId List.568;
let List.573 : Int1 = lowlevel Eq List.571 List.572;
if List.573 then
let List.184 : U64 = UnionAtIndex (Id 1) (Index 0) List.568;
ret List.184;
else
let List.177 : U64 = UnionAtIndex (Id 0) (Index 0) List.560;
ret List.177;
let List.185 : U64 = UnionAtIndex (Id 0) (Index 0) List.568;
ret List.185;

procedure List.38 (List.316, List.317):
let List.559 : U64 = CallByName List.6 List.316;
let List.318 : U64 = CallByName Num.77 List.559 List.317;
let List.545 : List U8 = CallByName List.43 List.316 List.318;
ret List.545;
procedure List.38 (List.324, List.325):
let List.567 : U64 = CallByName List.6 List.324;
let List.326 : U64 = CallByName Num.77 List.567 List.325;
let List.553 : List U8 = CallByName List.43 List.324 List.326;
ret List.553;

procedure List.43 (List.314, List.315):
let List.557 : U64 = CallByName List.6 List.314;
let List.556 : U64 = CallByName Num.77 List.557 List.315;
let List.547 : {U64, U64} = Struct {List.315, List.556};
let List.546 : List U8 = CallByName List.49 List.314 List.547;
ret List.546;
procedure List.43 (List.322, List.323):
let List.565 : U64 = CallByName List.6 List.322;
let List.564 : U64 = CallByName Num.77 List.565 List.323;
let List.555 : {U64, U64} = Struct {List.323, List.564};
let List.554 : List U8 = CallByName List.49 List.322 List.555;
ret List.554;

procedure List.49 (List.392, List.393):
let List.554 : U64 = StructAtIndex 0 List.393;
let List.555 : U64 = 0i64;
let List.552 : Int1 = CallByName Bool.11 List.554 List.555;
if List.552 then
dec List.392;
let List.553 : List U8 = Array [];
ret List.553;
procedure List.49 (List.400, List.401):
let List.562 : U64 = StructAtIndex 0 List.401;
let List.563 : U64 = 0i64;
let List.560 : Int1 = CallByName Bool.11 List.562 List.563;
if List.560 then
dec List.400;
let List.561 : List U8 = Array [];
ret List.561;
else
let List.549 : U64 = StructAtIndex 1 List.393;
let List.550 : U64 = StructAtIndex 0 List.393;
let List.548 : List U8 = CallByName List.72 List.392 List.549 List.550;
ret List.548;
let List.557 : U64 = StructAtIndex 1 List.401;
let List.558 : U64 = StructAtIndex 0 List.401;
let List.556 : List U8 = CallByName List.72 List.400 List.557 List.558;
ret List.556;

procedure List.6 (#Attr.2):
let List.558 : U64 = lowlevel ListLen #Attr.2;
ret List.558;
let List.566 : U64 = lowlevel ListLen #Attr.2;
ret List.566;

procedure List.66 (#Attr.2, #Attr.3):
let List.581 : U8 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.581;
let List.589 : U8 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.589;

procedure List.72 (#Attr.2, #Attr.3, #Attr.4):
let List.551 : List U8 = lowlevel ListSublist #Attr.2 #Attr.3 #Attr.4;
ret List.551;
let List.559 : List U8 = lowlevel ListSublist #Attr.2 #Attr.3 #Attr.4;
ret List.559;

procedure List.80 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.3, #Derived_gen.4):
joinpoint List.569 List.463 List.464 List.465 List.466 List.467:
let List.571 : Int1 = CallByName Num.22 List.466 List.467;
if List.571 then
let List.580 : U8 = CallByName List.66 List.463 List.466;
let List.572 : [C U64, C U64] = CallByName Test.4 List.464 List.580;
let List.577 : U8 = 1i64;
let List.578 : U8 = GetTagId List.572;
let List.579 : Int1 = lowlevel Eq List.577 List.578;
if List.579 then
let List.468 : U64 = UnionAtIndex (Id 1) (Index 0) List.572;
let List.575 : U64 = 1i64;
let List.574 : U64 = CallByName Num.51 List.466 List.575;
jump List.569 List.463 List.468 List.465 List.574 List.467;
joinpoint List.577 List.471 List.472 List.473 List.474 List.475:
let List.579 : Int1 = CallByName Num.22 List.474 List.475;
if List.579 then
let List.588 : U8 = CallByName List.66 List.471 List.474;
let List.580 : [C U64, C U64] = CallByName Test.4 List.472 List.588;
let List.585 : U8 = 1i64;
let List.586 : U8 = GetTagId List.580;
let List.587 : Int1 = lowlevel Eq List.585 List.586;
if List.587 then
let List.476 : U64 = UnionAtIndex (Id 1) (Index 0) List.580;
let List.583 : U64 = 1i64;
let List.582 : U64 = CallByName Num.51 List.474 List.583;
jump List.577 List.471 List.476 List.473 List.582 List.475;
else
dec List.463;
let List.469 : U64 = UnionAtIndex (Id 0) (Index 0) List.572;
let List.576 : [C U64, C U64] = TagId(0) List.469;
ret List.576;
dec List.471;
let List.477 : U64 = UnionAtIndex (Id 0) (Index 0) List.580;
let List.584 : [C U64, C U64] = TagId(0) List.477;
ret List.584;
else
dec List.463;
let List.570 : [C U64, C U64] = TagId(1) List.464;
ret List.570;
dec List.471;
let List.578 : [C U64, C U64] = TagId(1) List.472;
ret List.578;
in
jump List.569 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
jump List.577 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;

procedure List.97 (List.460, List.461, List.462):
let List.567 : U64 = 0i64;
let List.568 : U64 = CallByName List.6 List.460;
let List.566 : [C U64, C U64] = CallByName List.80 List.460 List.461 List.462 List.567 List.568;
ret List.566;
procedure List.99 (List.468, List.469, List.470):
let List.575 : U64 = 0i64;
let List.576 : U64 = CallByName List.6 List.468;
let List.574 : [C U64, C U64] = CallByName List.80 List.468 List.469 List.470 List.575 List.576;
ret List.574;

procedure Num.22 (#Attr.2, #Attr.3):
let Num.294 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
procedure List.5 (#Attr.2, #Attr.3):
let List.545 : List {} = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.2 #Attr.3;
let List.553 : List {} = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.2 #Attr.3;
decref #Attr.2;
ret List.545;
ret List.553;

procedure Test.2 (Test.3):
let Test.7 : {} = Struct {};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
procedure List.5 (#Attr.2, #Attr.3):
let List.545 : List [] = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.2 #Attr.3;
let List.553 : List [] = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.2 #Attr.3;
decref #Attr.2;
ret List.545;
ret List.553;

procedure Test.2 (Test.3):
let Test.7 : {} = Struct {};
Expand Down
44 changes: 22 additions & 22 deletions crates/compiler/test_mono/generated/capture_void_layout_task.txt
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
procedure List.18 (List.146, List.147, List.148):
let List.546 : U64 = 0i64;
let List.547 : U64 = CallByName List.6 List.146;
let List.545 : [<r>C {}, C *self {{}, []}] = CallByName List.86 List.146 List.147 List.148 List.546 List.547;
ret List.545;
procedure List.18 (List.154, List.155, List.156):
let List.554 : U64 = 0i64;
let List.555 : U64 = CallByName List.6 List.154;
let List.553 : [<r>C {}, C *self {{}, []}] = CallByName List.88 List.154 List.155 List.156 List.554 List.555;
ret List.553;

procedure List.6 (#Attr.2):
let List.556 : U64 = lowlevel ListLen #Attr.2;
ret List.556;
let List.564 : U64 = lowlevel ListLen #Attr.2;
ret List.564;

procedure List.66 (#Attr.2, #Attr.3):
let List.555 : [] = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.555;

procedure List.86 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_gen.17):
joinpoint List.548 List.149 List.150 List.151 List.152 List.153:
let List.550 : Int1 = CallByName Num.22 List.152 List.153;
if List.550 then
let List.554 : [] = CallByName List.66 List.149 List.152;
let List.154 : [<r>C {}, C *self {{}, []}] = CallByName Test.29 List.150 List.554 List.151;
let List.553 : U64 = 1i64;
let List.552 : U64 = CallByName Num.51 List.152 List.553;
jump List.548 List.149 List.154 List.151 List.552 List.153;
let List.563 : [] = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.563;

procedure List.88 (#Derived_gen.3, #Derived_gen.4, #Derived_gen.5, #Derived_gen.6, #Derived_gen.7):
joinpoint List.556 List.157 List.158 List.159 List.160 List.161:
let List.558 : Int1 = CallByName Num.22 List.160 List.161;
if List.558 then
let List.562 : [] = CallByName List.66 List.157 List.160;
let List.162 : [<r>C {}, C *self {{}, []}] = CallByName Test.29 List.158 List.562 List.159;
let List.561 : U64 = 1i64;
let List.560 : U64 = CallByName Num.51 List.160 List.561;
jump List.556 List.157 List.162 List.159 List.560 List.161;
else
dec List.149;
ret List.150;
dec List.157;
ret List.158;
in
jump List.548 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
jump List.556 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7;

procedure Num.22 (#Attr.2, #Attr.3):
let Num.292 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,49 @@ procedure Bool.1 ():
let Bool.24 : Int1 = false;
ret Bool.24;

procedure List.2 (List.101, List.102):
let List.559 : U64 = CallByName List.6 List.101;
let List.555 : Int1 = CallByName Num.22 List.102 List.559;
if List.555 then
let List.557 : Str = CallByName List.66 List.101 List.102;
inc List.557;
dec List.101;
let List.556 : [C {}, C Str] = TagId(1) List.557;
ret List.556;
procedure List.2 (List.103, List.104):
let List.567 : U64 = CallByName List.6 List.103;
let List.563 : Int1 = CallByName Num.22 List.104 List.567;
if List.563 then
let List.565 : Str = CallByName List.66 List.103 List.104;
inc List.565;
dec List.103;
let List.564 : [C {}, C Str] = TagId(1) List.565;
ret List.564;
else
dec List.101;
let List.554 : {} = Struct {};
let List.553 : [C {}, C Str] = TagId(0) List.554;
ret List.553;
dec List.103;
let List.562 : {} = Struct {};
let List.561 : [C {}, C Str] = TagId(0) List.562;
ret List.561;

procedure List.5 (#Attr.2, #Attr.3):
let List.561 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.10 #Attr.3;
let List.569 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.10 #Attr.3;
decref #Attr.2;
ret List.561;
ret List.569;

procedure List.6 (#Attr.2):
let List.560 : U64 = lowlevel ListLen #Attr.2;
ret List.560;
let List.568 : U64 = lowlevel ListLen #Attr.2;
ret List.568;

procedure List.66 (#Attr.2, #Attr.3):
let List.558 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.558;
let List.566 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.566;

procedure List.9 (List.307):
let List.552 : U64 = 0i64;
let List.545 : [C {}, C Str] = CallByName List.2 List.307 List.552;
let List.549 : U8 = 1i64;
let List.550 : U8 = GetTagId List.545;
let List.551 : Int1 = lowlevel Eq List.549 List.550;
if List.551 then
let List.308 : Str = UnionAtIndex (Id 1) (Index 0) List.545;
let List.546 : [C {}, C Str] = TagId(1) List.308;
ret List.546;
procedure List.9 (List.315):
let List.560 : U64 = 0i64;
let List.553 : [C {}, C Str] = CallByName List.2 List.315 List.560;
let List.557 : U8 = 1i64;
let List.558 : U8 = GetTagId List.553;
let List.559 : Int1 = lowlevel Eq List.557 List.558;
if List.559 then
let List.316 : Str = UnionAtIndex (Id 1) (Index 0) List.553;
let List.554 : [C {}, C Str] = TagId(1) List.316;
ret List.554;
else
dec List.545;
let List.548 : {} = Struct {};
let List.547 : [C {}, C Str] = TagId(0) List.548;
ret List.547;
dec List.553;
let List.556 : {} = Struct {};
let List.555 : [C {}, C Str] = TagId(0) List.556;
ret List.555;

procedure Num.22 (#Attr.2, #Attr.3):
let Num.291 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
Expand Down
Loading

0 comments on commit 0252a11

Please sign in to comment.