Implement List.find

`List.find : List elem, (elem -> Bool) -> Result elem [ NotFound ]*`
behaves as follows:

```
>>> List.find [1, 2, 3] (\n -> n > 2)
Ok 2
>>> List.find [1, 2, 3] (\n -> n > 4)
Err NotFound
```

We implement this as builtin in two phases. First, we call out to a
pure-llvm-lowlevel `ListFindUnsafe` that returns a record indicating
whether a satisfying element was found, and the value of that element
(the value is all null bytes if the element wasn't found). Then, we lift
that record to a `Result` via a standard construction of the can AST.

Closes #1909
This commit is contained in:
ayazhafiz 2021-11-07 20:56:46 -05:00
parent 35df58c18f
commit f65b174ab5
16 changed files with 417 additions and 8 deletions

View file

@ -618,7 +618,8 @@ impl<'a> BorrowInfState<'a> {
| ListKeepIf { xs }
| ListKeepOks { xs }
| ListKeepErrs { xs }
| ListAny { xs } => {
| ListAny { xs }
| ListFindUnsafe { xs } => {
// own the list if the function wants to own the element
if !function_ps[0].borrow {
self.own_var(*xs);
@ -959,6 +960,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
arena.alloc_slice_copy(&[owned, owned, function, closure_data])
}
ListSortWith => arena.alloc_slice_copy(&[owned, function, closure_data]),
ListFindUnsafe => arena.alloc_slice_copy(&[owned, function, closure_data]),
// TODO when we have lists with capacity (if ever)
// List.append should own its first argument