commit e21766777dfbe21b88f913de04268419a5ee21bd
parent 3f685edba32354a9479a74cf7e7ae033bea037f7
Author: Bor Grošelj Simić <bor.groseljsimic@telemach.net>
Date: Wed, 24 Feb 2021 00:55:56 +0100
bytes/index.ha: add rindex
Diffstat:
1 file changed, 46 insertions(+), 0 deletions(-)
diff --git a/bytes/index.ha b/bytes/index.ha
@@ -24,6 +24,33 @@ fn index_slice(haystack: []u8, needle: []u8) (size | void) = {
};
+// Returns the offset of the last instance of 'needle' in a 'haystack' of
+// bytes, or void if it is not found.
+export fn rindex(haystack: []u8, needle: (u8 | []u8)) (size | void) = {
+ return match (needle) {
+ b: u8 => rindex_byte(haystack, b),
+ b: []u8 => rindex_slice(haystack, b),
+ };
+};
+
+fn rindex_byte(haystack: []u8, needle: u8) (size | void) = {
+ for (let i = 0z; i < len(haystack); i += 1) {
+ if (haystack[len(haystack) - i - 1] == needle) {
+ return len(haystack) - i - 1;
+ };
+ };
+};
+
+fn rindex_slice(haystack: []u8, needle: []u8) (size | void) = {
+ for (let i = 0z; i + len(needle) <= len(haystack); i += 1) {
+ let r = len(haystack) - i;
+ if (equal(haystack[r - len(needle)..r], needle)) {
+ return r - len(needle);
+ };
+ };
+};
+
+
@test fn index() void = {
// Bytes
const a: [4]u8 = [1, 3, 3, 7];
@@ -40,6 +67,20 @@ fn index_slice(haystack: []u8, needle: []u8) (size | void) = {
void => void,
};
+ match (rindex(a, 3)) {
+ n: size => assert(n == 2),
+ void => abort(),
+ };
+ match (rindex(a, 42)) {
+ n: size => abort(),
+ void => void,
+ };
+ match (rindex([], 42)) {
+ size => abort(),
+ void => void,
+ };
+
+
// Slices
match (index(a, [3, 3])) {
n: size => assert(n == 1),
@@ -59,4 +100,9 @@ fn index_slice(haystack: []u8, needle: []u8) (size | void) = {
n: size => assert(n == 1),
void => abort(),
};
+
+ match (rindex(special, [1, 1])) {
+ n: size => assert(n == 1),
+ void => abort(),
+ };
};