mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
Merge remote-tracking branch 'origin/can-builtins-simplify' into list-range
This commit is contained in:
commit
f2c144f58c
55 changed files with 2303 additions and 1059 deletions
|
@ -4,6 +4,8 @@ const RocResult = utils.RocResult;
|
|||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
const TAG_WIDTH = 8;
|
||||
|
||||
const EqFn = fn (?[*]u8, ?[*]u8) callconv(.C) bool;
|
||||
const Opaque = ?[*]u8;
|
||||
|
||||
|
@ -502,6 +504,49 @@ pub fn listWalkBackwards(list: RocList, stepper: Opaque, stepper_caller: Caller2
|
|||
utils.decref(std.heap.c_allocator, alignment, list.bytes, data_bytes);
|
||||
}
|
||||
|
||||
pub fn listWalkUntil(list: RocList, stepper: Opaque, stepper_caller: Caller2, accum: Opaque, alignment: usize, element_width: usize, accum_width: usize, dec: Dec, output: Opaque) callconv(.C) void {
|
||||
// [ Continue a, Stop a ]
|
||||
const CONTINUE: usize = 0;
|
||||
|
||||
if (accum_width == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (list.isEmpty()) {
|
||||
@memcpy(output orelse unreachable, accum orelse unreachable, accum_width);
|
||||
return;
|
||||
}
|
||||
|
||||
const alloc: [*]u8 = @ptrCast([*]u8, std.heap.c_allocator.alloc(u8, TAG_WIDTH + accum_width) catch unreachable);
|
||||
|
||||
@memcpy(alloc + TAG_WIDTH, accum orelse unreachable, accum_width);
|
||||
|
||||
if (list.bytes) |source_ptr| {
|
||||
var i: usize = 0;
|
||||
const size = list.len();
|
||||
while (i < size) : (i += 1) {
|
||||
const element = source_ptr + i * element_width;
|
||||
stepper_caller(stepper, element, alloc + TAG_WIDTH, alloc);
|
||||
|
||||
const usizes: [*]usize = @ptrCast([*]usize, @alignCast(8, alloc));
|
||||
if (usizes[0] != 0) {
|
||||
// decrement refcount of the remaining items
|
||||
i += 1;
|
||||
while (i < size) : (i += 1) {
|
||||
dec(source_ptr + i * element_width);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@memcpy(output orelse unreachable, alloc + TAG_WIDTH, accum_width);
|
||||
std.heap.c_allocator.free(alloc[0 .. TAG_WIDTH + accum_width]);
|
||||
|
||||
const data_bytes = list.len() * element_width;
|
||||
utils.decref(std.heap.c_allocator, alignment, list.bytes, data_bytes);
|
||||
}
|
||||
|
||||
// List.contains : List k, k -> Bool
|
||||
pub fn listContains(list: RocList, key: Opaque, key_width: usize, is_eq: EqFn) callconv(.C) bool {
|
||||
if (list.bytes) |source_ptr| {
|
||||
|
|
|
@ -12,6 +12,7 @@ comptime {
|
|||
exportListFn(list.listMapWithIndex, "map_with_index");
|
||||
exportListFn(list.listKeepIf, "keep_if");
|
||||
exportListFn(list.listWalk, "walk");
|
||||
exportListFn(list.listWalkUntil, "walkUntil");
|
||||
exportListFn(list.listWalkBackwards, "walk_backwards");
|
||||
exportListFn(list.listKeepOks, "keep_oks");
|
||||
exportListFn(list.listKeepErrs, "keep_errs");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue