mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
work on dicts
This commit is contained in:
parent
d01d539d6b
commit
f3199ed2a7
5 changed files with 150 additions and 77 deletions
|
@ -414,8 +414,11 @@ const HashFn = fn (u64, ?[*]u8) callconv(.C) u64;
|
|||
const EqFn = fn (?[*]u8, ?[*]u8) callconv(.C) bool;
|
||||
|
||||
const Inc = fn (?[*]u8) callconv(.C) void;
|
||||
const IncN = fn (?[*]u8, usize) callconv(.C) void;
|
||||
const Dec = fn (?[*]u8) callconv(.C) void;
|
||||
|
||||
const Caller3 = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
|
||||
// Dict.insert : Dict k v, k, v -> Dict k v
|
||||
pub fn dictInsert(input: RocDict, alignment: Alignment, key: Opaque, key_width: usize, value: Opaque, value_width: usize, hash_fn: HashFn, is_eq: EqFn, dec_key: Dec, dec_value: Dec, output: *RocDict) callconv(.C) void {
|
||||
var seed: u64 = INITIAL_SEED;
|
||||
|
@ -759,14 +762,31 @@ pub fn setFromList(list: RocList, alignment: Alignment, key_width: usize, value_
|
|||
decref(std.heap.c_allocator, alignment, list.bytes, data_bytes);
|
||||
}
|
||||
|
||||
const StepperCaller = fn (?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8, ?[*]u8) callconv(.C) void;
|
||||
pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, accum: Opaque, alignment: Alignment, key_width: usize, value_width: usize, accum_width: usize, inc_key: Inc, inc_value: Inc, output: Opaque) callconv(.C) void {
|
||||
pub fn dictWalk(
|
||||
dict: RocDict,
|
||||
caller: Caller3,
|
||||
data: Opaque,
|
||||
inc_n_data: IncN,
|
||||
data_is_owned: bool,
|
||||
accum: Opaque,
|
||||
alignment: Alignment,
|
||||
key_width: usize,
|
||||
value_width: usize,
|
||||
accum_width: usize,
|
||||
inc_key: Inc,
|
||||
inc_value: Inc,
|
||||
output: Opaque,
|
||||
) callconv(.C) void {
|
||||
// allocate space to write the result of the stepper into
|
||||
// experimentally aliasing the accum and output pointers is not a good idea
|
||||
const alloc: [*]u8 = @ptrCast([*]u8, std.heap.c_allocator.alloc(u8, accum_width) catch unreachable);
|
||||
var b1 = output orelse unreachable;
|
||||
var b2 = alloc;
|
||||
|
||||
if (data_is_owned) {
|
||||
inc_n_data(data, dict.len());
|
||||
}
|
||||
|
||||
@memcpy(b2, accum orelse unreachable, accum_width);
|
||||
|
||||
var i: usize = 0;
|
||||
|
@ -777,7 +797,7 @@ pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, a
|
|||
const key = dict.getKey(i, alignment, key_width, value_width);
|
||||
const value = dict.getValue(i, alignment, key_width, value_width);
|
||||
|
||||
stepper_caller(stepper, key, value, b2, b1);
|
||||
caller(data, key, value, b2, b1);
|
||||
|
||||
const temp = b1;
|
||||
b2 = b1;
|
||||
|
@ -789,7 +809,4 @@ pub fn dictWalk(dict: RocDict, stepper: Opaque, stepper_caller: StepperCaller, a
|
|||
|
||||
@memcpy(output orelse unreachable, b2, accum_width);
|
||||
std.heap.c_allocator.free(alloc[0..accum_width]);
|
||||
|
||||
const data_bytes = dict.capacity() * slotSize(key_width, value_width);
|
||||
decref(std.heap.c_allocator, alignment, dict.dict_bytes, data_bytes);
|
||||
}
|
||||
|
|
|
@ -516,7 +516,18 @@ pub fn listKeepResult(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn listWalk(list: RocList, stepper: Opaque, stepper_caller: Caller2, accum: Opaque, alignment: usize, element_width: usize, accum_width: usize, output: Opaque) callconv(.C) void {
|
||||
pub fn listWalk(
|
||||
list: RocList,
|
||||
caller: Caller2,
|
||||
data: Opaque,
|
||||
inc_n_data: IncN,
|
||||
data_is_owned: bool,
|
||||
accum: Opaque,
|
||||
alignment: usize,
|
||||
element_width: usize,
|
||||
accum_width: usize,
|
||||
output: Opaque,
|
||||
) callconv(.C) void {
|
||||
if (accum_width == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -526,6 +537,10 @@ pub fn listWalk(list: RocList, stepper: Opaque, stepper_caller: Caller2, accum:
|
|||
return;
|
||||
}
|
||||
|
||||
if (data_is_owned) {
|
||||
inc_n_data(data, list.len());
|
||||
}
|
||||
|
||||
const alloc: [*]u8 = @ptrCast([*]u8, std.heap.c_allocator.alloc(u8, accum_width) catch unreachable);
|
||||
var b1 = output orelse unreachable;
|
||||
var b2 = alloc;
|
||||
|
@ -537,7 +552,7 @@ pub fn listWalk(list: RocList, stepper: Opaque, stepper_caller: Caller2, accum:
|
|||
const size = list.len();
|
||||
while (i < size) : (i += 1) {
|
||||
const element = source_ptr + i * element_width;
|
||||
stepper_caller(stepper, element, b2, b1);
|
||||
caller(data, element, b2, b1);
|
||||
|
||||
const temp = b1;
|
||||
b2 = b1;
|
||||
|
@ -547,12 +562,20 @@ pub fn listWalk(list: RocList, stepper: Opaque, stepper_caller: Caller2, accum:
|
|||
|
||||
@memcpy(output orelse unreachable, b2, accum_width);
|
||||
std.heap.c_allocator.free(alloc[0..accum_width]);
|
||||
|
||||
const data_bytes = list.len() * element_width;
|
||||
utils.decref(std.heap.c_allocator, alignment, list.bytes, data_bytes);
|
||||
}
|
||||
|
||||
pub fn listWalkBackwards(list: RocList, stepper: Opaque, stepper_caller: Caller2, accum: Opaque, alignment: usize, element_width: usize, accum_width: usize, output: Opaque) callconv(.C) void {
|
||||
pub fn listWalkBackwards(
|
||||
list: RocList,
|
||||
caller: Caller2,
|
||||
data: Opaque,
|
||||
inc_n_data: IncN,
|
||||
data_is_owned: bool,
|
||||
accum: Opaque,
|
||||
alignment: usize,
|
||||
element_width: usize,
|
||||
accum_width: usize,
|
||||
output: Opaque,
|
||||
) callconv(.C) void {
|
||||
if (accum_width == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -562,6 +585,10 @@ pub fn listWalkBackwards(list: RocList, stepper: Opaque, stepper_caller: Caller2
|
|||
return;
|
||||
}
|
||||
|
||||
if (data_is_owned) {
|
||||
inc_n_data(data, list.len());
|
||||
}
|
||||
|
||||
const alloc: [*]u8 = @ptrCast([*]u8, std.heap.c_allocator.alloc(u8, accum_width) catch unreachable);
|
||||
var b1 = output orelse unreachable;
|
||||
var b2 = alloc;
|
||||
|
@ -574,7 +601,7 @@ pub fn listWalkBackwards(list: RocList, stepper: Opaque, stepper_caller: Caller2
|
|||
while (i > 0) {
|
||||
i -= 1;
|
||||
const element = source_ptr + i * element_width;
|
||||
stepper_caller(stepper, element, b2, b1);
|
||||
caller(data, element, b2, b1);
|
||||
|
||||
const temp = b1;
|
||||
b2 = b1;
|
||||
|
@ -584,12 +611,21 @@ pub fn listWalkBackwards(list: RocList, stepper: Opaque, stepper_caller: Caller2
|
|||
|
||||
@memcpy(output orelse unreachable, b2, accum_width);
|
||||
std.heap.c_allocator.free(alloc[0..accum_width]);
|
||||
|
||||
const data_bytes = list.len() * element_width;
|
||||
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 {
|
||||
pub fn listWalkUntil(
|
||||
list: RocList,
|
||||
caller: Caller2,
|
||||
data: Opaque,
|
||||
inc_n_data: IncN,
|
||||
data_is_owned: bool,
|
||||
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;
|
||||
|
||||
|
@ -611,7 +647,12 @@ pub fn listWalkUntil(list: RocList, stepper: Opaque, stepper_caller: Caller2, ac
|
|||
const size = list.len();
|
||||
while (i < size) : (i += 1) {
|
||||
const element = source_ptr + i * element_width;
|
||||
stepper_caller(stepper, element, alloc + TAG_WIDTH, alloc);
|
||||
|
||||
if (data_is_owned) {
|
||||
inc_n_data(data, 1);
|
||||
}
|
||||
|
||||
caller(data, element, alloc + TAG_WIDTH, alloc);
|
||||
|
||||
const usizes: [*]usize = @ptrCast([*]usize, @alignCast(8, alloc));
|
||||
if (usizes[0] != 0) {
|
||||
|
@ -627,9 +668,6 @@ pub fn listWalkUntil(list: RocList, stepper: Opaque, stepper_caller: Caller2, ac
|
|||
|
||||
@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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue