From c249c3f3b6aa537eb13255b544e1a84202aed2fb Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 4 Jul 2023 02:29:02 +0200 Subject: [PATCH] Fix of accidentally printing "prev" when using $checks. Updated binary search. --- lib/std/hash/sha1.c3 | 37 +++++++------- lib/std/sort/binarysearch.c3 | 69 ++++++++++++++------------- src/compiler/diagnostics.c | 1 + src/version.h | 2 +- test/unit/stdlib/sort/binarysearch.c3 | 14 +++++- 5 files changed, 70 insertions(+), 53 deletions(-) diff --git a/lib/std/hash/sha1.c3 b/lib/std/hash/sha1.c3 index cf3701730..1e5332d39 100644 --- a/lib/std/hash/sha1.c3 +++ b/lib/std/hash/sha1.c3 @@ -14,10 +14,10 @@ struct Sha1 char[64] buffer; } -fn void Sha1.init(Sha1* this) +fn void Sha1.init(&self) { // SHA1 initialization constants - *this = { + *self = { .state = { 0x67452301, 0xEFCDAB89, @@ -29,55 +29,54 @@ fn void Sha1.init(Sha1* this) } /** - * @param [&inout] this * @param [in] data * @require data.len <= uint.max **/ -fn void Sha1.update(Sha1* this, char[] data) +fn void Sha1.update(&self, char[] data) { - uint j = this.count[0]; + uint j = self.count[0]; uint len = data.len; - if ((this.count[0] += len << 3) < j) this.count[1]++; - this.count[1] += len >> 29; + if ((self.count[0] += len << 3) < j) self.count[1]++; + self.count[1] += len >> 29; j = (j >> 3) & 63; uint i; if (j + len > 63) { i = 64 - j; - this.buffer[j..] = data[:i]; - sha1_transform(&this.state, &this.buffer); + self.buffer[j..] = data[:i]; + sha1_transform(&self.state, &self.buffer); for (; i + 63 < len; i += 64) { - sha1_transform(&this.state, &data[i]); + sha1_transform(&self.state, &data[i]); } j = 0; } - this.buffer[j:len - i] = data[i..]; + self.buffer[j:len - i] = data[i..]; } -fn char[20] Sha1.final(Sha1* this) +fn char[20] Sha1.final(&self) { char[8] finalcount; for (uint i = 0; i < 8; i++) { - finalcount[i] = (char)((this.count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 0xFF); + finalcount[i] = (char)((self.count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 0xFF); } - this.update(char[] { 0o200 }); - while ((this.count[0] & 504) != 448) + self.update(char[] { 0o200 }); + while ((self.count[0] & 504) != 448) { - this.update(char[] { 0 }); + self.update(char[] { 0 }); } - this.update(&finalcount); + self.update(&finalcount); char[20] digest; for (uint i = 0; i < 20; i++) { - digest[i] = (char)((this.state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF); + digest[i] = (char)((self.state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF); } // Clear mem - mem::clear(this, Sha1.sizeof); + mem::clear(self, Sha1.sizeof); finalcount = {}; return digest; } diff --git a/lib/std/sort/binarysearch.c3 b/lib/std/sort/binarysearch.c3 index 734f1c747..0ffd93631 100644 --- a/lib/std/sort/binarysearch.c3 +++ b/lib/std/sort/binarysearch.c3 @@ -1,26 +1,25 @@ module std::sort::binarysearch; -/* - * Compare x and y and return one of the following values: - * -1 if x < y - * 0 if x == y - * 1 if x > y - */ -def Comparer = fn int (void *x, void *y); - /** * Perform a binary search over the sorted array and return the smallest index * in [0, array.len) where cmp(i) is true and cmp(j) is true for j in [i, array.len). - * @require is_array_or_subarray(array) "array must be an array or subarray" + * @require is_searchable(list) "The list must be indexable and support .len or .len()" + * @require is_comparer(cmp, list) "Expeced a comparison function which compares values" **/ -macro usz cmp_search(array, x, Comparer cmp) +macro usz cmp_search(list, x, cmp) { usz i; - for (usz j = array.len; i < j;) + usz len = @len_from_list(list); + for (usz j = len; i < j;) { usz half = (i + j) / 2; - int res = cmp(&array[half], &x); - switch { + $if $checks(cmp(list[0], list[0])): + int res = cmp(list[half], x); + $else + int res = cmp(&list[half], &x); + $endif + switch + { case res > 0: j = half; case res < 0: i = half + 1; default: return half; @@ -32,35 +31,41 @@ macro usz cmp_search(array, x, Comparer cmp) /** * Perform a binary search over the sorted array and return the index * in [0, array.len) where x would be inserted. - * @require is_array_or_subarray(array) "array must be an array or subarray" + * @require is_searchable(list) "The list must be indexable and support .len or .len()" + * @checked less(list[0], x) "The values must be comparable" **/ -macro usz search(array, x) +macro usz search(list, x) { usz i; - for (usz j = array.len; i < j;) + usz len = @len_from_list(list); + for (usz j = len; i < j;) { usz half = (i + j) / 2; switch { - case greater(array[half], x): j = half; - case less(array[half], x): i = half + 1; + case greater(list[half], x): j = half; + case less(list[half], x): i = half + 1; default: return half; } } return i; } -macro bool is_array_or_subarray(slice) @private +macro bool is_searchable(list) @local { - $switch ($typeof(slice).kindof) - $case POINTER: - var $Inner = $typefrom($typeof(bytes).inner); - $if $Inner.kindof == ARRAY: - return true; - $endif - $case ARRAY: - $case SUBARRAY: - return true; - $default: - return false; - $endswitch -} \ No newline at end of file + return $checks(list[0]) && ($checks(list.len) || $checks(list.len())); +} + +macro usz @len_from_list(&list) @local +{ + $if $checks(list.len()): + return list.len(); + $else + return list.len; + $endif +} + +macro bool is_comparer(cmp, list) +{ + return $checks(int i = cmp(list[0], list[0])) + || $checks(int i = cmp(&list[0], &list[0])); +} diff --git a/src/compiler/diagnostics.c b/src/compiler/diagnostics.c index f3118013a..21f9d7949 100644 --- a/src/compiler/diagnostics.c +++ b/src/compiler/diagnostics.c @@ -190,6 +190,7 @@ void sema_error_at_after(SourceSpan loc, const char *message, ...) void sema_error_prev_at(SourceSpan loc, const char *message, ...) { + if (global_context.suppress_errors) return; va_list args; va_start(args, message); #define MAX_ERROR_LEN 4096 diff --git a/src/version.h b/src/version.h index e3c1c0d7a..a3affb494 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.550" \ No newline at end of file +#define COMPILER_VERSION "0.4.551" \ No newline at end of file diff --git a/test/unit/stdlib/sort/binarysearch.c3 b/test/unit/stdlib/sort/binarysearch.c3 index c5deaeb9b..e5ac62313 100644 --- a/test/unit/stdlib/sort/binarysearch.c3 +++ b/test/unit/stdlib/sort/binarysearch.c3 @@ -27,11 +27,23 @@ fn void search() usz cmp_idx = binarysearch::cmp_search(tc.data, tc.x, &cmp_int); assert(cmp_idx == tc.index, "%s: got %d; want %d", tc.data, cmp_idx, tc.index); + + usz cmp_idx2 = binarysearch::cmp_search(tc.data, tc.x, &cmp_int2); + assert(cmp_idx2 == tc.index, "%s: got %d; want %d", tc.data, cmp_idx2, tc.index); + + usz cmp_idx3 = binarysearch::cmp_search(tc.data, tc.x, fn int(int a, int b) => a - b); + assert(cmp_idx3 == tc.index, "%s: got %d; want %d", tc.data, cmp_idx2, tc.index); } + } module binarysearch_test; fn int cmp_int(void* x, void* y) { return *(int*)x - *(int*)y; -} \ No newline at end of file +} + +fn int cmp_int2(int x, int y) { + return x - y; +} +