hare

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

commit c7b0a929f568b1feb8d43df4498dd9b32f98187c
parent 70d771de6bccb1866cf3936b8fd7e9cba42e616b
Author: Bor Grošelj Simić <bgs@turminal.net>
Date:   Fri, 22 Apr 2022 02:15:23 +0200

compare strings byte-by-byte

and rename strings::strcmp to strings::compare

Signed-off-by: Bor Grošelj Simić <bgs@turminal.net>

Diffstat:
Mcmd/haredoc/sort.ha | 2+-
Mfnmatch/fnmatch.ha | 2+-
Mglob/glob.ha | 2+-
Mhare/types/store.ha | 2+-
Mscripts/gen-stdlib | 2+-
Msort/types.ha | 2+-
Mstdlib.mk | 4++--
Astrings/compare.ha | 23+++++++++++++++++++++++
Dstrings/strcmp.ha | 38--------------------------------------
9 files changed, 31 insertions(+), 46 deletions(-)

diff --git a/cmd/haredoc/sort.ha b/cmd/haredoc/sort.ha @@ -98,7 +98,7 @@ fn decl_cmp(a: const *void, b: const *void) int = { return -1; }; const id_a = decl_ident(a), id_b = decl_ident(b); - return strings::strcmp(id_a[len(id_a) - 1], id_b[len(id_b) - 1]); + return strings::compare(id_a[len(id_a) - 1], id_b[len(id_b) - 1]); }; fn decl_ident(decl: ast::decl) ast::ident = { diff --git a/fnmatch/fnmatch.ha b/fnmatch/fnmatch.ha @@ -335,7 +335,7 @@ fn match_ctype(it: *strings::iterator, c: rune) (bool | errors::invalid) = { type funcmap = (str, *fn(c: rune) bool); fn cmp(a: const *void, b: const *void) int = - strings::strcmp((a: *funcmap).0, *(b: const *str)); + strings::compare((a: *funcmap).0, *(b: const *str)); fn ctype_name_to_func(name: str) nullable *fn(c: rune) bool = { const map: [_]funcmap = [ diff --git a/glob/glob.ha b/glob/glob.ha @@ -261,7 +261,7 @@ fn strstack_sort(ss: *strstack, pos: size) void = { }; fn bufcmp(a: const *void, b: const *void) int = - strings::strcmp( + strings::compare( strio::string(b: *strio::stream), strio::string(a: *strio::stream), ); diff --git a/hare/types/store.ha b/hare/types/store.ha @@ -516,7 +516,7 @@ fn tuple_from_ast( fn field_cmp(a: const *void, b: const *void) int = { const a = a: const *struct_field, b = b: *const struct_field; - return strings::strcmp(a.name, b.name); + return strings::compare(a.name, b.name); }; fn type_finish(t: *_type) void = { diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -1125,7 +1125,7 @@ strings() { utf8.ha \ index.ha \ trim.ha \ - strcmp.ha \ + compare.ha \ pad.ha \ replace.ha gen_ssa strings bytes encoding::utf8 types diff --git a/sort/types.ha b/sort/types.ha @@ -10,7 +10,7 @@ export type cmpfunc = fn(a: const *void, b: const *void) int; fn scmp(a: const *void, b: const *void) int = { const a = a: const *str, b = b: const *str; - return strings::strcmp(*a, *b); + return strings::compare(*a, *b); }; fn icmp(a: const *void, b: const *void) int = { diff --git a/stdlib.mk b/stdlib.mk @@ -1727,7 +1727,7 @@ stdlib_strings_any_srcs= \ $(STDLIB)/strings/utf8.ha \ $(STDLIB)/strings/index.ha \ $(STDLIB)/strings/trim.ha \ - $(STDLIB)/strings/strcmp.ha \ + $(STDLIB)/strings/compare.ha \ $(STDLIB)/strings/pad.ha \ $(STDLIB)/strings/replace.ha @@ -3766,7 +3766,7 @@ testlib_strings_any_srcs= \ $(STDLIB)/strings/utf8.ha \ $(STDLIB)/strings/index.ha \ $(STDLIB)/strings/trim.ha \ - $(STDLIB)/strings/strcmp.ha \ + $(STDLIB)/strings/compare.ha \ $(STDLIB)/strings/pad.ha \ $(STDLIB)/strings/replace.ha diff --git a/strings/compare.ha b/strings/compare.ha @@ -0,0 +1,23 @@ +// Compares two strings by their Unicode codepoint sort order. Zero is returned +// if the strings are equal, a negative value if a is less than b, or a positive +// value if a is greater than b. +export fn compare(a: str, b: str) int = { + let a = toutf8(a), b = toutf8(b); + let ln = if (len(a) < len(b)) (len(a), -1) else (len(b), 1); + for (let i = 0z; i < ln.0; i += 1) { + if (a[i] != b[i]) { + return a[i]: int - b[i]: int; + }; + }; + return if (len(a) == len(b)) 0 else ln.1; +}; + + +@test fn compare() void = { + assert(compare("ABC", "ABC") == 0); + assert(compare("ABC", "AB") > 0); + assert(compare("AB", "ABC") < 0); + assert(compare("BCD", "ABC") > 0); + assert(compare("ABC", "こんにちは") < 0); + assert(compare("ABC", "abc") < 0); +}; diff --git a/strings/strcmp.ha b/strings/strcmp.ha @@ -1,38 +0,0 @@ -// Compares two strings by their Unicode codepoint sort order. Zero is returned -// if the strings are equal, a negative value if a is less than b, or a positive -// value if a is greater than b. -export fn strcmp(a: str, b: str) int = { - let a = iter(a), b = iter(b); - for (true) { - let ra = match (next(&a)) { - case void => - match (next(&b)) { - case void => - return 0; - case rune => - return -1; - }; - case let r: rune => - yield r; - }; - let rb = match (next(&b)) { - case void => - return 1; - case let r: rune => - yield r; - }; - if (ra != rb) { - return ra: u32: int - rb: u32: int; - }; - }; - abort("unreachable"); -}; - -@test fn strcmp() void = { - assert(strcmp("ABC", "ABC") == 0); - assert(strcmp("ABC", "AB") > 0); - assert(strcmp("AB", "ABC") < 0); - assert(strcmp("BCD", "ABC") > 0); - assert(strcmp("ABC", "こんにちは") < 0); - assert(strcmp("ABC", "abc") < 0); -};