hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 23561b03f80b13786cb3b8d98e560b5fd0720ea6
parent 7b067d2f1fe4ec0c02766ea17206d57329681120
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu,  1 Apr 2021 12:05:43 -0400

slice: add []void functions

Diffstat:
Mrt/ensure.ha | 2+-
Mscripts/gen-stdlib | 5+++--
Aslice/void.ha | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mstdlib.mk | 10++++++----
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 \