add List.range

This commit is contained in:
Folkert 2021-03-29 23:00:49 +02:00
parent 4ce520fed6
commit d718e21fd3
11 changed files with 253 additions and 2 deletions

View file

@ -557,3 +557,89 @@ pub fn listAppend(list: RocList, alignment: usize, element: Opaque, element_widt
return output;
}
pub fn listRange(width: utils.IntWidth, low: Opaque, high: Opaque) callconv(.C) RocList {
const allocator = std.heap.c_allocator;
const IntWidth = utils.IntWidth;
switch (width) {
IntWidth.U8 => {
return helper1(allocator, u8, low, high);
},
IntWidth.U16 => {
return helper1(allocator, u16, low, high);
},
IntWidth.U32 => {
return helper1(allocator, u32, low, high);
},
IntWidth.U64 => {
return helper1(allocator, u64, low, high);
},
IntWidth.U128 => {
return helper1(allocator, u128, low, high);
},
IntWidth.I8 => {
return helper1(allocator, i8, low, high);
},
IntWidth.I16 => {
return helper1(allocator, i16, low, high);
},
IntWidth.I32 => {
return helper1(allocator, i32, low, high);
},
IntWidth.I64 => {
return helper1(allocator, i64, low, high);
},
IntWidth.I128 => {
return helper1(allocator, i128, low, high);
},
IntWidth.Usize => {
return helper1(allocator, usize, low, high);
},
}
}
fn helper1(allocator: *Allocator, 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(allocator, T, ptr1.*, ptr2.*);
}
fn listRangeHelp(allocator: *Allocator, 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(allocator, @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(allocator, @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;
},
}
}

View file

@ -18,6 +18,7 @@ comptime {
exportListFn(list.listContains, "contains");
exportListFn(list.listRepeat, "repeat");
exportListFn(list.listAppend, "append");
exportListFn(list.listRange, "range");
}
// Dict Module

View file

@ -4,6 +4,58 @@ const Allocator = std.mem.Allocator;
const REFCOUNT_ONE_ISIZE: comptime isize = std.math.minInt(isize);
pub const REFCOUNT_ONE: usize = @bitCast(usize, REFCOUNT_ONE_ISIZE);
pub const IntWidth = enum(u8) {
U8,
U16,
U32,
U64,
U128,
I8,
I16,
I32,
I64,
I128,
Usize,
};
pub fn intWidth(width: IntWidth) anytype {
switch (width) {
IntWidth.U8 => {
return u8;
},
IntWidth.U16 => {
return u16;
},
IntWidth.U32 => {
return u32;
},
IntWidth.U64 => {
return u64;
},
IntWidth.U128 => {
return u128;
},
IntWidth.I8 => {
return i8;
},
IntWidth.I16 => {
return i16;
},
IntWidth.I32 => {
return i32;
},
IntWidth.I64 => {
return i64;
},
IntWidth.I128 => {
return i128;
},
IntWidth.Usize => {
return usize;
},
}
}
pub fn decref(
allocator: *Allocator,
alignment: usize,