mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 07:49:17 +03:00
Merge branch 'trunk' of github.com:rtfeldman/roc into crates-folder
This commit is contained in:
commit
b74fc3554b
@ -1,27 +1,27 @@
|
||||
procedure List.3 (List.76, List.77, List.78):
|
||||
let List.167 : {List I64, I64} = CallByName List.57 List.76 List.77 List.78;
|
||||
let List.166 : List I64 = StructAtIndex 0 List.167;
|
||||
inc List.166;
|
||||
dec List.167;
|
||||
ret List.166;
|
||||
procedure List.3 (List.81, List.82, List.83):
|
||||
let List.242 : {List I64, I64} = CallByName List.57 List.81 List.82 List.83;
|
||||
let List.241 : List I64 = StructAtIndex 0 List.242;
|
||||
inc List.241;
|
||||
dec List.242;
|
||||
ret List.241;
|
||||
|
||||
procedure List.57 (List.73, List.74, List.75):
|
||||
let List.173 : U64 = CallByName List.6 List.73;
|
||||
let List.170 : Int1 = CallByName Num.22 List.74 List.173;
|
||||
if List.170 then
|
||||
let List.171 : {List I64, I64} = CallByName List.61 List.73 List.74 List.75;
|
||||
ret List.171;
|
||||
procedure List.57 (List.78, List.79, List.80):
|
||||
let List.248 : U64 = CallByName List.6 List.78;
|
||||
let List.245 : Int1 = CallByName Num.22 List.79 List.248;
|
||||
if List.245 then
|
||||
let List.246 : {List I64, I64} = CallByName List.61 List.78 List.79 List.80;
|
||||
ret List.246;
|
||||
else
|
||||
let List.169 : {List I64, I64} = Struct {List.73, List.75};
|
||||
ret List.169;
|
||||
let List.244 : {List I64, I64} = Struct {List.78, List.80};
|
||||
ret List.244;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.165 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.165;
|
||||
let List.240 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.240;
|
||||
|
||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let List.172 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.172;
|
||||
let List.247 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.247;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
|
@ -1,22 +1,22 @@
|
||||
procedure List.2 (List.67, List.68):
|
||||
let List.170 : U64 = CallByName List.6 List.67;
|
||||
let List.166 : Int1 = CallByName Num.22 List.68 List.170;
|
||||
if List.166 then
|
||||
let List.168 : I64 = CallByName List.60 List.67 List.68;
|
||||
let List.167 : [C {}, C I64] = Ok List.168;
|
||||
ret List.167;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.245 : U64 = CallByName List.6 List.72;
|
||||
let List.241 : Int1 = CallByName Num.22 List.73 List.245;
|
||||
if List.241 then
|
||||
let List.243 : I64 = CallByName List.60 List.72 List.73;
|
||||
let List.242 : [C {}, C I64] = Ok List.243;
|
||||
ret List.242;
|
||||
else
|
||||
let List.165 : {} = Struct {};
|
||||
let List.164 : [C {}, C I64] = Err List.165;
|
||||
ret List.164;
|
||||
let List.240 : {} = Struct {};
|
||||
let List.239 : [C {}, C I64] = Err List.240;
|
||||
ret List.239;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.173 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.173;
|
||||
let List.248 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.248;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.172 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.172;
|
||||
let List.247 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.247;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -1,27 +1,27 @@
|
||||
procedure List.3 (List.76, List.77, List.78):
|
||||
let List.165 : {List I64, I64} = CallByName List.57 List.76 List.77 List.78;
|
||||
let List.164 : List I64 = StructAtIndex 0 List.165;
|
||||
inc List.164;
|
||||
dec List.165;
|
||||
ret List.164;
|
||||
procedure List.3 (List.81, List.82, List.83):
|
||||
let List.240 : {List I64, I64} = CallByName List.57 List.81 List.82 List.83;
|
||||
let List.239 : List I64 = StructAtIndex 0 List.240;
|
||||
inc List.239;
|
||||
dec List.240;
|
||||
ret List.239;
|
||||
|
||||
procedure List.57 (List.73, List.74, List.75):
|
||||
let List.171 : U64 = CallByName List.6 List.73;
|
||||
let List.168 : Int1 = CallByName Num.22 List.74 List.171;
|
||||
if List.168 then
|
||||
let List.169 : {List I64, I64} = CallByName List.61 List.73 List.74 List.75;
|
||||
ret List.169;
|
||||
procedure List.57 (List.78, List.79, List.80):
|
||||
let List.246 : U64 = CallByName List.6 List.78;
|
||||
let List.243 : Int1 = CallByName Num.22 List.79 List.246;
|
||||
if List.243 then
|
||||
let List.244 : {List I64, I64} = CallByName List.61 List.78 List.79 List.80;
|
||||
ret List.244;
|
||||
else
|
||||
let List.167 : {List I64, I64} = Struct {List.73, List.75};
|
||||
ret List.167;
|
||||
let List.242 : {List I64, I64} = Struct {List.78, List.80};
|
||||
ret List.242;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.172 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.172;
|
||||
let List.247 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.247;
|
||||
|
||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let List.170 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.170;
|
||||
let List.245 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.245;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -1332,16 +1332,6 @@ fn lowlevel_spec(
|
||||
|
||||
with_new_heap_cell(builder, block, bag)
|
||||
}
|
||||
ListReverse => {
|
||||
let list = env.symbols[&arguments[0]];
|
||||
|
||||
let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?;
|
||||
let cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?;
|
||||
|
||||
let _unit = builder.add_update(block, update_mode_var, cell)?;
|
||||
|
||||
with_new_heap_cell(builder, block, bag)
|
||||
}
|
||||
ListAppend => {
|
||||
let list = env.symbols[&arguments[0]];
|
||||
let to_insert = env.symbols[&arguments[1]];
|
||||
|
@ -990,66 +990,6 @@ pub fn listDropAt(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn listRange(width: utils.IntWidth, low: Opaque, high: Opaque) callconv(.C) RocList {
|
||||
return switch (width) {
|
||||
.U8 => helper1(u8, low, high),
|
||||
.U16 => helper1(u16, low, high),
|
||||
.U32 => helper1(u32, low, high),
|
||||
.U64 => helper1(u64, low, high),
|
||||
.U128 => helper1(u128, low, high),
|
||||
.I8 => helper1(i8, low, high),
|
||||
.I16 => helper1(i16, low, high),
|
||||
.I32 => helper1(i32, low, high),
|
||||
.I64 => helper1(i64, low, high),
|
||||
.I128 => helper1(i128, low, high),
|
||||
};
|
||||
}
|
||||
|
||||
fn helper1(comptime T: type, low: Opaque, high: Opaque) RocList {
|
||||
const ptr1 = @ptrCast(*T, @alignCast(@alignOf(T), low));
|
||||
const ptr2 = @ptrCast(*T, @alignCast(@alignOf(T), high));
|
||||
|
||||
return listRangeHelp(T, ptr1.*, ptr2.*);
|
||||
}
|
||||
|
||||
fn listRangeHelp(comptime T: type, low: T, high: T) RocList {
|
||||
const Order = std.math.Order;
|
||||
|
||||
switch (std.math.order(low, high)) {
|
||||
Order.gt => {
|
||||
return RocList.empty();
|
||||
},
|
||||
|
||||
Order.eq => {
|
||||
const list = RocList.allocate(@alignOf(usize), 1, @sizeOf(T));
|
||||
const buffer = @ptrCast([*]T, @alignCast(@alignOf(T), list.bytes orelse unreachable));
|
||||
|
||||
buffer[0] = low;
|
||||
|
||||
return list;
|
||||
},
|
||||
|
||||
Order.lt => {
|
||||
const length: usize = @intCast(usize, high - low);
|
||||
const list = RocList.allocate(@alignOf(usize), length, @sizeOf(T));
|
||||
|
||||
const buffer = @ptrCast([*]T, @alignCast(@alignOf(T), list.bytes orelse unreachable));
|
||||
|
||||
var i: usize = 0;
|
||||
var current = low;
|
||||
|
||||
while (i < length) {
|
||||
buffer[i] = current;
|
||||
|
||||
i += 1;
|
||||
current += 1;
|
||||
}
|
||||
|
||||
return list;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn partition(source_ptr: [*]u8, transform: Opaque, wrapper: CompareFn, element_width: usize, low: isize, high: isize) isize {
|
||||
const pivot = source_ptr + (@intCast(usize, high) * element_width);
|
||||
var i = (low - 1); // Index of smaller element and indicates the right position of pivot found so far
|
||||
@ -1209,34 +1149,6 @@ fn swapElements(source_ptr: [*]u8, element_width: usize, index_1: usize, index_2
|
||||
return swap(element_width, element_at_i, element_at_j);
|
||||
}
|
||||
|
||||
pub fn listJoin(list_of_lists: RocList, alignment: u32, element_width: usize) callconv(.C) RocList {
|
||||
var total_length: usize = 0;
|
||||
|
||||
const slice_of_lists = @ptrCast([*]RocList, @alignCast(@alignOf(RocList), list_of_lists.bytes));
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < list_of_lists.len()) : (i += 1) {
|
||||
total_length += slice_of_lists[i].len();
|
||||
}
|
||||
|
||||
const output = RocList.allocate(alignment, total_length, element_width);
|
||||
|
||||
if (output.bytes) |target| {
|
||||
var elements_copied: usize = 0;
|
||||
|
||||
i = 0;
|
||||
while (i < list_of_lists.len()) : (i += 1) {
|
||||
const list = slice_of_lists[i];
|
||||
if (list.bytes) |source| {
|
||||
@memcpy(target + elements_copied * element_width, source, list.len() * element_width);
|
||||
elements_copied += list.len();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_width: usize) callconv(.C) RocList {
|
||||
if (list_a.isEmpty()) {
|
||||
return list_b;
|
||||
|
@ -53,8 +53,6 @@ comptime {
|
||||
exportListFn(list.listPrepend, "prepend");
|
||||
exportListFn(list.listSingle, "single");
|
||||
exportListFn(list.listWithCapacity, "with_capacity");
|
||||
exportListFn(list.listJoin, "join");
|
||||
exportListFn(list.listRange, "range");
|
||||
exportListFn(list.listReverse, "reverse");
|
||||
exportListFn(list.listSortWith, "sort_with");
|
||||
exportListFn(list.listConcat, "concat");
|
||||
|
@ -9,6 +9,7 @@ interface List
|
||||
map,
|
||||
len,
|
||||
withCapacity,
|
||||
iterate,
|
||||
walkBackwards,
|
||||
concat,
|
||||
first,
|
||||
@ -273,6 +274,10 @@ concat : List a, List a -> List a
|
||||
|
||||
## Returns the last element in the list, or `ListWasEmpty` if it was empty.
|
||||
last : List a -> Result a [ListWasEmpty]*
|
||||
last = \list ->
|
||||
when List.get list (Num.subSaturated (List.len list) 1) is
|
||||
Ok v -> Ok v
|
||||
Err _ -> Err ListWasEmpty
|
||||
|
||||
## A list with a single element in it.
|
||||
##
|
||||
@ -283,15 +288,34 @@ last : List a -> Result a [ListWasEmpty]*
|
||||
## |> List.single
|
||||
##
|
||||
single : a -> List a
|
||||
single = \x -> [x]
|
||||
|
||||
## Returns a list with the given length, where every element is the given value.
|
||||
##
|
||||
##
|
||||
repeat : a, Nat -> List a
|
||||
repeat = \value, count ->
|
||||
repeatHelp value count (List.withCapacity count)
|
||||
|
||||
repeatHelp : a, Nat, List a -> List a
|
||||
repeatHelp = \value, count, accum ->
|
||||
if count > 0 then
|
||||
repeatHelp value (count - 1) (List.append accum value)
|
||||
else
|
||||
accum
|
||||
|
||||
## Returns the list with its elements reversed.
|
||||
##
|
||||
## >>> List.reverse [1, 2, 3]
|
||||
reverse : List a -> List a
|
||||
reverse = \list ->
|
||||
reverseHelp list 0 (Num.subSaturated (List.len list) 1)
|
||||
|
||||
reverseHelp = \list, left, right ->
|
||||
if left < right then
|
||||
reverseHelp (List.swap list left right) (left + 1) (right - 1)
|
||||
else
|
||||
list
|
||||
|
||||
## Join the given lists together into one list.
|
||||
##
|
||||
@ -301,7 +325,15 @@ reverse : List a -> List a
|
||||
##
|
||||
## >>> List.join []
|
||||
join : List (List a) -> List a
|
||||
join = \lists ->
|
||||
totalLength =
|
||||
List.walk lists 0 (\state, list -> state + List.len list)
|
||||
|
||||
List.walk lists (List.withCapacity totalLength) (\state, list -> List.concat state list)
|
||||
|
||||
contains : List a, a -> Bool
|
||||
contains = \list, needle ->
|
||||
List.any list (\x -> x == needle)
|
||||
|
||||
## Build a value using each element in the list.
|
||||
##
|
||||
@ -356,7 +388,11 @@ walkBackwards : List elem, state, (state, elem -> state) -> state
|
||||
##
|
||||
## As such, it is typically better for performance to use this over [List.walk]
|
||||
## if returning `Done` earlier than the last element is expected to be common.
|
||||
walkUntil : List elem, state, (state, elem -> [Continue state, Stop state]) -> state
|
||||
walkUntil : List elem, state, (state, elem -> [Continue state, Break state]) -> state
|
||||
walkUntil = \list, initial, step ->
|
||||
when List.iterate list initial step is
|
||||
Continue new -> new
|
||||
Break new -> new
|
||||
|
||||
sum : List (Num a) -> Num a
|
||||
sum = \list ->
|
||||
@ -369,10 +405,30 @@ product = \list ->
|
||||
## Run the given predicate on each element of the list, returning `True` if
|
||||
## any of the elements satisfy it.
|
||||
any : List a, (a -> Bool) -> Bool
|
||||
any = \list, predicate ->
|
||||
looper = \{}, element ->
|
||||
if predicate element then
|
||||
Break {}
|
||||
else
|
||||
Continue {}
|
||||
|
||||
when List.iterate list {} looper is
|
||||
Continue {} -> False
|
||||
Break {} -> True
|
||||
|
||||
## Run the given predicate on each element of the list, returning `True` if
|
||||
## all of the elements satisfy it.
|
||||
all : List a, (a -> Bool) -> Bool
|
||||
all = \list, predicate ->
|
||||
looper = \{}, element ->
|
||||
if predicate element then
|
||||
Continue {}
|
||||
else
|
||||
Break {}
|
||||
|
||||
when List.iterate list {} looper is
|
||||
Continue {} -> True
|
||||
Break {} -> False
|
||||
|
||||
## Run the given function on each element of a list, and return all the
|
||||
## elements for which the function returned `True`.
|
||||
@ -467,6 +523,23 @@ mapWithIndex : List a, (a, Nat -> b) -> List b
|
||||
##
|
||||
## >>> List.range 2 8
|
||||
range : Int a, Int a -> List (Int a)
|
||||
range = \start, end ->
|
||||
when Num.compare start end is
|
||||
GT -> []
|
||||
EQ -> [start]
|
||||
LT ->
|
||||
length = Num.intCast (start - end)
|
||||
|
||||
rangeHelp (List.withCapacity length) start end
|
||||
|
||||
rangeHelp : List (Int a), Int a, Int a -> List (Int a)
|
||||
rangeHelp = \accum, start, end ->
|
||||
if end <= start then
|
||||
accum
|
||||
else
|
||||
rangeHelp (List.append accum start) (start + 1) end
|
||||
|
||||
## Sort with a custom comparison function
|
||||
sortWith : List a, (a, a -> [LT, EQ, GT]) -> List a
|
||||
|
||||
## Sorts a list in ascending order (lowest to highest), using a function which
|
||||
@ -487,6 +560,10 @@ swap : List a, Nat, Nat -> List a
|
||||
|
||||
## Returns the first element in the list, or `ListWasEmpty` if it was empty.
|
||||
first : List a -> Result a [ListWasEmpty]*
|
||||
first = \list ->
|
||||
when List.get list 0 is
|
||||
Ok v -> Ok v
|
||||
Err _ -> Err ListWasEmpty
|
||||
|
||||
## Remove the first element from the list.
|
||||
##
|
||||
@ -610,22 +687,33 @@ joinMap = \list, mapper ->
|
||||
## Returns the first element of the list satisfying a predicate function.
|
||||
## If no satisfying element is found, an `Err NotFound` is returned.
|
||||
find : List elem, (elem -> Bool) -> Result elem [NotFound]*
|
||||
find = \array, pred ->
|
||||
callback = \_, elem ->
|
||||
if pred elem then
|
||||
Break elem
|
||||
else
|
||||
Continue {}
|
||||
|
||||
when List.iterate array {} callback is
|
||||
Continue {} ->
|
||||
Err NotFound
|
||||
Break found ->
|
||||
Ok found
|
||||
|
||||
## Returns the index at which the first element in the list
|
||||
## satisfying a predicate function can be found.
|
||||
## If no satisfying element is found, an `Err NotFound` is returned.
|
||||
findIndex : List elem, (elem -> Bool) -> Result Nat [NotFound]*
|
||||
findIndex = \list, matcher ->
|
||||
foundIndex = List.walkUntil list 0 \index, elem ->
|
||||
foundIndex = List.iterate list 0 \index, elem ->
|
||||
if matcher elem then
|
||||
Stop index
|
||||
Break index
|
||||
else
|
||||
Continue (index + 1)
|
||||
|
||||
if foundIndex < List.len list then
|
||||
Ok foundIndex
|
||||
else
|
||||
Err NotFound
|
||||
when foundIndex is
|
||||
Break index -> Ok index
|
||||
Continue _ -> Err NotFound
|
||||
|
||||
## Returns a subsection of the given list, beginning at the `start` index and
|
||||
## including a total of `len` elements.
|
||||
@ -653,3 +741,20 @@ intersperse : List elem, elem -> List elem
|
||||
## means if you give an index of 0, the `before` list will be empty and the
|
||||
## `others` list will have the same elements as the original list.)
|
||||
split : List elem, Nat -> { before : List elem, others : List elem }
|
||||
|
||||
## Primitive for iterating over a List, being able to decide at every element whether to continue
|
||||
iterate : List elem, s, (s, elem -> [Continue s, Break b]) -> [Continue s, Break b]
|
||||
iterate = \list, init, func ->
|
||||
iterHelp list init func 0 (List.len list)
|
||||
|
||||
## internal helper
|
||||
iterHelp : List elem, s, (s, elem -> [Continue s, Break b]), Nat, Nat -> [Continue s, Break b]
|
||||
iterHelp = \list, state, f, index, length ->
|
||||
if index < length then
|
||||
when f state (List.getUnsafe list index) is
|
||||
Continue nextState ->
|
||||
iterHelp list nextState f (index + 1) length
|
||||
Break b ->
|
||||
Break b
|
||||
else
|
||||
Continue state
|
||||
|
@ -368,8 +368,6 @@ pub const LIST_DROP_AT: &str = "roc_builtins.list.drop_at";
|
||||
pub const LIST_SWAP: &str = "roc_builtins.list.swap";
|
||||
pub const LIST_SINGLE: &str = "roc_builtins.list.single";
|
||||
pub const LIST_WITH_CAPACITY: &str = "roc_builtins.list.with_capacity";
|
||||
pub const LIST_JOIN: &str = "roc_builtins.list.join";
|
||||
pub const LIST_RANGE: &str = "roc_builtins.list.range";
|
||||
pub const LIST_REVERSE: &str = "roc_builtins.list.reverse";
|
||||
pub const LIST_SORT_WITH: &str = "roc_builtins.list.sort_with";
|
||||
pub const LIST_CONCAT: &str = "roc_builtins.list.concat";
|
||||
|
@ -1214,11 +1214,11 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||
);
|
||||
|
||||
fn until_type(content: SolvedType) -> SolvedType {
|
||||
// [LT, EQ, GT]
|
||||
// [Continue, Break]
|
||||
SolvedType::TagUnion(
|
||||
vec![
|
||||
(TagName("Continue".into()), vec![content.clone()]),
|
||||
(TagName("Stop".into()), vec![content]),
|
||||
(TagName("Break".into()), vec![content]),
|
||||
],
|
||||
Box::new(SolvedType::EmptyTagUnion),
|
||||
)
|
||||
|
@ -56,7 +56,6 @@ pub fn builtin_dependencies(symbol: Symbol) -> &'static [Symbol] {
|
||||
Symbol::LIST_SORT_DESC => &[Symbol::LIST_SORT_WITH],
|
||||
Symbol::LIST_PRODUCT => &[Symbol::LIST_WALK, Symbol::NUM_MUL],
|
||||
Symbol::LIST_SUM => &[Symbol::LIST_WALK, Symbol::NUM_ADD],
|
||||
Symbol::LIST_JOIN_MAP => &[Symbol::LIST_WALK, Symbol::LIST_CONCAT],
|
||||
Symbol::LIST_SET => &[Symbol::LIST_REPLACE],
|
||||
_ => &[],
|
||||
}
|
||||
@ -105,19 +104,10 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||
LIST_WITH_CAPACITY => list_with_capacity,
|
||||
LIST_GET_UNSAFE => list_get_unsafe,
|
||||
LIST_REPLACE_UNSAFE => list_replace_unsafe,
|
||||
LIST_SET => list_set,
|
||||
LIST_APPEND => list_append,
|
||||
LIST_FIRST => list_first,
|
||||
LIST_LAST => list_last,
|
||||
LIST_IS_EMPTY => list_is_empty,
|
||||
LIST_SINGLE => list_single,
|
||||
LIST_REPEAT => list_repeat,
|
||||
LIST_REVERSE => list_reverse,
|
||||
LIST_CONCAT => list_concat,
|
||||
LIST_CONTAINS => list_contains,
|
||||
LIST_PREPEND => list_prepend,
|
||||
LIST_JOIN => list_join,
|
||||
LIST_JOIN_MAP => list_join_map,
|
||||
LIST_MAP => list_map,
|
||||
LIST_MAP2 => list_map2,
|
||||
LIST_MAP3 => list_map3,
|
||||
@ -134,14 +124,10 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||
LIST_KEEP_IF => list_keep_if,
|
||||
LIST_KEEP_OKS => list_keep_oks,
|
||||
LIST_KEEP_ERRS=> list_keep_errs,
|
||||
LIST_RANGE => list_range,
|
||||
LIST_WALK => list_walk,
|
||||
LIST_WALK_BACKWARDS => list_walk_backwards,
|
||||
LIST_WALK_UNTIL => list_walk_until,
|
||||
LIST_SORT_WITH => list_sort_with,
|
||||
LIST_ANY => list_any,
|
||||
LIST_ALL => list_all,
|
||||
LIST_FIND => list_find,
|
||||
LIST_IS_UNIQUE => list_is_unique,
|
||||
DICT_LEN => dict_len,
|
||||
DICT_EMPTY => dict_empty,
|
||||
@ -1517,25 +1503,6 @@ fn list_is_empty(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// List.reverse : List elem -> List elem
|
||||
fn list_reverse(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::ListReverse,
|
||||
args: vec![(list_var, Var(Symbol::ARG_1))],
|
||||
ret_var: list_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(list_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
list_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// Str.split : Str, Str -> List Str
|
||||
fn str_split(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let str_var = var_store.fresh();
|
||||
@ -2107,50 +2074,6 @@ fn list_concat(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// List.repeat : elem, Nat -> List elem
|
||||
fn list_repeat(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let elem_var = var_store.fresh();
|
||||
let len_var = var_store.fresh();
|
||||
let list_var = var_store.fresh();
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::ListRepeat,
|
||||
args: vec![
|
||||
(elem_var, Var(Symbol::ARG_1)),
|
||||
(len_var, Var(Symbol::ARG_2)),
|
||||
],
|
||||
ret_var: list_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(elem_var, Symbol::ARG_1), (len_var, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
list_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.single : elem -> List elem
|
||||
fn list_single(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let elem_var = var_store.fresh();
|
||||
let list_var = var_store.fresh();
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::ListSingle,
|
||||
args: vec![(elem_var, Var(Symbol::ARG_1))],
|
||||
ret_var: list_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(elem_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
list_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.len : List a -> Nat
|
||||
fn list_len(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_1(symbol, LowLevel::ListLen, var_store)
|
||||
@ -2171,91 +2094,6 @@ fn list_replace_unsafe(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_3(symbol, LowLevel::ListReplaceUnsafe, var_store)
|
||||
}
|
||||
|
||||
/// List.set : List elem, Nat, elem -> List elem
|
||||
fn list_set(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let arg_list = Symbol::ARG_1;
|
||||
let arg_index = Symbol::ARG_2;
|
||||
let arg_elem = Symbol::ARG_3;
|
||||
let bool_var = var_store.fresh();
|
||||
let len_var = var_store.fresh();
|
||||
let elem_var = var_store.fresh();
|
||||
let replace_record_var = var_store.fresh();
|
||||
let list_arg_var = var_store.fresh(); // Uniqueness type Attr differs between
|
||||
let list_ret_var = var_store.fresh(); // the arg list and the returned list
|
||||
|
||||
let replace_function = (
|
||||
var_store.fresh(),
|
||||
Loc::at_zero(Expr::Var(Symbol::LIST_REPLACE)),
|
||||
var_store.fresh(),
|
||||
replace_record_var,
|
||||
);
|
||||
|
||||
let replace_call = Expr::Call(
|
||||
Box::new(replace_function),
|
||||
vec![
|
||||
(list_arg_var, Loc::at_zero(Var(arg_list))),
|
||||
(len_var, Loc::at_zero(Var(arg_index))),
|
||||
(elem_var, Loc::at_zero(Var(arg_elem))),
|
||||
],
|
||||
CalledVia::Space,
|
||||
);
|
||||
|
||||
// Perform a bounds check. If it passes, run LowLevel::ListSet.
|
||||
// Otherwise, return the list unmodified.
|
||||
let body = If {
|
||||
cond_var: bool_var,
|
||||
branch_var: list_ret_var,
|
||||
branches: vec![(
|
||||
// if-condition
|
||||
no_region(
|
||||
// index < List.len list
|
||||
RunLowLevel {
|
||||
op: LowLevel::NumLt,
|
||||
args: vec![
|
||||
(len_var, Var(arg_index)),
|
||||
(
|
||||
len_var,
|
||||
RunLowLevel {
|
||||
op: LowLevel::ListLen,
|
||||
args: vec![(list_arg_var, Var(arg_list))],
|
||||
ret_var: len_var,
|
||||
},
|
||||
),
|
||||
],
|
||||
ret_var: bool_var,
|
||||
},
|
||||
),
|
||||
// then-branch
|
||||
no_region(Access {
|
||||
record_var: replace_record_var,
|
||||
ext_var: var_store.fresh(),
|
||||
field_var: list_ret_var,
|
||||
loc_expr: Box::new(no_region(
|
||||
// List.replaceUnsafe list index elem
|
||||
replace_call,
|
||||
)),
|
||||
field: "list".into(),
|
||||
}),
|
||||
)],
|
||||
final_else: Box::new(
|
||||
// else-branch
|
||||
no_region(Var(arg_list)),
|
||||
),
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![
|
||||
(list_arg_var, Symbol::ARG_1),
|
||||
(len_var, Symbol::ARG_2),
|
||||
(elem_var, Symbol::ARG_3),
|
||||
],
|
||||
var_store,
|
||||
body,
|
||||
list_ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.swap : List elem, Nat, Nat -> List elem
|
||||
fn list_swap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
@ -2718,26 +2556,6 @@ fn list_prepend(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// List.join : List (List elem) -> List elem
|
||||
fn list_join(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
let list_of_list_var = var_store.fresh();
|
||||
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::ListJoin,
|
||||
args: vec![(list_of_list_var, Var(Symbol::ARG_1))],
|
||||
ret_var: list_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(list_of_list_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
list_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.walk : List elem, state, (state, elem -> state) -> state
|
||||
fn list_walk(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_3(symbol, LowLevel::ListWalk, var_store)
|
||||
@ -2753,90 +2571,6 @@ fn list_walk_until(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_3(symbol, LowLevel::ListWalkUntil, var_store)
|
||||
}
|
||||
|
||||
/// List.joinMap : List before, (before -> List after) -> List after
|
||||
fn list_join_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let before = var_store.fresh();
|
||||
let list_before = var_store.fresh();
|
||||
let after = var_store.fresh();
|
||||
let list_after = var_store.fresh();
|
||||
let before2list_after = var_store.fresh();
|
||||
let t_concat_clos = var_store.fresh();
|
||||
let mapper_lambda_set = var_store.fresh();
|
||||
|
||||
// \state, elem -> List.concat state (mapper elem)
|
||||
let concat_clos = Closure(ClosureData {
|
||||
function_type: t_concat_clos,
|
||||
closure_type: var_store.fresh(),
|
||||
return_type: list_after,
|
||||
name: Symbol::LIST_JOIN_MAP_CONCAT,
|
||||
recursive: Recursive::NotRecursive,
|
||||
captured_symbols: vec![(Symbol::ARG_2, before2list_after)],
|
||||
arguments: vec![
|
||||
(
|
||||
list_after,
|
||||
AnnotatedMark::new(var_store),
|
||||
no_region(Pattern::Identifier(Symbol::ARG_3)),
|
||||
),
|
||||
(
|
||||
before,
|
||||
AnnotatedMark::new(var_store),
|
||||
no_region(Pattern::Identifier(Symbol::ARG_4)),
|
||||
),
|
||||
],
|
||||
loc_body: {
|
||||
let mapper = Box::new((
|
||||
before2list_after,
|
||||
no_region(Var(Symbol::ARG_2)),
|
||||
mapper_lambda_set,
|
||||
list_after, // return type
|
||||
));
|
||||
// (mapper elem)
|
||||
let mapper_elem = Call(
|
||||
mapper,
|
||||
vec![(before, no_region(Var(Symbol::ARG_4)))],
|
||||
CalledVia::Space,
|
||||
);
|
||||
Box::new(no_region(RunLowLevel {
|
||||
op: LowLevel::ListConcat,
|
||||
args: vec![(list_after, Var(Symbol::ARG_3)), (list_after, mapper_elem)],
|
||||
ret_var: list_after,
|
||||
}))
|
||||
},
|
||||
});
|
||||
|
||||
// List.joinMap = \input_list, mapper ->
|
||||
// List.walk [] input_list (\state, elem -> List.concat state (mapper elem))
|
||||
let body = RunLowLevel {
|
||||
op: LowLevel::ListWalk,
|
||||
args: vec![
|
||||
// input_list : List before
|
||||
(list_before, Var(Symbol::ARG_1)),
|
||||
// [] : List after
|
||||
(
|
||||
list_after,
|
||||
List {
|
||||
elem_var: after,
|
||||
loc_elems: vec![],
|
||||
},
|
||||
),
|
||||
// \state, elem -> List.concat state (mapper elem)
|
||||
(t_concat_clos, concat_clos),
|
||||
],
|
||||
ret_var: list_after,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![
|
||||
(list_before, Symbol::ARG_1),
|
||||
(before2list_after, Symbol::ARG_2),
|
||||
],
|
||||
var_store,
|
||||
body,
|
||||
list_after,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||
fn list_keep_if(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list_var = var_store.fresh();
|
||||
@ -2860,11 +2594,6 @@ fn list_keep_if(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// List.contains : List elem, elem -> Bool
|
||||
fn list_contains(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListContains, var_store)
|
||||
}
|
||||
|
||||
/// List.keepOks : List before, (before -> Result after *) -> List after
|
||||
fn list_keep_oks(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListKeepOks, var_store)
|
||||
@ -2875,11 +2604,6 @@ fn list_keep_errs(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListKeepErrs, var_store)
|
||||
}
|
||||
|
||||
/// List.range: Int a, Int a -> List (Int a)
|
||||
fn list_range(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListRange, var_store)
|
||||
}
|
||||
|
||||
/// List.map : List before, (before -> after) -> List after
|
||||
fn list_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListMap, var_store)
|
||||
@ -2910,93 +2634,6 @@ fn list_sort_with(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListSortWith, var_store)
|
||||
}
|
||||
|
||||
/// List.any: List elem, (elem -> Bool) -> Bool
|
||||
fn list_any(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListAny, var_store)
|
||||
}
|
||||
|
||||
/// List.all: List elem, (elem -> Bool) -> Bool
|
||||
fn list_all(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::ListAll, var_store)
|
||||
}
|
||||
|
||||
/// List.find : List elem, (elem -> Bool) -> Result elem [NotFound]*
|
||||
fn list_find(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let list = Symbol::ARG_1;
|
||||
let find_predicate = Symbol::ARG_2;
|
||||
|
||||
let find_result = Symbol::LIST_FIND_RESULT;
|
||||
|
||||
let t_list = var_store.fresh();
|
||||
let t_pred_fn = var_store.fresh();
|
||||
let t_bool = var_store.fresh();
|
||||
let t_found = var_store.fresh();
|
||||
let t_value = var_store.fresh();
|
||||
let t_ret = var_store.fresh();
|
||||
let t_find_result = var_store.fresh();
|
||||
let t_ext_var1 = var_store.fresh();
|
||||
let t_ext_var2 = var_store.fresh();
|
||||
|
||||
// ListFindUnsafe returns { value: elem, found: Bool }.
|
||||
// When `found` is true, the value was found. Otherwise `List.find` should return `Err ...`
|
||||
let find_result_def = Def {
|
||||
annotation: None,
|
||||
expr_var: t_find_result,
|
||||
loc_expr: no_region(RunLowLevel {
|
||||
op: LowLevel::ListFindUnsafe,
|
||||
args: vec![(t_list, Var(list)), (t_pred_fn, Var(find_predicate))],
|
||||
ret_var: t_find_result,
|
||||
}),
|
||||
loc_pattern: no_region(Pattern::Identifier(find_result)),
|
||||
pattern_vars: Default::default(),
|
||||
};
|
||||
|
||||
let get_value = Access {
|
||||
record_var: t_find_result,
|
||||
ext_var: t_ext_var1,
|
||||
field_var: t_value,
|
||||
loc_expr: Box::new(no_region(Var(find_result))),
|
||||
field: "value".into(),
|
||||
};
|
||||
|
||||
let get_found = Access {
|
||||
record_var: t_find_result,
|
||||
ext_var: t_ext_var2,
|
||||
field_var: t_found,
|
||||
loc_expr: Box::new(no_region(Var(find_result))),
|
||||
field: "found".into(),
|
||||
};
|
||||
|
||||
let make_ok = tag("Ok", vec![get_value], var_store);
|
||||
|
||||
let make_err = tag(
|
||||
"Err",
|
||||
vec![tag("NotFound", Vec::new(), var_store)],
|
||||
var_store,
|
||||
);
|
||||
|
||||
let inspect = If {
|
||||
cond_var: t_bool,
|
||||
branch_var: t_ret,
|
||||
branches: vec![(
|
||||
// if-condition
|
||||
no_region(get_found),
|
||||
no_region(make_ok),
|
||||
)],
|
||||
final_else: Box::new(no_region(make_err)),
|
||||
};
|
||||
|
||||
let body = LetNonRec(Box::new(find_result_def), Box::new(no_region(inspect)));
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(t_list, Symbol::ARG_1), (t_pred_fn, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
t_ret,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.isUnique : List * -> Bool
|
||||
fn list_is_unique(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_1(symbol, LowLevel::ListIsUnique, var_store)
|
||||
@ -3720,203 +3357,6 @@ fn num_div_ceil_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// List.first : List elem -> Result elem [ListWasEmpty]*
|
||||
///
|
||||
/// List.first :
|
||||
/// Attr (* | u) (List (Attr u a)),
|
||||
/// -> Attr * (Result (Attr u a) (Attr * [OutOfBounds]*))
|
||||
fn list_first(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let list_var = var_store.fresh();
|
||||
let len_var = Variable::NAT;
|
||||
let zero_var = len_var;
|
||||
let zero_precision_var = Variable::NATURAL;
|
||||
let list_elem_var = var_store.fresh();
|
||||
let ret_var = var_store.fresh();
|
||||
|
||||
// Perform a bounds check. If it passes, delegate to List.getUnsafe.
|
||||
let body = If {
|
||||
cond_var: bool_var,
|
||||
branch_var: var_store.fresh(),
|
||||
branches: vec![(
|
||||
// if-condition
|
||||
no_region(
|
||||
// List.len list != 0
|
||||
RunLowLevel {
|
||||
op: LowLevel::NotEq,
|
||||
args: vec![
|
||||
(
|
||||
len_var,
|
||||
int::<i128>(zero_var, zero_precision_var, 0, int_no_bound()),
|
||||
),
|
||||
(
|
||||
len_var,
|
||||
RunLowLevel {
|
||||
op: LowLevel::ListLen,
|
||||
args: vec![(list_var, Var(Symbol::ARG_1))],
|
||||
ret_var: len_var,
|
||||
},
|
||||
),
|
||||
],
|
||||
ret_var: bool_var,
|
||||
},
|
||||
),
|
||||
// list was not empty
|
||||
no_region(
|
||||
// Ok (List.#getUnsafe list 0)
|
||||
tag(
|
||||
"Ok",
|
||||
vec![
|
||||
// List.#getUnsafe list 0
|
||||
RunLowLevel {
|
||||
op: LowLevel::ListGetUnsafe,
|
||||
args: vec![
|
||||
(list_var, Var(Symbol::ARG_1)),
|
||||
(
|
||||
len_var,
|
||||
int::<i128>(zero_var, zero_precision_var, 0, int_no_bound()),
|
||||
),
|
||||
],
|
||||
ret_var: list_elem_var,
|
||||
},
|
||||
],
|
||||
var_store,
|
||||
),
|
||||
),
|
||||
)],
|
||||
final_else: Box::new(
|
||||
// list was empty
|
||||
no_region(
|
||||
// Err ListWasEmpty
|
||||
tag(
|
||||
"Err",
|
||||
vec![tag("ListWasEmpty", Vec::new(), var_store)],
|
||||
var_store,
|
||||
),
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(list_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.last : List elem -> Result elem [ListWasEmpty]*
|
||||
///
|
||||
/// List.last :
|
||||
/// Attr (* | u) (List (Attr u a)),
|
||||
/// -> Attr * (Result (Attr u a) (Attr * [OutOfBounds]*))
|
||||
fn list_last(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let arg_var = var_store.fresh();
|
||||
let bool_var = var_store.fresh();
|
||||
let list_var = var_store.fresh();
|
||||
let len_var = Variable::NAT;
|
||||
let num_var = len_var;
|
||||
let num_precision_var = Variable::NATURAL;
|
||||
let list_elem_var = var_store.fresh();
|
||||
let ret_var = var_store.fresh();
|
||||
|
||||
// Perform a bounds check. If it passes, delegate to List.getUnsafe.
|
||||
let body = If {
|
||||
cond_var: bool_var,
|
||||
branch_var: var_store.fresh(),
|
||||
branches: vec![(
|
||||
// if-condition
|
||||
no_region(
|
||||
// List.len list != 0
|
||||
RunLowLevel {
|
||||
op: LowLevel::NotEq,
|
||||
args: vec![
|
||||
(
|
||||
len_var,
|
||||
int::<i128>(num_var, num_precision_var, 0, int_no_bound()),
|
||||
),
|
||||
(
|
||||
len_var,
|
||||
RunLowLevel {
|
||||
op: LowLevel::ListLen,
|
||||
args: vec![(list_var, Var(Symbol::ARG_1))],
|
||||
ret_var: len_var,
|
||||
},
|
||||
),
|
||||
],
|
||||
ret_var: bool_var,
|
||||
},
|
||||
),
|
||||
// list was not empty
|
||||
no_region(
|
||||
// Ok (List.getUnsafe list (Num.sub (List.len list) 1))
|
||||
tag(
|
||||
"Ok",
|
||||
vec![
|
||||
// List.getUnsafe list (Num.sub (List.len list) 1)
|
||||
RunLowLevel {
|
||||
op: LowLevel::ListGetUnsafe,
|
||||
args: vec![
|
||||
(list_var, Var(Symbol::ARG_1)),
|
||||
(
|
||||
len_var,
|
||||
// Num.sub (List.len list) 1
|
||||
RunLowLevel {
|
||||
op: LowLevel::NumSubWrap,
|
||||
args: vec![
|
||||
(
|
||||
arg_var,
|
||||
// List.len list
|
||||
RunLowLevel {
|
||||
op: LowLevel::ListLen,
|
||||
args: vec![(list_var, Var(Symbol::ARG_1))],
|
||||
ret_var: len_var,
|
||||
},
|
||||
),
|
||||
(
|
||||
arg_var,
|
||||
int::<i128>(
|
||||
num_var,
|
||||
num_precision_var,
|
||||
1,
|
||||
int_no_bound(),
|
||||
),
|
||||
),
|
||||
],
|
||||
ret_var: len_var,
|
||||
},
|
||||
),
|
||||
],
|
||||
ret_var: list_elem_var,
|
||||
},
|
||||
],
|
||||
var_store,
|
||||
),
|
||||
),
|
||||
)],
|
||||
final_else: Box::new(
|
||||
// list was empty
|
||||
no_region(
|
||||
// Err ListWasEmpty
|
||||
tag(
|
||||
"Err",
|
||||
vec![tag("ListWasEmpty", Vec::new(), var_store)],
|
||||
var_store,
|
||||
),
|
||||
),
|
||||
),
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(list_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
fn result_map(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let ret_var = var_store.fresh();
|
||||
let func_var = var_store.fresh();
|
||||
|
@ -9,11 +9,10 @@ use crate::llvm::build_dict::{
|
||||
use crate::llvm::build_hash::generic_hash;
|
||||
use crate::llvm::build_list::{
|
||||
self, allocate_list, empty_polymorphic_list, list_all, list_any, list_append, list_concat,
|
||||
list_contains, list_drop_at, list_find_unsafe, list_get_unsafe, list_join, list_keep_errs,
|
||||
list_keep_if, list_keep_oks, list_len, list_map, list_map2, list_map3, list_map4,
|
||||
list_map_with_index, list_prepend, list_range, list_repeat, list_replace_unsafe, list_reverse,
|
||||
list_single, list_sort_with, list_sublist, list_swap, list_symbol_to_c_abi, list_to_c_abi,
|
||||
list_with_capacity,
|
||||
list_drop_at, list_find_unsafe, list_get_unsafe, list_keep_errs, list_keep_if, list_keep_oks,
|
||||
list_len, list_map, list_map2, list_map3, list_map4, list_map_with_index, list_prepend,
|
||||
list_replace_unsafe, list_sort_with, list_sublist, list_swap, list_symbol_to_c_abi,
|
||||
list_to_c_abi, list_with_capacity,
|
||||
};
|
||||
use crate::llvm::build_str::{
|
||||
str_from_float, str_from_int, str_from_utf8, str_from_utf8_range, str_split,
|
||||
@ -5595,33 +5594,6 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||
|
||||
list_with_capacity(env, list_len, &list_element_layout!(result_layout))
|
||||
}
|
||||
ListSingle => {
|
||||
// List.single : a -> List a
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (arg, arg_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
list_single(env, arg, arg_layout)
|
||||
}
|
||||
ListRepeat => {
|
||||
// List.repeat : elem, Nat -> List elem
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (elem, elem_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let list_len = load_symbol(scope, &args[1]).into_int_value();
|
||||
|
||||
list_repeat(env, layout_ids, elem, elem_layout, list_len)
|
||||
}
|
||||
ListReverse => {
|
||||
// List.reverse : List elem -> List elem
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (list, list_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let element_layout = list_element_layout!(list_layout);
|
||||
|
||||
list_reverse(env, list, element_layout, update_mode)
|
||||
}
|
||||
ListConcat => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
@ -5633,30 +5605,6 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||
|
||||
list_concat(env, first_list, second_list, element_layout)
|
||||
}
|
||||
ListContains => {
|
||||
// List.contains : List elem, elem -> Bool
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let list = load_symbol(scope, &args[0]);
|
||||
|
||||
let (elem, elem_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||
|
||||
list_contains(env, layout_ids, elem, elem_layout, list)
|
||||
}
|
||||
ListRange => {
|
||||
// List.contains : List elem, elem -> Bool
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (low, low_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let high = load_symbol(scope, &args[1]);
|
||||
|
||||
let int_width = match low_layout {
|
||||
Layout::Builtin(Builtin::Int(int_width)) => *int_width,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
list_range(env, int_width, low.into_int_value(), high.into_int_value())
|
||||
}
|
||||
ListAppend => {
|
||||
// List.append : List elem, elem -> List elem
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
@ -5736,17 +5684,6 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||
|
||||
list_prepend(env, original_wrapper, elem, elem_layout)
|
||||
}
|
||||
ListJoin => {
|
||||
// List.join : List (List elem) -> List elem
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let (list, outer_list_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
|
||||
let inner_list_layout = list_element_layout!(outer_list_layout);
|
||||
let element_layout = list_element_layout!(inner_list_layout);
|
||||
|
||||
list_join(env, list, element_layout)
|
||||
}
|
||||
ListGetUnsafe => {
|
||||
// List.get : List elem, Nat -> [Ok elem, OutOfBounds]*
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
@ -6226,7 +6163,7 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListWalk
|
||||
| ListWalkUntil | ListWalkBackwards | ListKeepOks | ListKeepErrs | ListSortWith
|
||||
| ListAny | ListAll | ListFindUnsafe | DictWalk => {
|
||||
| ListFindUnsafe | DictWalk => {
|
||||
unreachable!("these are higher order, and are handled elsewhere")
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
use crate::llvm::bitcode::{
|
||||
build_dec_wrapper, build_eq_wrapper, build_has_tag_id, build_inc_n_wrapper, build_inc_wrapper,
|
||||
call_bitcode_fn, call_list_bitcode_fn, call_void_bitcode_fn,
|
||||
build_dec_wrapper, build_has_tag_id, build_inc_n_wrapper, build_inc_wrapper, call_bitcode_fn,
|
||||
call_list_bitcode_fn, call_void_bitcode_fn,
|
||||
};
|
||||
use crate::llvm::build::{
|
||||
allocate_with_refcount_help, cast_basic_basic, Env, RocFunctionCall, Scope,
|
||||
@ -14,7 +14,7 @@ use inkwell::types::{BasicType, BasicTypeEnum, PointerType};
|
||||
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue, StructValue};
|
||||
use inkwell::{AddressSpace, IntPredicate};
|
||||
use morphic_lib::UpdateMode;
|
||||
use roc_builtins::bitcode::{self, IntWidth};
|
||||
use roc_builtins::bitcode;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::layout::{Builtin, Layout, LayoutIds};
|
||||
|
||||
@ -106,23 +106,6 @@ pub fn pass_as_opaque<'a, 'ctx, 'env>(
|
||||
)
|
||||
}
|
||||
|
||||
/// List.single : a -> List a
|
||||
pub fn list_single<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
element: BasicValueEnum<'ctx>,
|
||||
element_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
env.alignment_intvalue(element_layout),
|
||||
pass_element_as_opaque(env, element, *element_layout),
|
||||
layout_width(env, element_layout),
|
||||
],
|
||||
bitcode::LIST_SINGLE,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn list_with_capacity<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
capacity: IntValue<'ctx>,
|
||||
@ -162,42 +145,6 @@ pub fn list_repeat<'a, 'ctx, 'env>(
|
||||
)
|
||||
}
|
||||
|
||||
/// List.join : List (List elem) -> List elem
|
||||
pub fn list_join<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
outer_list: BasicValueEnum<'ctx>,
|
||||
element_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
list_to_c_abi(env, outer_list).into(),
|
||||
env.alignment_intvalue(element_layout),
|
||||
layout_width(env, element_layout),
|
||||
],
|
||||
bitcode::LIST_JOIN,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.reverse : List elem -> List elem
|
||||
pub fn list_reverse<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
element_layout: &Layout<'a>,
|
||||
update_mode: UpdateMode,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
list_to_c_abi(env, list).into(),
|
||||
env.alignment_intvalue(element_layout),
|
||||
layout_width(env, element_layout),
|
||||
pass_update_mode(env, update_mode),
|
||||
],
|
||||
bitcode::LIST_REVERSE,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn list_get_unsafe<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
@ -526,63 +473,6 @@ pub fn list_walk_generic<'a, 'ctx, 'env>(
|
||||
}
|
||||
}
|
||||
|
||||
/// List.range : Int a, Int a -> List (Int a)
|
||||
pub fn list_range<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
int_width: IntWidth,
|
||||
low: IntValue<'ctx>,
|
||||
high: IntValue<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let builder = env.builder;
|
||||
|
||||
let low_ptr = builder.build_alloca(low.get_type(), "low_ptr");
|
||||
env.builder.build_store(low_ptr, low);
|
||||
|
||||
let high_ptr = builder.build_alloca(high.get_type(), "high_ptr");
|
||||
env.builder.build_store(high_ptr, high);
|
||||
|
||||
let int_width = env
|
||||
.context
|
||||
.i8_type()
|
||||
.const_int(int_width as u64, false)
|
||||
.into();
|
||||
|
||||
call_list_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
int_width,
|
||||
pass_as_opaque(env, low_ptr),
|
||||
pass_as_opaque(env, high_ptr),
|
||||
],
|
||||
bitcode::LIST_RANGE,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.contains : List elem, elem -> Bool
|
||||
pub fn list_contains<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout_ids: &mut LayoutIds<'a>,
|
||||
element: BasicValueEnum<'ctx>,
|
||||
element_layout: &Layout<'a>,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let eq_fn = build_eq_wrapper(env, layout_ids, element_layout)
|
||||
.as_global_value()
|
||||
.as_pointer_value()
|
||||
.into();
|
||||
|
||||
call_bitcode_fn(
|
||||
env,
|
||||
&[
|
||||
list_to_c_abi(env, list).into(),
|
||||
pass_element_as_opaque(env, element, *element_layout),
|
||||
layout_width(env, element_layout),
|
||||
eq_fn,
|
||||
],
|
||||
bitcode::LIST_CONTAINS,
|
||||
)
|
||||
}
|
||||
|
||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||
pub fn list_keep_if<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
|
@ -5,7 +5,7 @@ use roc_error_macros::internal_error;
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::code_gen_help::HelperOp;
|
||||
use roc_mono::ir::{HigherOrderLowLevel, ListLiteralElement, PassedFunction, ProcLayout};
|
||||
use roc_mono::ir::{HigherOrderLowLevel, PassedFunction, ProcLayout};
|
||||
use roc_mono::layout::{Builtin, FieldOrderHash, Layout, UnionLayout};
|
||||
use roc_mono::low_level::HigherOrder;
|
||||
|
||||
@ -290,7 +290,7 @@ impl<'a> LowLevelCall<'a> {
|
||||
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListWalk
|
||||
| ListWalkUntil | ListWalkBackwards | ListKeepOks | ListKeepErrs | ListSortWith
|
||||
| ListAny | ListAll | ListFindUnsafe | DictWalk => {
|
||||
| ListFindUnsafe | DictWalk => {
|
||||
internal_error!("HigherOrder lowlevels should not be handled here")
|
||||
}
|
||||
|
||||
@ -419,12 +419,6 @@ impl<'a> LowLevelCall<'a> {
|
||||
// There is an in-place version of this but we don't use it for dev backends. No morphic_lib analysis.
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_REPLACE, 8, false);
|
||||
}
|
||||
ListSingle => {
|
||||
let elem = self.arguments[0];
|
||||
let elem_layout = &backend.storage.symbol_layouts[&elem].clone();
|
||||
let elems = backend.env.arena.alloc([ListLiteralElement::Symbol(elem)]);
|
||||
backend.expr_array(self.ret_symbol, &self.ret_storage, elem_layout, elems)
|
||||
}
|
||||
ListWithCapacity => {
|
||||
// List.withCapacity : Nat -> List elem
|
||||
|
||||
@ -446,72 +440,6 @@ impl<'a> LowLevelCall<'a> {
|
||||
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_WITH_CAPACITY, 4, false);
|
||||
}
|
||||
ListRepeat => {
|
||||
// List.repeat : elem, Nat -> List elem
|
||||
|
||||
let element: Symbol = self.arguments[0];
|
||||
let count: Symbol = self.arguments[1];
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
|
||||
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
|
||||
|
||||
let (elem_local, elem_offset, elem_in_memory_layout) =
|
||||
ensure_symbol_is_in_memory(backend, element, *elem_layout, backend.env.arena);
|
||||
|
||||
let inc_fn = backend.get_refcount_fn_index(elem_in_memory_layout, HelperOp::Inc);
|
||||
let inc_fn_ptr = backend.get_fn_ptr(inc_fn);
|
||||
|
||||
// Zig arguments Wasm types
|
||||
// (return pointer) i32
|
||||
// count: usize i32
|
||||
// alignment: u32 i32
|
||||
// element: Opaque i32
|
||||
// element_width: usize i32
|
||||
// inc_n_element: IncN i32
|
||||
|
||||
backend
|
||||
.storage
|
||||
.load_symbols(&mut backend.code_builder, &[self.ret_symbol, count]);
|
||||
backend.code_builder.i32_const(elem_align as i32);
|
||||
|
||||
backend.code_builder.get_local(elem_local);
|
||||
if elem_offset > 0 {
|
||||
backend.code_builder.i32_const(elem_offset as i32);
|
||||
backend.code_builder.i32_add();
|
||||
}
|
||||
|
||||
backend.code_builder.i32_const(elem_width as i32);
|
||||
backend.code_builder.i32_const(inc_fn_ptr);
|
||||
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_REPEAT, 6, false);
|
||||
}
|
||||
ListReverse => {
|
||||
// List.reverse : List elem -> List elem
|
||||
// Zig arguments Wasm types
|
||||
// (return pointer) i32
|
||||
// list: RocList i64, i32
|
||||
// alignment: u32 i32
|
||||
// element_width: usize i32
|
||||
// update_mode: UpdateMode i32
|
||||
|
||||
// Load the arguments that have symbols
|
||||
backend.storage.load_symbols_for_call(
|
||||
backend.env.arena,
|
||||
&mut backend.code_builder,
|
||||
self.arguments,
|
||||
self.ret_symbol,
|
||||
&WasmLayout::new(&self.ret_layout),
|
||||
CallConv::Zig,
|
||||
);
|
||||
|
||||
// Load monomorphization constants
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
|
||||
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
|
||||
backend.code_builder.i32_const(elem_align as i32);
|
||||
backend.code_builder.i32_const(elem_width as i32);
|
||||
backend.code_builder.i32_const(UPDATE_MODE_IMMUTABLE);
|
||||
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_REVERSE, 6, false);
|
||||
}
|
||||
ListConcat => {
|
||||
// List.concat : List elem, List elem -> List elem
|
||||
// Zig arguments Wasm types
|
||||
@ -539,7 +467,6 @@ impl<'a> LowLevelCall<'a> {
|
||||
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_CONCAT, 7, false);
|
||||
}
|
||||
ListContains => todo!("{:?}", self.lowlevel),
|
||||
ListAppend => {
|
||||
// List.append : List elem, elem -> List elem
|
||||
|
||||
@ -583,33 +510,6 @@ impl<'a> LowLevelCall<'a> {
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_APPEND, 7, false);
|
||||
}
|
||||
ListPrepend => todo!("{:?}", self.lowlevel),
|
||||
ListJoin => {
|
||||
// List.join : List (List elem) -> List elem
|
||||
// Zig arguments Wasm types
|
||||
// (return pointer) i32
|
||||
// list_of_lists: RocList i64, i32
|
||||
// alignment: u32 i32
|
||||
// element_width: usize i32
|
||||
|
||||
// Load the arguments that have symbols
|
||||
backend.storage.load_symbols_for_call(
|
||||
backend.env.arena,
|
||||
&mut backend.code_builder,
|
||||
self.arguments,
|
||||
self.ret_symbol,
|
||||
&WasmLayout::new(&self.ret_layout),
|
||||
CallConv::Zig,
|
||||
);
|
||||
|
||||
// Load monomorphization constants
|
||||
let elem_layout = unwrap_list_elem_layout(self.ret_layout);
|
||||
let (elem_width, elem_align) = elem_layout.stack_size_and_alignment(TARGET_INFO);
|
||||
backend.code_builder.i32_const(elem_align as i32);
|
||||
backend.code_builder.i32_const(elem_width as i32);
|
||||
|
||||
backend.call_host_fn_after_loading_args(bitcode::LIST_JOIN, 5, false);
|
||||
}
|
||||
ListRange => todo!("{:?}", self.lowlevel),
|
||||
ListSublist => {
|
||||
// As a low-level, record is destructured
|
||||
// List.sublist : List elem, start : Nat, len : Nat -> List elem
|
||||
|
@ -134,7 +134,9 @@ impl<'a> Storage<'a> {
|
||||
}
|
||||
|
||||
fn allocate_stack_memory(&mut self, size: u32, alignment_bytes: u32) -> u32 {
|
||||
if self.stack_frame_pointer.is_none() && size > 0 {
|
||||
// Note: We need a stack frame pointer even if size is zero.
|
||||
// e.g. when passing an empty record to a Zig builtin, we pass the frame pointer
|
||||
if self.stack_frame_pointer.is_none() {
|
||||
let next_local_id = self.get_next_local_id();
|
||||
self.stack_frame_pointer = Some(next_local_id);
|
||||
self.local_types.push(PTR_TYPE);
|
||||
|
@ -26,16 +26,10 @@ pub enum LowLevel {
|
||||
ListLen,
|
||||
ListWithCapacity,
|
||||
ListGetUnsafe,
|
||||
ListSingle,
|
||||
ListRepeat,
|
||||
ListReplaceUnsafe,
|
||||
ListReverse,
|
||||
ListConcat,
|
||||
ListContains,
|
||||
ListAppend,
|
||||
ListPrepend,
|
||||
ListJoin,
|
||||
ListRange,
|
||||
ListMap,
|
||||
ListMap2,
|
||||
ListMap3,
|
||||
@ -51,8 +45,6 @@ pub enum LowLevel {
|
||||
ListSublist,
|
||||
ListDropAt,
|
||||
ListSwap,
|
||||
ListAny,
|
||||
ListAll,
|
||||
ListFindUnsafe,
|
||||
ListIsUnique,
|
||||
DictSize,
|
||||
@ -146,8 +138,6 @@ macro_rules! higher_order {
|
||||
| ListKeepOks
|
||||
| ListKeepErrs
|
||||
| ListSortWith
|
||||
| ListAny
|
||||
| ListAll
|
||||
| ListFindUnsafe
|
||||
| DictWalk
|
||||
};
|
||||
@ -178,8 +168,6 @@ impl LowLevel {
|
||||
ListKeepOks => 1,
|
||||
ListKeepErrs => 1,
|
||||
ListSortWith => 1,
|
||||
ListAny => 1,
|
||||
ListAll => 1,
|
||||
ListFindUnsafe => 1,
|
||||
DictWalk => 2,
|
||||
_ => unreachable!(),
|
||||
@ -236,15 +224,9 @@ impl LowLevelWrapperType {
|
||||
Symbol::LIST_LEN => CanBeReplacedBy(ListLen),
|
||||
Symbol::LIST_GET => WrapperIsRequired,
|
||||
Symbol::LIST_REPLACE => WrapperIsRequired,
|
||||
Symbol::LIST_SINGLE => CanBeReplacedBy(ListSingle),
|
||||
Symbol::LIST_REPEAT => CanBeReplacedBy(ListRepeat),
|
||||
Symbol::LIST_REVERSE => CanBeReplacedBy(ListReverse),
|
||||
Symbol::LIST_CONCAT => CanBeReplacedBy(ListConcat),
|
||||
Symbol::LIST_CONTAINS => CanBeReplacedBy(ListContains),
|
||||
Symbol::LIST_APPEND => CanBeReplacedBy(ListAppend),
|
||||
Symbol::LIST_PREPEND => CanBeReplacedBy(ListPrepend),
|
||||
Symbol::LIST_JOIN => CanBeReplacedBy(ListJoin),
|
||||
Symbol::LIST_RANGE => CanBeReplacedBy(ListRange),
|
||||
Symbol::LIST_MAP => WrapperIsRequired,
|
||||
Symbol::LIST_MAP2 => WrapperIsRequired,
|
||||
Symbol::LIST_MAP3 => WrapperIsRequired,
|
||||
|
@ -1254,6 +1254,7 @@ define_builtins! {
|
||||
60 LIST_GET_UNSAFE: "getUnsafe"
|
||||
61 LIST_REPLACE_UNSAFE: "replaceUnsafe"
|
||||
62 LIST_WITH_CAPACITY: "withCapacity"
|
||||
63 LIST_ITERATE: "iterate"
|
||||
}
|
||||
6 RESULT: "Result" => {
|
||||
0 RESULT_RESULT: "Result" // the Result.Result type alias
|
||||
|
@ -907,22 +907,15 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||
StrTrimRight => arena.alloc_slice_copy(&[owned]),
|
||||
StrSplit => arena.alloc_slice_copy(&[borrowed, borrowed]),
|
||||
StrToNum => arena.alloc_slice_copy(&[borrowed]),
|
||||
ListSingle => arena.alloc_slice_copy(&[irrelevant]),
|
||||
// List.repeat : elem, Nat -> List.elem
|
||||
ListRepeat => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
ListReverse => arena.alloc_slice_copy(&[owned]),
|
||||
ListPrepend => arena.alloc_slice_copy(&[owned, owned]),
|
||||
StrJoinWith => arena.alloc_slice_copy(&[borrowed, borrowed]),
|
||||
ListJoin => arena.alloc_slice_copy(&[irrelevant]),
|
||||
ListMap | ListMapWithIndex => arena.alloc_slice_copy(&[owned, function, closure_data]),
|
||||
ListMap2 => arena.alloc_slice_copy(&[owned, owned, function, closure_data]),
|
||||
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, function, closure_data]),
|
||||
ListMap4 => arena.alloc_slice_copy(&[owned, owned, owned, owned, function, closure_data]),
|
||||
ListKeepIf | ListKeepOks | ListKeepErrs | ListAny | ListAll => {
|
||||
ListKeepIf | ListKeepOks | ListKeepErrs => {
|
||||
arena.alloc_slice_copy(&[owned, function, closure_data])
|
||||
}
|
||||
ListContains => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
ListRange => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
|
||||
ListWalk | ListWalkUntil | ListWalkBackwards => {
|
||||
arena.alloc_slice_copy(&[owned, owned, function, closure_data])
|
||||
}
|
||||
|
@ -5061,17 +5061,6 @@ pub fn with_hole<'a>(
|
||||
stmt,
|
||||
)
|
||||
}
|
||||
ListAny => {
|
||||
debug_assert_eq!(arg_symbols.len(), 2);
|
||||
let xs = arg_symbols[0];
|
||||
match_on_closure_argument!(ListAny, [xs])
|
||||
}
|
||||
ListAll => {
|
||||
debug_assert_eq!(arg_symbols.len(), 2);
|
||||
let xs = arg_symbols[0];
|
||||
match_on_closure_argument!(ListAll, [xs])
|
||||
}
|
||||
|
||||
ListKeepOks => {
|
||||
debug_assert_eq!(arg_symbols.len(), 2);
|
||||
let xs = arg_symbols[0];
|
||||
|
@ -132,18 +132,11 @@ enum FirstOrder {
|
||||
StrFromFloat,
|
||||
ListLen,
|
||||
ListGetUnsafe,
|
||||
ListSet,
|
||||
ListSublist,
|
||||
ListDropAt,
|
||||
ListSingle,
|
||||
ListRepeat,
|
||||
ListReverse,
|
||||
ListConcat,
|
||||
ListContains,
|
||||
ListAppend,
|
||||
ListPrepend,
|
||||
ListJoin,
|
||||
ListRange,
|
||||
ListSwap,
|
||||
DictSize,
|
||||
DictEmpty,
|
||||
|
@ -809,7 +809,7 @@ fn list_walk_implements_position() {
|
||||
findHelp = \list, needle ->
|
||||
List.walkUntil list { n: 0, v: None } \{ n, v }, element ->
|
||||
if element == needle then
|
||||
Stop { n, v: Some n }
|
||||
Break { n, v: Some n }
|
||||
else
|
||||
Continue { n: n + 1, v }
|
||||
|
||||
@ -832,7 +832,7 @@ fn list_walk_until_even_prefix_sum() {
|
||||
Continue (a + b)
|
||||
|
||||
else
|
||||
Stop a
|
||||
Break a
|
||||
|
||||
List.walkUntil [2, 4, 8, 9] 0 helper"#,
|
||||
2 + 4 + 8,
|
||||
@ -1197,7 +1197,7 @@ fn list_map2_different_lengths() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_empty_list() {
|
||||
assert_evals_to!(
|
||||
"List.join []",
|
||||
@ -1207,7 +1207,7 @@ fn list_join_empty_list() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_one_list() {
|
||||
assert_evals_to!(
|
||||
"List.join [[1, 2, 3]]",
|
||||
@ -1217,7 +1217,7 @@ fn list_join_one_list() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_two_non_empty_lists() {
|
||||
assert_evals_to!(
|
||||
"List.join [[1, 2, 3] , [4 ,5, 6]]",
|
||||
@ -1227,7 +1227,7 @@ fn list_join_two_non_empty_lists() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_two_non_empty_lists_of_float() {
|
||||
assert_evals_to!(
|
||||
"List.join [[1.2, 1.1], [2.1, 2.2]]",
|
||||
@ -1237,7 +1237,7 @@ fn list_join_two_non_empty_lists_of_float() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_to_big_list() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
@ -1263,7 +1263,7 @@ fn list_join_to_big_list() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_defined_empty_list() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
@ -1281,7 +1281,7 @@ fn list_join_defined_empty_list() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_all_empty_lists() {
|
||||
assert_evals_to!(
|
||||
"List.join [[], [], []]",
|
||||
@ -1291,7 +1291,7 @@ fn list_join_all_empty_lists() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn list_join_one_empty_list() {
|
||||
assert_evals_to!(
|
||||
"List.join [[1.2, 1.1], []]",
|
||||
@ -2597,7 +2597,7 @@ fn cleanup_because_exception() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn list_range() {
|
||||
assert_evals_to!(
|
||||
"List.range 0 -1",
|
||||
|
@ -2804,7 +2804,7 @@ fn list_walk_until() {
|
||||
satisfyA = \_ -> []
|
||||
|
||||
oneOfResult =
|
||||
List.walkUntil [satisfyA] [] \_, _ -> Stop []
|
||||
List.walkUntil [satisfyA] [] \_, _ -> Break []
|
||||
|
||||
main =
|
||||
when oneOfResult is
|
||||
@ -3004,10 +3004,10 @@ fn do_pass_bool_byte_closure_layout() {
|
||||
\input ->
|
||||
walker = \accum, (Pair u rest) ->
|
||||
if predicate u then
|
||||
Stop [Pair u rest]
|
||||
Break [Pair u rest]
|
||||
|
||||
else
|
||||
Stop accum
|
||||
Break accum
|
||||
|
||||
List.walkUntil (any input) [] walker
|
||||
|
||||
@ -3019,7 +3019,7 @@ fn do_pass_bool_byte_closure_layout() {
|
||||
walker = \accum, p ->
|
||||
output = p input
|
||||
if List.len output == 1 then
|
||||
Stop output
|
||||
Break output
|
||||
|
||||
else
|
||||
Continue accum
|
||||
|
@ -1,6 +1,6 @@
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.164 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.164;
|
||||
let List.239 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.239;
|
||||
|
||||
procedure Test.1 (Test.5):
|
||||
let Test.2 : I64 = 41i64;
|
||||
|
@ -1,22 +1,22 @@
|
||||
procedure List.2 (List.67, List.68):
|
||||
let List.170 : U64 = CallByName List.6 List.67;
|
||||
let List.166 : Int1 = CallByName Num.22 List.68 List.170;
|
||||
if List.166 then
|
||||
let List.168 : {} = CallByName List.60 List.67 List.68;
|
||||
let List.167 : [C {}, C {}] = Ok List.168;
|
||||
ret List.167;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.245 : U64 = CallByName List.6 List.72;
|
||||
let List.241 : Int1 = CallByName Num.22 List.73 List.245;
|
||||
if List.241 then
|
||||
let List.243 : {} = CallByName List.60 List.72 List.73;
|
||||
let List.242 : [C {}, C {}] = Ok List.243;
|
||||
ret List.242;
|
||||
else
|
||||
let List.165 : {} = Struct {};
|
||||
let List.164 : [C {}, C {}] = Err List.165;
|
||||
ret List.164;
|
||||
let List.240 : {} = Struct {};
|
||||
let List.239 : [C {}, C {}] = Err List.240;
|
||||
ret List.239;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.173 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.173;
|
||||
let List.248 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.248;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.172 : {} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.172;
|
||||
let List.247 : {} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.247;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -1,6 +1,6 @@
|
||||
procedure List.4 (#Attr.2, #Attr.3):
|
||||
let List.164 : List U8 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||
ret List.164;
|
||||
let List.239 : List U8 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||
ret List.239;
|
||||
|
||||
procedure Test.20 (Test.22):
|
||||
let Test.34 : {U8} = Struct {Test.22};
|
||||
|
@ -1,6 +1,6 @@
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.164 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.164;
|
||||
let List.239 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.239;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.275 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
|
@ -1,16 +1,41 @@
|
||||
procedure List.9 (#Attr.2):
|
||||
let List.170 : U64 = 0i64;
|
||||
let List.171 : U64 = lowlevel ListLen #Attr.2;
|
||||
let List.166 : Int1 = lowlevel NotEq List.170 List.171;
|
||||
if List.166 then
|
||||
let List.169 : U64 = 0i64;
|
||||
let List.168 : I64 = lowlevel ListGetUnsafe #Attr.2 List.169;
|
||||
let List.167 : [C Int1, C I64] = Ok List.168;
|
||||
ret List.167;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.254 : U64 = CallByName List.6 List.72;
|
||||
let List.250 : Int1 = CallByName Num.22 List.73 List.254;
|
||||
if List.250 then
|
||||
let List.252 : I64 = CallByName List.60 List.72 List.73;
|
||||
let List.251 : [C {}, C I64] = Ok List.252;
|
||||
ret List.251;
|
||||
else
|
||||
let List.165 : Int1 = true;
|
||||
let List.164 : [C Int1, C I64] = Err List.165;
|
||||
ret List.164;
|
||||
let List.249 : {} = Struct {};
|
||||
let List.248 : [C {}, C I64] = Err List.249;
|
||||
ret List.248;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.255 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.255;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.253 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.253;
|
||||
|
||||
procedure List.9 (List.166):
|
||||
let List.246 : U64 = 0i64;
|
||||
let List.239 : [C {}, C I64] = CallByName List.2 List.166 List.246;
|
||||
let List.243 : U8 = 1i64;
|
||||
let List.244 : U8 = GetTagId List.239;
|
||||
let List.245 : Int1 = lowlevel Eq List.243 List.244;
|
||||
if List.245 then
|
||||
let List.167 : I64 = UnionAtIndex (Id 1) (Index 0) List.239;
|
||||
let List.240 : [C Int1, C I64] = Ok List.167;
|
||||
ret List.240;
|
||||
else
|
||||
let List.242 : Int1 = true;
|
||||
let List.241 : [C Int1, C I64] = Err List.242;
|
||||
ret List.241;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
ret Num.273;
|
||||
|
||||
procedure Str.27 (#Attr.2):
|
||||
let #Attr.3 : {I64, U8} = lowlevel StrToNum #Attr.2;
|
||||
|
@ -1,6 +1,6 @@
|
||||
procedure List.4 (#Attr.2, #Attr.3):
|
||||
let List.164 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||
ret List.164;
|
||||
let List.239 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||
ret List.239;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.2 : List I64 = Array [1i64];
|
||||
|
@ -1,6 +1,6 @@
|
||||
procedure List.4 (#Attr.2, #Attr.3):
|
||||
let List.164 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||
ret List.164;
|
||||
let List.239 : List I64 = lowlevel ListAppend #Attr.2 #Attr.3;
|
||||
ret List.239;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
let Test.6 : I64 = 42i64;
|
||||
|
@ -1,10 +1,10 @@
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.164 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.164;
|
||||
let List.239 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.239;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.165 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.165;
|
||||
let List.240 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.240;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.273 : U64 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
|
@ -1,26 +1,26 @@
|
||||
procedure List.2 (List.67, List.68):
|
||||
let List.170 : U64 = CallByName List.6 List.67;
|
||||
let List.166 : Int1 = CallByName Num.22 List.68 List.170;
|
||||
if List.166 then
|
||||
let List.168 : Str = CallByName List.60 List.67 List.68;
|
||||
let List.167 : [C {}, C Str] = Ok List.168;
|
||||
ret List.167;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.245 : U64 = CallByName List.6 List.72;
|
||||
let List.241 : Int1 = CallByName Num.22 List.73 List.245;
|
||||
if List.241 then
|
||||
let List.243 : Str = CallByName List.60 List.72 List.73;
|
||||
let List.242 : [C {}, C Str] = Ok List.243;
|
||||
ret List.242;
|
||||
else
|
||||
let List.165 : {} = Struct {};
|
||||
let List.164 : [C {}, C Str] = Err List.165;
|
||||
ret List.164;
|
||||
let List.240 : {} = Struct {};
|
||||
let List.239 : [C {}, C Str] = Err List.240;
|
||||
ret List.239;
|
||||
|
||||
procedure List.5 (#Attr.2, #Attr.3):
|
||||
let List.172 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
||||
ret List.172;
|
||||
let List.247 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
||||
ret List.247;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.174 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.174;
|
||||
let List.249 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.249;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.173 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.173;
|
||||
let List.248 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.248;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -1,28 +1,28 @@
|
||||
procedure List.2 (List.67, List.68):
|
||||
let List.170 : U64 = CallByName List.6 List.67;
|
||||
let List.166 : Int1 = CallByName Num.22 List.68 List.170;
|
||||
if List.166 then
|
||||
let List.168 : Str = CallByName List.60 List.67 List.68;
|
||||
let List.167 : [C {}, C Str] = Ok List.168;
|
||||
ret List.167;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.245 : U64 = CallByName List.6 List.72;
|
||||
let List.241 : Int1 = CallByName Num.22 List.73 List.245;
|
||||
if List.241 then
|
||||
let List.243 : Str = CallByName List.60 List.72 List.73;
|
||||
let List.242 : [C {}, C Str] = Ok List.243;
|
||||
ret List.242;
|
||||
else
|
||||
let List.165 : {} = Struct {};
|
||||
let List.164 : [C {}, C Str] = Err List.165;
|
||||
ret List.164;
|
||||
let List.240 : {} = Struct {};
|
||||
let List.239 : [C {}, C Str] = Err List.240;
|
||||
ret List.239;
|
||||
|
||||
procedure List.5 (#Attr.2, #Attr.3):
|
||||
inc #Attr.2;
|
||||
let List.172 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
||||
let List.247 : List Str = lowlevel ListMap { xs: `#Attr.#arg1` } #Attr.2 Test.3 #Attr.3;
|
||||
decref #Attr.2;
|
||||
ret List.172;
|
||||
ret List.247;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.174 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.174;
|
||||
let List.249 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.249;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.173 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.173;
|
||||
let List.248 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.248;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.273 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -1,16 +1,16 @@
|
||||
procedure List.28 (#Attr.2, #Attr.3):
|
||||
let List.167 : List I64 = lowlevel ListSortWith { xs: `#Attr.#arg1` } #Attr.2 Num.46 #Attr.3;
|
||||
let List.242 : List I64 = lowlevel ListSortWith { xs: `#Attr.#arg1` } #Attr.2 Num.46 #Attr.3;
|
||||
let Bool.14 : Int1 = lowlevel ListIsUnique #Attr.2;
|
||||
if Bool.14 then
|
||||
ret List.167;
|
||||
ret List.242;
|
||||
else
|
||||
decref #Attr.2;
|
||||
ret List.167;
|
||||
ret List.242;
|
||||
|
||||
procedure List.54 (List.111):
|
||||
let List.165 : {} = Struct {};
|
||||
let List.164 : List I64 = CallByName List.28 List.111 List.165;
|
||||
ret List.164;
|
||||
procedure List.54 (List.160):
|
||||
let List.240 : {} = Struct {};
|
||||
let List.239 : List I64 = CallByName List.28 List.160 List.240;
|
||||
ret List.239;
|
||||
|
||||
procedure Num.46 (#Attr.2, #Attr.3):
|
||||
let Num.273 : U8 = lowlevel NumCompare #Attr.2 #Attr.3;
|
||||
|
@ -1,43 +1,43 @@
|
||||
procedure List.2 (List.67, List.68):
|
||||
let List.184 : U64 = CallByName List.6 List.67;
|
||||
let List.180 : Int1 = CallByName Num.22 List.68 List.184;
|
||||
if List.180 then
|
||||
let List.182 : I64 = CallByName List.60 List.67 List.68;
|
||||
let List.181 : [C {}, C I64] = Ok List.182;
|
||||
ret List.181;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.259 : U64 = CallByName List.6 List.72;
|
||||
let List.255 : Int1 = CallByName Num.22 List.73 List.259;
|
||||
if List.255 then
|
||||
let List.257 : I64 = CallByName List.60 List.72 List.73;
|
||||
let List.256 : [C {}, C I64] = Ok List.257;
|
||||
ret List.256;
|
||||
else
|
||||
let List.179 : {} = Struct {};
|
||||
let List.178 : [C {}, C I64] = Err List.179;
|
||||
ret List.178;
|
||||
let List.254 : {} = Struct {};
|
||||
let List.253 : [C {}, C I64] = Err List.254;
|
||||
ret List.253;
|
||||
|
||||
procedure List.3 (List.76, List.77, List.78):
|
||||
let List.168 : {List I64, I64} = CallByName List.57 List.76 List.77 List.78;
|
||||
let List.167 : List I64 = StructAtIndex 0 List.168;
|
||||
inc List.167;
|
||||
dec List.168;
|
||||
ret List.167;
|
||||
procedure List.3 (List.81, List.82, List.83):
|
||||
let List.243 : {List I64, I64} = CallByName List.57 List.81 List.82 List.83;
|
||||
let List.242 : List I64 = StructAtIndex 0 List.243;
|
||||
inc List.242;
|
||||
dec List.243;
|
||||
ret List.242;
|
||||
|
||||
procedure List.57 (List.73, List.74, List.75):
|
||||
let List.190 : U64 = CallByName List.6 List.73;
|
||||
let List.187 : Int1 = CallByName Num.22 List.74 List.190;
|
||||
if List.187 then
|
||||
let List.188 : {List I64, I64} = CallByName List.61 List.73 List.74 List.75;
|
||||
ret List.188;
|
||||
procedure List.57 (List.78, List.79, List.80):
|
||||
let List.265 : U64 = CallByName List.6 List.78;
|
||||
let List.262 : Int1 = CallByName Num.22 List.79 List.265;
|
||||
if List.262 then
|
||||
let List.263 : {List I64, I64} = CallByName List.61 List.78 List.79 List.80;
|
||||
ret List.263;
|
||||
else
|
||||
let List.186 : {List I64, I64} = Struct {List.73, List.75};
|
||||
ret List.186;
|
||||
let List.261 : {List I64, I64} = Struct {List.78, List.80};
|
||||
ret List.261;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.191 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.191;
|
||||
let List.266 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.266;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.192 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.192;
|
||||
let List.267 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.267;
|
||||
|
||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let List.189 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.189;
|
||||
let List.264 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.264;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -1,43 +1,43 @@
|
||||
procedure List.2 (List.67, List.68):
|
||||
let List.184 : U64 = CallByName List.6 List.67;
|
||||
let List.180 : Int1 = CallByName Num.22 List.68 List.184;
|
||||
if List.180 then
|
||||
let List.182 : I64 = CallByName List.60 List.67 List.68;
|
||||
let List.181 : [C {}, C I64] = Ok List.182;
|
||||
ret List.181;
|
||||
procedure List.2 (List.72, List.73):
|
||||
let List.259 : U64 = CallByName List.6 List.72;
|
||||
let List.255 : Int1 = CallByName Num.22 List.73 List.259;
|
||||
if List.255 then
|
||||
let List.257 : I64 = CallByName List.60 List.72 List.73;
|
||||
let List.256 : [C {}, C I64] = Ok List.257;
|
||||
ret List.256;
|
||||
else
|
||||
let List.179 : {} = Struct {};
|
||||
let List.178 : [C {}, C I64] = Err List.179;
|
||||
ret List.178;
|
||||
let List.254 : {} = Struct {};
|
||||
let List.253 : [C {}, C I64] = Err List.254;
|
||||
ret List.253;
|
||||
|
||||
procedure List.3 (List.76, List.77, List.78):
|
||||
let List.168 : {List I64, I64} = CallByName List.57 List.76 List.77 List.78;
|
||||
let List.167 : List I64 = StructAtIndex 0 List.168;
|
||||
inc List.167;
|
||||
dec List.168;
|
||||
ret List.167;
|
||||
procedure List.3 (List.81, List.82, List.83):
|
||||
let List.243 : {List I64, I64} = CallByName List.57 List.81 List.82 List.83;
|
||||
let List.242 : List I64 = StructAtIndex 0 List.243;
|
||||
inc List.242;
|
||||
dec List.243;
|
||||
ret List.242;
|
||||
|
||||
procedure List.57 (List.73, List.74, List.75):
|
||||
let List.190 : U64 = CallByName List.6 List.73;
|
||||
let List.187 : Int1 = CallByName Num.22 List.74 List.190;
|
||||
if List.187 then
|
||||
let List.188 : {List I64, I64} = CallByName List.61 List.73 List.74 List.75;
|
||||
ret List.188;
|
||||
procedure List.57 (List.78, List.79, List.80):
|
||||
let List.265 : U64 = CallByName List.6 List.78;
|
||||
let List.262 : Int1 = CallByName Num.22 List.79 List.265;
|
||||
if List.262 then
|
||||
let List.263 : {List I64, I64} = CallByName List.61 List.78 List.79 List.80;
|
||||
ret List.263;
|
||||
else
|
||||
let List.186 : {List I64, I64} = Struct {List.73, List.75};
|
||||
ret List.186;
|
||||
let List.261 : {List I64, I64} = Struct {List.78, List.80};
|
||||
ret List.261;
|
||||
|
||||
procedure List.6 (#Attr.2):
|
||||
let List.191 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.191;
|
||||
let List.266 : U64 = lowlevel ListLen #Attr.2;
|
||||
ret List.266;
|
||||
|
||||
procedure List.60 (#Attr.2, #Attr.3):
|
||||
let List.192 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.192;
|
||||
let List.267 : I64 = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
|
||||
ret List.267;
|
||||
|
||||
procedure List.61 (#Attr.2, #Attr.3, #Attr.4):
|
||||
let List.189 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.189;
|
||||
let List.264 : {List I64, I64} = lowlevel ListReplaceUnsafe #Attr.2 #Attr.3 #Attr.4;
|
||||
ret List.264;
|
||||
|
||||
procedure Num.22 (#Attr.2, #Attr.3):
|
||||
let Num.275 : Int1 = lowlevel NumLt #Attr.2 #Attr.3;
|
||||
|
@ -465,8 +465,8 @@ mod test_reporting {
|
||||
|
||||
List.isEmpty
|
||||
List.set
|
||||
List.iterate
|
||||
List.get
|
||||
List.keepIf
|
||||
"#
|
||||
),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user