mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
WIP code for the basic methods on the Zig RocDict type (init, deinit, clone, allocate)
This commit is contained in:
parent
7a64ffede5
commit
7e63f72922
2 changed files with 99 additions and 8 deletions
|
@ -1,23 +1,111 @@
|
|||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
const expectEqual = testing.expectEqual;
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
const level_size = 32;
|
||||
|
||||
const InPlace = packed enum(u8) {
|
||||
InPlace,
|
||||
Clone,
|
||||
};
|
||||
|
||||
const Slot = packed enum(u8) {
|
||||
Empty,
|
||||
Filled,
|
||||
PreviouslyFilled,
|
||||
};
|
||||
|
||||
pub const RocDict = extern struct {
|
||||
dict_bytes: ?[*]u8,
|
||||
dict_len: usize,
|
||||
dict_slot_len: usize,
|
||||
dict_entries_len: usize,
|
||||
|
||||
pub fn init() RocDict {
|
||||
return RocDict{ .dict_len = 0, .dict_bytes = null };
|
||||
pub fn init(allocator: *Allocator, bytes_ptr: [*]const u8, number_of_slots: usize, number_of_entries: usize, key_size: usize, value_size: usize) RocDict {
|
||||
var result = RocDict.allocate(
|
||||
allocator,
|
||||
InPlace.Clone,
|
||||
number_of_slots,
|
||||
number_of_entries,
|
||||
key_size,
|
||||
value_size,
|
||||
);
|
||||
|
||||
@memcpy(result.asU8ptr(), bytes_ptr, number_of_slots);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn deinit(self: RocDict, allocator: *Allocator) void {
|
||||
const dict_bytes_ptr: [*]u8 = self.dict_bytes orelse unreachable;
|
||||
const dict_bytes: []u8 = dict_bytes_ptr[0..self.dict_slot_len];
|
||||
allocator.free(dict_bytes);
|
||||
}
|
||||
|
||||
pub fn allocate(
|
||||
allocator: *Allocator,
|
||||
result_in_place: InPlace,
|
||||
number_of_slots: usize,
|
||||
number_of_entries: usize,
|
||||
key_size: usize,
|
||||
value_size: usize,
|
||||
) RocDict {
|
||||
const slot_size = @sizeOf(Slot) + key_size + value_size;
|
||||
|
||||
const length = @sizeOf(usize) + (number_of_slots * slot_size);
|
||||
|
||||
var new_bytes: []usize = allocator.alloc(usize, length) catch unreachable;
|
||||
|
||||
if (result_in_place == InPlace.InPlace) {
|
||||
new_bytes[0] = @intCast(usize, number_of_slots);
|
||||
} else {
|
||||
const v: isize = std.math.minInt(isize);
|
||||
new_bytes[0] = @bitCast(usize, v);
|
||||
}
|
||||
|
||||
var first_slot = @ptrCast([*]align(@alignOf(usize)) u8, new_bytes);
|
||||
first_slot += @sizeOf(usize);
|
||||
|
||||
return RocDict{
|
||||
.dict_bytes = first_slot,
|
||||
.dict_slot_len = number_of_slots,
|
||||
.dict_entries_len = number_of_entries,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn asU8ptr(self: RocDict) [*]u8 {
|
||||
return @ptrCast([*]u8, self.dict_bytes);
|
||||
}
|
||||
|
||||
pub fn contains(self: RocDict, key_size: usize, key_ptr: *const c_void, hash_code: u64) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn len(self: RocDict) usize {
|
||||
return self.dict_entries_len;
|
||||
}
|
||||
|
||||
pub fn isEmpty(self: RocDict) bool {
|
||||
return self.len() == 0;
|
||||
}
|
||||
|
||||
pub fn clone(self: RocDict, allocator: *Allocator, in_place: InPlace, key_size: usize, value_size: usize) RocDict {
|
||||
var new_dict = RocDict.init(allocator, self.dict_slot_len, self.dict_entries_len, key_size, value_size);
|
||||
|
||||
var old_bytes: [*]u8 = @ptrCast([*]u8, self.dict_bytes);
|
||||
var new_bytes: [*]u8 = @ptrCast([*]u8, new_dict.dict_bytes);
|
||||
|
||||
@memcpy(new_bytes, old_bytes, self.dict_slot_len);
|
||||
|
||||
return new_dict;
|
||||
}
|
||||
// pub fn insert(self: RocDict, key_size: usize, key_ptr: *const c_void, value_ptr: *const c_void)
|
||||
};
|
||||
|
||||
// Dict.empty
|
||||
pub fn dictEmpty() callconv(.C) RocDict {
|
||||
return RocDict.init();
|
||||
pub fn dictEmpty(allocator: *Allocator, key_size: usize, value_size: usize) callconv(.C) RocDict {
|
||||
return RocDict.init(allocator, "", 0, 0, key_size, value_size);
|
||||
}
|
||||
|
||||
// Dict.len
|
||||
|
@ -26,7 +114,12 @@ pub fn dictLen(dict: RocDict) callconv(.C) usize {
|
|||
}
|
||||
|
||||
test "RocDict.init() contains nothing" {
|
||||
const dict = RocDict.init();
|
||||
const key_size = @sizeOf(usize);
|
||||
const value_size = @sizeOf(usize);
|
||||
|
||||
const dict = dictEmpty(testing.allocator, key_size, value_size);
|
||||
|
||||
expectEqual(false, dict.contains(4, @ptrCast(*const c_void, &""), 9));
|
||||
|
||||
dict.deinit(testing.allocator);
|
||||
}
|
||||
|
|
|
@ -40,8 +40,6 @@ pub const RocStr = extern struct {
|
|||
// This clones the pointed-to bytes if they won't fit in a
|
||||
// small string, and returns a (pointer, len) tuple which points to them.
|
||||
pub fn init(allocator: *Allocator, bytes_ptr: [*]const u8, length: usize) RocStr {
|
||||
const roc_str_size = @sizeOf(RocStr);
|
||||
|
||||
var result = RocStr.allocate(allocator, InPlace.Clone, length);
|
||||
@memcpy(result.asU8ptr(), bytes_ptr, length);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue