mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
WIP
This commit is contained in:
parent
5582644166
commit
3d7254726d
6 changed files with 104 additions and 56 deletions
|
@ -543,7 +543,14 @@ pub fn elementsRc(dict: RocDict, alignment: Alignment, key_width: usize, value_w
|
|||
}
|
||||
}
|
||||
|
||||
pub fn dictKeys(dict: RocDict, alignment: Alignment, key_width: usize, value_width: usize, inc_key: Inc, output: *RocList) callconv(.C) void {
|
||||
pub fn dictKeys(
|
||||
dict: RocDict,
|
||||
alignment: Alignment,
|
||||
key_width: usize,
|
||||
value_width: usize,
|
||||
inc_key: Inc,
|
||||
output: *RocList,
|
||||
) callconv(.C) void {
|
||||
const size = dict.capacity();
|
||||
|
||||
var length: usize = 0;
|
||||
|
@ -581,7 +588,7 @@ pub fn dictKeys(dict: RocDict, alignment: Alignment, key_width: usize, value_wid
|
|||
}
|
||||
}
|
||||
|
||||
output.* = RocList{ .bytes = ptr, .length = length };
|
||||
output.* = RocList{ .bytes = ptr, .length = length, .capacity = length };
|
||||
}
|
||||
|
||||
pub fn dictValues(dict: RocDict, alignment: Alignment, key_width: usize, value_width: usize, inc_value: Inc, output: *RocList) callconv(.C) void {
|
||||
|
@ -622,14 +629,25 @@ pub fn dictValues(dict: RocDict, alignment: Alignment, key_width: usize, value_w
|
|||
}
|
||||
}
|
||||
|
||||
output.* = RocList{ .bytes = ptr, .length = length };
|
||||
output.* = RocList{ .bytes = ptr, .length = length, .capacity = length };
|
||||
}
|
||||
|
||||
fn doNothing(_: Opaque) callconv(.C) void {
|
||||
return;
|
||||
}
|
||||
|
||||
pub fn dictUnion(dict1: RocDict, dict2: RocDict, alignment: Alignment, key_width: usize, value_width: usize, hash_fn: HashFn, is_eq: EqFn, inc_key: Inc, inc_value: Inc, output: *RocDict) callconv(.C) void {
|
||||
pub fn dictUnion(
|
||||
dict1: RocDict,
|
||||
dict2: RocDict,
|
||||
alignment: Alignment,
|
||||
key_width: usize,
|
||||
value_width: usize,
|
||||
hash_fn: HashFn,
|
||||
is_eq: EqFn,
|
||||
inc_key: Inc,
|
||||
inc_value: Inc,
|
||||
output: *RocDict,
|
||||
) callconv(.C) void {
|
||||
output.* = dict1.makeUnique(alignment, key_width, value_width);
|
||||
|
||||
var i: usize = 0;
|
||||
|
|
|
@ -16,6 +16,7 @@ const HasTagId = fn (u16, ?[*]u8) callconv(.C) extern struct { matched: bool, da
|
|||
pub const RocList = extern struct {
|
||||
bytes: ?[*]u8,
|
||||
length: usize,
|
||||
capacity: usize,
|
||||
|
||||
pub fn len(self: RocList) usize {
|
||||
return self.length;
|
||||
|
@ -26,7 +27,7 @@ pub const RocList = extern struct {
|
|||
}
|
||||
|
||||
pub fn empty() RocList {
|
||||
return RocList{ .bytes = null, .length = 0 };
|
||||
return RocList{ .bytes = null, .length = 0, .capacity = 0 };
|
||||
}
|
||||
|
||||
pub fn isUnique(self: RocList) bool {
|
||||
|
@ -50,6 +51,7 @@ pub const RocList = extern struct {
|
|||
return RocList{
|
||||
.bytes = utils.allocateWithRefcount(data_bytes, alignment),
|
||||
.length = length,
|
||||
.capacity = length,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -96,7 +98,7 @@ pub const RocList = extern struct {
|
|||
if (self.isUnique()) {
|
||||
const new_source = utils.unsafeReallocate(source_ptr, alignment, self.len(), new_length, element_width);
|
||||
|
||||
return RocList{ .bytes = new_source, .length = new_length };
|
||||
return RocList{ .bytes = new_source, .length = new_length, .capacity = new_length };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,6 +130,7 @@ pub const RocList = extern struct {
|
|||
const result = RocList{
|
||||
.bytes = first_slot,
|
||||
.length = new_length,
|
||||
.capacity = new_length,
|
||||
};
|
||||
|
||||
utils.decref(self.bytes, old_length * element_width, alignment);
|
||||
|
@ -1237,7 +1240,7 @@ pub fn listConcat(list_a: RocList, list_b: RocList, alignment: u32, element_widt
|
|||
@memcpy(new_source + list_a.len() * element_width, source_b, list_b.len() * element_width);
|
||||
}
|
||||
|
||||
return RocList{ .bytes = new_source, .length = total_length };
|
||||
return RocList{ .bytes = new_source, .length = total_length, .capacity = total_length };
|
||||
}
|
||||
}
|
||||
const total_length: usize = list_a.len() + list_b.len();
|
||||
|
|
|
@ -33,14 +33,17 @@ fn init_blank_small_string(comptime n: usize) [n]u8 {
|
|||
pub const RocStr = extern struct {
|
||||
str_bytes: ?[*]u8,
|
||||
str_len: usize,
|
||||
str_capacity: usize,
|
||||
|
||||
pub const alignment = @alignOf(usize);
|
||||
|
||||
pub inline fn empty() RocStr {
|
||||
const small_str_flag: isize = std.math.minInt(isize);
|
||||
const length = @bitCast(usize, small_str_flag);
|
||||
return RocStr{
|
||||
.str_len = @bitCast(usize, small_str_flag),
|
||||
.str_len = length,
|
||||
.str_bytes = null,
|
||||
.str_capacity = 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -59,6 +62,7 @@ pub const RocStr = extern struct {
|
|||
return RocStr{
|
||||
.str_bytes = first_element,
|
||||
.str_len = number_of_chars,
|
||||
.str_capacity = number_of_chars,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -218,7 +222,7 @@ pub const RocStr = extern struct {
|
|||
}
|
||||
|
||||
pub fn isEmpty(self: RocStr) bool {
|
||||
comptime const empty_len = RocStr.empty().str_len;
|
||||
const empty_len = RocStr.empty().str_len;
|
||||
return self.str_len == empty_len;
|
||||
}
|
||||
|
||||
|
@ -268,36 +272,6 @@ pub const RocStr = extern struct {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns (@sizeOf(RocStr) - 1) for small strings and the empty string.
|
||||
// Returns 0 for refcounted strings and immortal strings.
|
||||
// Returns the stored capacity value for all other strings.
|
||||
pub fn capacity(self: RocStr) usize {
|
||||
const length = self.len();
|
||||
const longest_small_str = @sizeOf(RocStr) - 1;
|
||||
|
||||
if (length <= longest_small_str) {
|
||||
// Note that although empty strings technically have the full
|
||||
// capacity of a small string available, they aren't marked as small
|
||||
// strings, so if you want to make use of that capacity, you need
|
||||
// to first change its flag to mark it as a small string!
|
||||
return longest_small_str;
|
||||
} else {
|
||||
const ptr: [*]usize = @ptrCast([*]usize, @alignCast(@alignOf(usize), self.str_bytes));
|
||||
const capacity_or_refcount: isize = (ptr - 1)[0];
|
||||
|
||||
if (capacity_or_refcount > 0) {
|
||||
// If capacity_or_refcount is positive, that means it's a
|
||||
// capacity value.
|
||||
return capacity_or_refcount;
|
||||
} else {
|
||||
// This is either a refcount or else this big string is stored
|
||||
// in a readonly section; either way, it has no capacity,
|
||||
// because we cannot mutate it in-place!
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn isUnique(self: RocStr) bool {
|
||||
// small strings can be copied
|
||||
if (self.isSmallStr()) {
|
||||
|
@ -1128,7 +1102,11 @@ fn strConcat(arg1: RocStr, arg2: RocStr) RocStr {
|
|||
|
||||
@memcpy(new_source + arg1.len(), arg2.asU8ptr(), arg2.len());
|
||||
|
||||
return RocStr{ .str_bytes = new_source, .str_len = combined_length };
|
||||
return RocStr{
|
||||
.str_bytes = new_source,
|
||||
.str_len = combined_length,
|
||||
.str_capacity = combined_length,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1264,9 +1242,9 @@ inline fn strToBytes(arg: RocStr) RocList {
|
|||
|
||||
@memcpy(ptr, arg.asU8ptr(), length);
|
||||
|
||||
return RocList{ .length = length, .bytes = ptr };
|
||||
return RocList{ .length = length, .bytes = ptr, .capacity = length };
|
||||
} else {
|
||||
return RocList{ .length = arg.len(), .bytes = arg.str_bytes };
|
||||
return RocList{ .length = arg.len(), .bytes = arg.str_bytes, .capacity = arg.str_capacity };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1308,7 +1286,11 @@ inline fn fromUtf8(arg: RocList, update_mode: UpdateMode) FromUtf8Result {
|
|||
} else {
|
||||
const byte_list = arg.makeUniqueExtra(RocStr.alignment, @sizeOf(u8), update_mode);
|
||||
|
||||
const string = RocStr{ .str_bytes = byte_list.bytes, .str_len = byte_list.length };
|
||||
const string = RocStr{
|
||||
.str_bytes = byte_list.bytes,
|
||||
.str_len = byte_list.length,
|
||||
.str_capacity = byte_list.capacity,
|
||||
};
|
||||
|
||||
return FromUtf8Result{
|
||||
.is_ok = true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue