commit 23561b03f80b13786cb3b8d98e560b5fd0720ea6
parent 7b067d2f1fe4ec0c02766ea17206d57329681120
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 1 Apr 2021 12:05:43 -0400
slice: add []void functions
Diffstat:
4 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/rt/ensure.ha b/rt/ensure.ha
@@ -1,5 +1,5 @@
export type slice = struct {
- data: *void,
+ data: nullable *void,
length: size,
capacity: size,
};
diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib
@@ -454,8 +454,9 @@ gensrcs_strconv() {
slice() {
gen_srcs slice \
- reverse.ha
- gen_ssa slice
+ reverse.ha \
+ void.ha
+ gen_ssa slice types
}
gensrcs_sort() {
diff --git a/slice/void.ha b/slice/void.ha
@@ -0,0 +1,56 @@
+use rt;
+use types;
+
+// Appends an item, or items, to a slice, returning a new slice.
+export fn appendto(sl: *[]void, itemsz: size, items: const *void...) void = {
+ if (len(items) == 0) {
+ return;
+ };
+ let sl = sl: *types::slice;
+ let end = sl.length;
+ sl.length += len(items);
+ rt::ensure(sl, itemsz);
+ let data = sl.data: *[*]u8;
+ for (let i = 0z; i < len(items); i += 1) {
+ rt::memcpy(&data[(end + i) * itemsz], items[i], itemsz);
+ };
+};
+
+@test fn appendto() void = {
+ let input: []int = [];
+ let num = 1337;
+ appendto(&input: *[]void, size(int), &num, &num);
+ assert(len(input) == 2 && input[0] == 1337 && input[1] == 1337);
+ free(input);
+};
+
+// Swaps two elements of a slice.
+export fn swap(sl: []void, itemsz: size, a: size, b: size) void = {
+ assert(a < len(sl) && b < len(sl));
+ let sl = sl: *[*]u8;
+ let a = &sl[a * itemsz]: *[*]u8, b = &sl[b * itemsz]: *[*]u8;
+ for (let i = 0z; i < itemsz; i += 1) {
+ let c = a[i];
+ a[i] = b[i];
+ b[i] = c;
+ };
+};
+
+@test fn swap() void = {
+ let x: []int = [1, 2, 3];
+ swap(x: []void, size(int), 0, 2);
+ assert(x[0] == 3 && x[2] == 1);
+};
+
+// Returns a pointer to the nth item of a slice.
+export fn index(sl: []void, itemsz: size, n: size) *void = {
+ assert(n < len(sl));
+ let ba = sl: *[*]u8;
+ return &ba[n * itemsz];
+};
+
+@test fn index() void = {
+ let x: []int = [1, 2, 3];
+ let ptr = index(x, size(int), 1): *int;
+ assert(*ptr == 2);
+};
diff --git a/stdlib.mk b/stdlib.mk
@@ -601,9 +601,10 @@ $(HARECACHE)/path/path.ssa: $(stdlib_path_srcs) $(stdlib_rt) $(stdlib_strings) $
# slice
stdlib_slice_srcs= \
- $(STDLIB)/slice/reverse.ha
+ $(STDLIB)/slice/reverse.ha \
+ $(STDLIB)/slice/void.ha
-$(HARECACHE)/slice/slice.ssa: $(stdlib_slice_srcs) $(stdlib_rt)
+$(HARECACHE)/slice/slice.ssa: $(stdlib_slice_srcs) $(stdlib_rt) $(stdlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(HARECACHE)/slice
@HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nslice \
@@ -1344,9 +1345,10 @@ $(TESTCACHE)/path/path.ssa: $(testlib_path_srcs) $(testlib_rt) $(testlib_strings
# slice
testlib_slice_srcs= \
- $(STDLIB)/slice/reverse.ha
+ $(STDLIB)/slice/reverse.ha \
+ $(STDLIB)/slice/void.ha
-$(TESTCACHE)/slice/slice.ssa: $(testlib_slice_srcs) $(testlib_rt)
+$(TESTCACHE)/slice/slice.ssa: $(testlib_slice_srcs) $(testlib_rt) $(testlib_types)
@printf 'HAREC \t$@\n'
@mkdir -p $(TESTCACHE)/slice
@HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nslice \