From d1349c9cfbd3dab6d84dc4d9e425482637fc301f Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Fri, 5 Sep 2025 18:41:41 +0200 Subject: [PATCH] Revert 0.7.6 code for 0.7.5 re-release --- lib/std/atomic_nolibc.c3 | 4 +- lib/std/collections/anylist.c3 | 548 ++++++++++++++++-- lib/std/collections/interfacelist.c3 | 539 ----------------- lib/std/core/allocators/dynamic_arena.c3 | 2 +- lib/std/core/allocators/tracking_allocator.c3 | 4 +- lib/std/core/array.c3 | 4 +- lib/std/core/builtin.c3 | 2 +- lib/std/core/types.c3 | 4 +- lib/std/crypto/ed25519.c3 | 10 +- lib/std/io/file_mmap.c3 | 2 +- lib/std/io/stream/bytebuffer.c3 | 4 +- lib/std/libc/libc.c3 | 2 +- lib/std/libc/os/posix.c3 | 2 +- lib/std/math/math.c3 | 4 +- lib/std/net/os/darwin.c3 | 4 +- lib/std/os/subprocess.c3 | 2 +- lib/std/os/win32/memoryapi.c3 | 2 +- lib/std/os/win32/types.c3 | 2 +- lib/std/sort/quicksort.c3 | 4 +- releasenotes.md | 29 +- resources/grammar/grammar.y | 98 ++-- resources/grammar/grammar_proposal.y | 8 +- src/build/build_options.c | 4 +- src/build/libraries.c | 2 +- src/build/project.c | 2 +- src/compiler/compiler.c | 3 +- src/compiler/compiler_internal.h | 42 +- src/compiler/copying.c | 8 - src/compiler/llvm_codegen.c | 2 +- src/compiler/llvm_codegen_expr.c | 2 +- src/compiler/llvm_codegen_stmt.c | 2 +- src/compiler/parse_expr.c | 4 +- src/compiler/parse_global.c | 6 +- src/compiler/parser_internal.h | 2 +- src/compiler/sema_asm.c | 12 +- src/compiler/sema_builtins.c | 2 +- src/compiler/sema_casts.c | 2 +- src/compiler/sema_const.c | 2 +- src/compiler/sema_decls.c | 20 +- src/compiler/sema_expr.c | 46 +- src/compiler/sema_stmts.c | 22 +- src/compiler/semantic_analyser.c | 11 - src/compiler_tests/tests.c | 226 ++++---- src/utils/lib.h | 2 +- src/utils/stringutils.c | 2 +- src/version.h | 4 +- test/src/test_suite_runner.c3 | 2 +- ...ray.c3 => cast_string_to_infered_array.c3} | 0 .../defined_subscript_assign.c3 | 14 - ...ck_implict_conversion_signed_unsigned.c3t} | 0 .../expressions/fail_index_usize.c3 | 2 +- ...ents.c3t => defered_default_arguments.c3t} | 0 test/test_suite/functions/slice_escape.c3 | 16 - .../test_suite/methods/subscript_set_error.c3 | 14 - .../{fallthrough_do.c3t => fallthough_do.c3t} | 0 test/test_suite/struct/member_expr.c3 | 4 +- test/test_suite/struct/struct_recursive.c3 | 4 +- .../switch/switch_in_defer_macro.c3t | 6 +- test/test_suite/variables/noinit_with_val.c3 | 10 - test/unit/stdlib/collections/anylist.c3 | 28 - test/unit/stdlib/collections/interfacelist.c3 | 126 ---- test/unit/stdlib/core/string.c3 | 4 +- test/unit/stdlib/libc/libc.c3 | 4 +- 63 files changed, 796 insertions(+), 1148 deletions(-) delete mode 100644 lib/std/collections/interfacelist.c3 rename test/test_suite/cast/{cast_string_to_inferred_array.c3 => cast_string_to_infered_array.c3} (100%) delete mode 100644 test/test_suite/compile_time_introspection/defined_subscript_assign.c3 rename test/test_suite/expressions/{check_implicit_conversion_signed_unsigned.c3t => check_implict_conversion_signed_unsigned.c3t} (100%) rename test/test_suite/functions/{deferred_default_arguments.c3t => defered_default_arguments.c3t} (100%) delete mode 100644 test/test_suite/functions/slice_escape.c3 delete mode 100644 test/test_suite/methods/subscript_set_error.c3 rename test/test_suite/statements/{fallthrough_do.c3t => fallthough_do.c3t} (100%) delete mode 100644 test/test_suite/variables/noinit_with_val.c3 delete mode 100644 test/unit/stdlib/collections/anylist.c3 delete mode 100644 test/unit/stdlib/collections/interfacelist.c3 diff --git a/lib/std/atomic_nolibc.c3 b/lib/std/atomic_nolibc.c3 index 5c0fde4ac..cdac3199e 100644 --- a/lib/std/atomic_nolibc.c3 +++ b/lib/std/atomic_nolibc.c3 @@ -58,7 +58,7 @@ fn CInt __atomic_compare_exchange(CInt size, any ptr, any expected, any desired, nextcase; $endif default: - unreachable("Unsupported size (%d) for atomic_compare_exchange", size); + unreachable("Unsuported size (%d) for atomic_compare_exchange", size); } return 0; -} +} \ No newline at end of file diff --git a/lib/std/collections/anylist.c3 b/lib/std/collections/anylist.c3 index f497cf59d..e929e07a6 100644 --- a/lib/std/collections/anylist.c3 +++ b/lib/std/collections/anylist.c3 @@ -2,10 +2,10 @@ // Use of self source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. module std::collections::anylist; -import std::collections::interfacelist; +import std::io,std::math; -alias AnyPredicate = InterfacePredicate {any}; -alias AnyTest = InterfaceTest {any}; +alias AnyPredicate = fn bool(any value); +alias AnyTest = fn bool(any type, any context); <* The AnyList contains a heterogenous set of types. Anything placed in the @@ -18,7 +18,282 @@ alias AnyTest = InterfaceTest {any}; If we're not doing pop, then things are easier, since we can just hand over the existing any. *> -typedef AnyList = inline InterfaceList {any}; +struct AnyList (Printable) +{ + usz size; + usz capacity; + Allocator allocator; + any* entries; +} + + +<* + Initialize the list. If not initialized then it will use the temp allocator + when something is pushed to it. + + @param [&inout] allocator : "The allocator to use" + @param initial_capacity : "The initial capacity to reserve, defaults to 16" +*> +fn AnyList* AnyList.init(&self, Allocator allocator, usz initial_capacity = 16) +{ + self.allocator = allocator; + self.size = 0; + if (initial_capacity > 0) + { + initial_capacity = math::next_power_of_2(initial_capacity); + self.entries = allocator::alloc_array(allocator, any, initial_capacity); + } + else + { + self.entries = null; + } + self.capacity = initial_capacity; + return self; +} + +<* + Initialize the list using the temp allocator. + + @param initial_capacity : "The initial capacity to reserve" +*> +fn AnyList* AnyList.tinit(&self, usz initial_capacity = 16) +{ + return self.init(tmem, initial_capacity) @inline; +} + +fn bool AnyList.is_initialized(&self) @inline => self.allocator != null; + +<* + Push an element on the list by cloning it. +*> +macro void AnyList.push(&self, element) +{ + if (!self.allocator) self.allocator = tmem; + self._append(allocator::clone(self.allocator, element)); +} + +<* + Free a retained element removed using *_retained. +*> +fn void AnyList.free_element(&self, any element) @inline +{ + allocator::free(self.allocator, element.ptr); +} + +<* + Pop a value who's type is known. If the type is incorrect, this + will still pop the element. + + @param $Type : "The type we assume the value has" + @return "The last value as the type given" + @return? TYPE_MISMATCH, NO_MORE_ELEMENT +*> +macro AnyList.pop(&self, $Type) +{ + if (!self.size) return NO_MORE_ELEMENT?; + defer self.free_element(self.entries[self.size]); + return *anycast(self.entries[--self.size], $Type); +} + +<* + Copy the last value, pop it and return the copy of it. + + @param [&inout] allocator : "The allocator to use for copying" + @return "A copy of the last value if it exists" + @return? NO_MORE_ELEMENT +*> +fn any? AnyList.copy_pop(&self, Allocator allocator) +{ + if (!self.size) return NO_MORE_ELEMENT?; + defer self.free_element(self.entries[self.size]); + return allocator::clone_any(allocator, self.entries[--self.size]); +} + + +<* + Copy the last value, pop it and return the copy of it. + + @return "A temp copy of the last value if it exists" + @return? NO_MORE_ELEMENT +*> +fn any? AnyList.tcopy_pop(&self) => self.copy_pop(tmem); + + +<* + Pop the last value. It must later be released using `list.free_element()`. + + @return "The last value if it exists" + @return? NO_MORE_ELEMENT +*> +fn any? AnyList.pop_retained(&self) +{ + if (!self.size) return NO_MORE_ELEMENT?; + return self.entries[--self.size]; +} + +<* + Remove all elements in the list. +*> +fn void AnyList.clear(&self) +{ + for (usz i = 0; i < self.size; i++) + { + self.free_element(self.entries[i]); + } + self.size = 0; +} + +<* + Pop a value who's type is known. If the type is incorrect, this + will still pop the element. + + @param $Type : "The type we assume the value has" + @return "The first value as the type given" + @return? TYPE_MISMATCH, NO_MORE_ELEMENT +*> +macro AnyList.pop_first(&self, $Type) +{ + if (!self.size) return NO_MORE_ELEMENT?; + defer self.remove_at(0); + return *anycast(self.entries[0], $Type); +} + +<* + Pop the first value. It must later be released using `list.free_element()`. + + @return "The first value if it exists" + @return? NO_MORE_ELEMENT +*> +fn any? AnyList.pop_first_retained(&self) +{ + if (!self.size) return NO_MORE_ELEMENT?; + defer self.remove_at(0); + return self.entries[0]; +} + + +<* + Copy the first value, pop it and return the copy of it. + + @param [&inout] allocator : "The allocator to use for copying" + @return "A copy of the first value if it exists" + @return? NO_MORE_ELEMENT +*> +fn any? AnyList.copy_pop_first(&self, Allocator allocator) +{ + if (!self.size) return NO_MORE_ELEMENT?; + defer self.free_element(self.entries[self.size]); + defer self.remove_at(0); + return allocator::clone_any(allocator, self.entries[0]); +} + +<* + Copy the first value, pop it and return the temp copy of it. + + @return "A temp copy of the first value if it exists" + @return? NO_MORE_ELEMENT +*> +fn any? AnyList.tcopy_pop_first(&self) => self.copy_pop_first(tmem); + +<* + Remove the element at the particular index. + + @param index : "The index of the element to remove" + @require index < self.size +*> +fn void AnyList.remove_at(&self, usz index) +{ + if (!--self.size || index == self.size) return; + self.free_element(self.entries[index]); + self.entries[index .. self.size - 1] = self.entries[index + 1 .. self.size]; +} + +<* + Add all the elements in another AnyList. + + @param [&in] other_list : "The list to add" +*> +fn void AnyList.add_all(&self, AnyList* other_list) +{ + if (!other_list.size) return; + self.reserve(other_list.size); + foreach (value : other_list) + { + self.entries[self.size++] = allocator::clone_any(self.allocator, value); + } +} + +<* + Reverse the order of the elements in the list. +*> +fn void AnyList.reverse(&self) +{ + if (self.size < 2) return; + usz half = self.size / 2U; + usz end = self.size - 1; + for (usz i = 0; i < half; i++) + { + self.swap(i, end - i); + } +} + +<* + Return a view of the data as a slice. + + @return "The slice view" +*> +fn any[] AnyList.array_view(&self) +{ + return self.entries[:self.size]; +} + +<* + Push an element to the front of the list. + + @param value : "The value to push to the list" +*> +macro void AnyList.push_front(&self, value) +{ + self.insert_at(0, value); +} + +<* + Insert an element at a particular index. + + @param index : "the index where the element should be inserted" + @param type : "the value to insert" + @require index <= self.size : "The index is out of bounds" +*> +macro void AnyList.insert_at(&self, usz index, type) +{ + if (index == self.size) + { + self.push(type); + return; + } + any value = allocator::copy(self.allocator, type); + self._insert_at(self, index, value); +} + +<* + Remove the last element in the list. The list may not be empty. + + @require self.size > 0 : "The list was already empty" +*> +fn void AnyList.remove_last(&self) +{ + self.free_element(self.entries[--self.size]); +} + +<* + Remove the first element in the list, the list may not be empty. + + @require self.size > 0 +*> +fn void AnyList.remove_first(&self) +{ + self.remove_at(0); +} <* Return the first element by value, assuming it is the given type. @@ -38,7 +313,10 @@ macro AnyList.first(&self, $Type) @return "The first element" @return? NO_MORE_ELEMENT *> -fn any? AnyList.first_any(&self) @inline => InterfaceList {any}.first(self); +fn any? AnyList.first_any(&self) @inline +{ + return self.size ? self.entries[0] : NO_MORE_ELEMENT?; +} <* Return the last element by value, assuming it is the given type. @@ -58,36 +336,29 @@ macro AnyList.last(&self, $Type) @return "The last element" @return? NO_MORE_ELEMENT *> -fn any? AnyList.last_any(&self) @inline => InterfaceList {any}.last(self); - -<* - Pop a value who's type is known. If the type is incorrect, this - will still pop the element. - - @param $Type : "The type we assume the value has" - @return "The last value as the type given" - @return? TYPE_MISMATCH, NO_MORE_ELEMENT -*> -macro AnyList.pop(&self, $Type) +fn any? AnyList.last_any(&self) @inline { - if (!self.size) return NO_MORE_ELEMENT?; - defer self.free_element(self.entries[self.size]); - return *anycast(self.entries[--self.size], $Type); + return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT?; } <* - Pop a value who's type is known. If the type is incorrect, this - will still pop the element. + Return whether the list is empty. - @param $Type : "The type we assume the value has" - @return "The first value as the type given" - @return? TYPE_MISMATCH, NO_MORE_ELEMENT + @return "True if the list is empty" *> -macro AnyList.pop_first(&self, $Type) +fn bool AnyList.is_empty(&self) @inline { - if (!self.size) return NO_MORE_ELEMENT?; - defer self.remove_at(0); - return *anycast(self.entries[0], $Type); + return !self.size; +} + +<* + Return the length of the list. + + @return "The number of elements in the list" +*> +fn usz AnyList.len(&self) @operator(len) @inline +{ + return self.size; } <* @@ -112,11 +383,222 @@ macro AnyList.get(&self, usz index, $Type) @return? TYPE_MISMATCH, NO_MORE_ELEMENT @require index < self.size : "Index out of range" *> -fn any AnyList.get_any(&self, usz index) @inline @operator([]) => InterfaceList {any}.get(self, index); +fn any AnyList.get_any(&self, usz index) @inline @operator([]) +{ + return self.entries[index]; +} <* - Return the length of the list. - - @return "The number of elements in the list" + Completely free and clear a list. *> -fn usz AnyList.len(&self) @operator(len) @inline => InterfaceList {any}.len(self); +fn void AnyList.free(&self) +{ + if (!self.allocator) return; + self.clear(); + allocator::free(self.allocator, self.entries); + self.capacity = 0; + self.entries = null; +} + +<* + Swap two elements in a list. + + @param i : "Index of one of the elements" + @param j : "Index of the other element" + @require i < self.size : "The first index is out of range" + @require j < self.size : "The second index is out of range" +*> +fn void AnyList.swap(&self, usz i, usz j) +{ + any temp = self.entries[i]; + self.entries[i] = self.entries[j]; + self.entries[j] = temp; +} + +<* + Print the list to a formatter. +*> +fn usz? AnyList.to_format(&self, Formatter* formatter) @dynamic +{ + switch (self.size) + { + case 0: + return formatter.print("[]")!; + case 1: + return formatter.printf("[%s]", self.entries[0])!; + default: + usz n = formatter.print("[")!; + foreach (i, element : self.entries[:self.size]) + { + if (i != 0) formatter.print(", ")!; + n += formatter.printf("%s", element)!; + } + n += formatter.print("]")!; + return n; + } +} + +<* + Remove any elements matching the predicate. + + @param filter : "The function to determine if it should be removed or not" + @return "the number of deleted elements" +*> +fn usz AnyList.remove_if(&self, AnyPredicate filter) +{ + return self._remove_if(filter, false); +} + +<* + Retain the elements matching the predicate. + + @param selection : "The function to determine if it should be kept or not" + @return "the number of deleted elements" +*> +fn usz AnyList.retain_if(&self, AnyPredicate selection) +{ + return self._remove_if(selection, true); +} + +<* + Remove any elements matching the predicate. + + @param filter : "The function to determine if it should be removed or not" + @param context : "The context to the function" + @return "the number of deleted elements" +*> +fn usz AnyList.remove_using_test(&self, AnyTest filter, any context) +{ + return self._remove_using_test(filter, false, context); +} + +<* + Retain any elements matching the predicate. + + @param selection : "The function to determine if it should be retained or not" + @param context : "The context to the function" + @return "the number of deleted elements" +*> +fn usz AnyList.retain_using_test(&self, AnyTest selection, any context) +{ + return self._remove_using_test(selection, true, context); +} + + +<* + Reserve memory so that at least the `min_capacity` exists. + + @param min_capacity : "The min capacity to hold" +*> +fn void AnyList.reserve(&self, usz min_capacity) +{ + if (!min_capacity) return; + if (self.capacity >= min_capacity) return; + if (!self.allocator) self.allocator = tmem; + min_capacity = math::next_power_of_2(min_capacity); + self.entries = allocator::realloc(self.allocator, self.entries, any.sizeof * min_capacity); + self.capacity = min_capacity; +} + +<* + Set the element at any index. + + @param index : "The index where to set the value." + @param value : "The value to set" + @require index <= self.size : "Index out of range" +*> +macro void AnyList.set(&self, usz index, value) +{ + if (index == self.size) + { + self.push(value); + return; + } + self.free_element(self.entries[index]); + self.entries[index] = allocator::copy(self.allocator, value); +} + +// -- private + +fn void AnyList.ensure_capacity(&self, usz added = 1) @inline @private +{ + usz new_size = self.size + added; + if (self.capacity >= new_size) return; + + assert(new_size < usz.max / 2U); + usz new_capacity = self.capacity ? 2U * self.capacity : 16U; + while (new_capacity < new_size) new_capacity *= 2U; + self.reserve(new_capacity); +} + +fn void AnyList._append(&self, any element) @local +{ + self.ensure_capacity(); + self.entries[self.size++] = element; +} + +<* + @require index < self.size +*> +fn void AnyList._insert_at(&self, usz index, any value) @local +{ + self.ensure_capacity(); + for (usz i = self.size; i > index; i--) + { + self.entries[i] = self.entries[i - 1]; + } + self.size++; + self.entries[index] = value; +} + +macro usz AnyList._remove_using_test(&self, AnyTest filter, bool $invert, ctx) @local +{ + usz size = self.size; + for (usz i = size, usz k = size; k > 0; k = i) + { + // Find last index of item to be deleted. + $if $invert: + while (i > 0 && !filter(&self.entries[i - 1], ctx)) i--; + $else + while (i > 0 && filter(&self.entries[i - 1], ctx)) i--; + $endif + // Remove the items from this index up to the one not to be deleted. + usz n = self.size - k; + for (usz j = i; j < k; j++) self.free_element(self.entries[j]); + self.entries[i:n] = self.entries[k:n]; + self.size -= k - i; + // Find last index of item not to be deleted. + $if $invert: + while (i > 0 && filter(&self.entries[i - 1], ctx)) i--; + $else + while (i > 0 && !filter(&self.entries[i - 1], ctx)) i--; + $endif + } + return size - self.size; +} + +macro usz AnyList._remove_if(&self, AnyPredicate filter, bool $invert) @local +{ + usz size = self.size; + for (usz i = size, usz k = size; k > 0; k = i) + { + // Find last index of item to be deleted. + $if $invert: + while (i > 0 && !filter(&self.entries[i - 1])) i--; + $else + while (i > 0 && filter(&self.entries[i - 1])) i--; + $endif + // Remove the items from this index up to the one not to be deleted. + usz n = self.size - k; + for (usz j = i; j < k; j++) self.free_element(self.entries[j]); + self.entries[i:n] = self.entries[k:n]; + self.size -= k - i; + // Find last index of item not to be deleted. + $if $invert: + while (i > 0 && filter(&self.entries[i - 1])) i--; + $else + while (i > 0 && !filter(&self.entries[i - 1])) i--; + $endif + } + return size - self.size; +} diff --git a/lib/std/collections/interfacelist.c3 b/lib/std/collections/interfacelist.c3 deleted file mode 100644 index ffd51bd73..000000000 --- a/lib/std/collections/interfacelist.c3 +++ /dev/null @@ -1,539 +0,0 @@ -// Copyright (c) 2024-2025 Christoffer Lerno. All rights reserved. -// Use of self source code is governed by the MIT license -// a copy of which can be found in the LICENSE_STDLIB file. -<* - @require Type.kindof == INTERFACE || Type.kindof == ANY : "The kind of an interfacelist must be an interface or `any`" -*> -module std::collections::interfacelist {Type}; -import std::io,std::math; - -alias InterfacePredicate = fn bool(Type value); -alias InterfaceTest = fn bool(Type type, Type context); - -<* - The InterfaceList contains a heterogenous set of types implementing an interface. anything placed in the - list will shallowly copied in order to be stored as the interface. This means - that the list will copy and free its elements. - - However, because we're getting interface values back when we pop, those operations - need to take an allocator, as we can only copy then pop then return the copy. - - If we're not doing pop, then things are easier, since we can just hand over - the existing value. -*> -struct InterfaceList (Printable) -{ - usz size; - usz capacity; - Allocator allocator; - Type* entries; -} - - -<* - Initialize the list. If not initialized then it will use the temp allocator - when something is pushed to it. - - @param [&inout] allocator : "The allocator to use" - @param initial_capacity : "The initial capacity to reserve, defaults to 16" -*> -fn InterfaceList* InterfaceList.init(&self, Allocator allocator, usz initial_capacity = 16) -{ - self.allocator = allocator; - self.size = 0; - if (initial_capacity > 0) - { - initial_capacity = math::next_power_of_2(initial_capacity); - self.entries = allocator::alloc_array(allocator, Type, initial_capacity); - } - else - { - self.entries = null; - } - self.capacity = initial_capacity; - return self; -} - -<* - Initialize the list using the temp allocator. - - @param initial_capacity : "The initial capacity to reserve" -*> -fn InterfaceList* InterfaceList.tinit(&self, usz initial_capacity = 16) -{ - return self.init(tmem, initial_capacity) @inline; -} - -fn bool InterfaceList.is_initialized(&self) @inline => self.allocator != null; - -<* - Push an element on the list by cloning it. - @require $defined(Type t = &element) : "Element must implement the interface" -*> -macro void InterfaceList.push(&self, element) -{ - if (!self.allocator) self.allocator = tmem; - self._append(allocator::clone(self.allocator, element)); -} - -<* - Free a retained element removed using *_retained. -*> -fn void InterfaceList.free_element(&self, Type element) @inline -{ - allocator::free(self.allocator, element.ptr); -} - -<* - Copy the last value, pop it and return the copy of it. - - @param [&inout] allocator : "The allocator to use for copying" - @return "A copy of the last value if it exists" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.copy_pop(&self, Allocator allocator) -{ - if (!self.size) return NO_MORE_ELEMENT?; - defer self.free_element(self.entries[self.size]); - return (Type)allocator::clone_any(allocator, self.entries[--self.size]); -} - -<* - Copy the last value, pop it and return the copy of it. - - @return "A temp copy of the last value if it exists" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.tcopy_pop(&self) => self.copy_pop(tmem); - -<* - Pop the last value. It must later be released using `list.free_element()`. - - @return "The last value if it exists" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.pop_retained(&self) -{ - if (!self.size) return NO_MORE_ELEMENT?; - return self.entries[--self.size]; -} - -<* - Remove all elements in the list. -*> -fn void InterfaceList.clear(&self) -{ - for (usz i = 0; i < self.size; i++) - { - self.free_element(self.entries[i]); - } - self.size = 0; -} - -<* - Pop the first value. It must later be released using `list.free_element()`. - - @return "The first value if it exists" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.pop_first_retained(&self) -{ - if (!self.size) return NO_MORE_ELEMENT?; - defer self.remove_at(0); - return self.entries[0]; -} - -<* - Copy the first value, pop it and return the copy of it. - - @param [&inout] allocator : "The allocator to use for copying" - @return "A copy of the first value if it exists" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.copy_pop_first(&self, Allocator allocator) -{ - if (!self.size) return NO_MORE_ELEMENT?; - defer self.free_element(self.entries[self.size]); - defer self.remove_at(0); - return (Type)allocator::clone_any(allocator, self.entries[0]); -} - -<* - Copy the first value, pop it and return the temp copy of it. - - @return "A temp copy of the first value if it exists" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.tcopy_pop_first(&self) => self.copy_pop_first(tmem); - -<* - Remove the element at the particular index. - - @param index : "The index of the element to remove" - @require index < self.size -*> -fn void InterfaceList.remove_at(&self, usz index) -{ - if (!--self.size || index == self.size) return; - self.free_element(self.entries[index]); - self.entries[index .. self.size - 1] = self.entries[index + 1 .. self.size]; -} - -<* - Add all the elements in another InterfaceList. - - @param [&in] other_list : "The list to add" -*> -fn void InterfaceList.add_all(&self, InterfaceList* other_list) -{ - if (!other_list.size) return; - self.reserve(other_list.size); - foreach (value : other_list) - { - self.entries[self.size++] = (Type)allocator::clone_any(self.allocator, value); - } -} - -<* - Reverse the order of the elements in the list. -*> -fn void InterfaceList.reverse(&self) -{ - if (self.size < 2) return; - usz half = self.size / 2U; - usz end = self.size - 1; - for (usz i = 0; i < half; i++) - { - self.swap(i, end - i); - } -} - -<* - Return a view of the data as a slice. - - @return "The slice view" -*> -fn Type[] InterfaceList.array_view(&self) -{ - return self.entries[:self.size]; -} - -<* - Push an element to the front of the list. - - @param value : "The value to push to the list" - @require $defined(Type t = &value) : "Value must implement the interface" -*> -macro void InterfaceList.push_front(&self, value) -{ - self.insert_at(0, value); -} - -<* - Insert an element at a particular index. - - @param index : "the index where the element should be inserted" - @param type : "the value to insert" - @require index <= self.size : "The index is out of bounds" - @require $defined(Type t = &type) : "Type must implement the interface" -*> -macro void InterfaceList.insert_at(&self, usz index, type) -{ - if (index == self.size) - { - self.push(type); - return; - } - Type value = allocator::clone(self.allocator, type); - self._insert_at(self, index, value); -} - -<* - Remove the last element in the list. The list may not be empty. - - @require self.size > 0 : "The list was already empty" -*> -fn void InterfaceList.remove_last(&self) -{ - self.free_element(self.entries[--self.size]); -} - -<* - Remove the first element in the list, the list may not be empty. - - @require self.size > 0 -*> -fn void InterfaceList.remove_first(&self) -{ - self.remove_at(0); -} - -<* - Return the first element - - @return "The first element" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.first(&self) @inline -{ - return self.size ? self.entries[0] : NO_MORE_ELEMENT?; -} - -<* - Return the last element - - @return "The last element" - @return? NO_MORE_ELEMENT -*> -fn Type? InterfaceList.last(&self) @inline -{ - return self.size ? self.entries[self.size - 1] : NO_MORE_ELEMENT?; -} - -<* - Return whether the list is empty. - - @return "True if the list is empty" -*> -fn bool InterfaceList.is_empty(&self) @inline -{ - return !self.size; -} - -<* - Return the length of the list. - - @return "The number of elements in the list" -*> -fn usz InterfaceList.len(&self) @operator(len) @inline -{ - return self.size; -} - -<* - Return an element in the list. - - @param index : "The index of the element to retrieve" - @return "The element at the index" - @return? TYPE_MISMATCH, NO_MORE_ELEMENT - @require index < self.size : "Index out of range" -*> -fn Type InterfaceList.get(&self, usz index) @inline @operator([]) -{ - return self.entries[index]; -} - -<* - Completely free and clear a list. -*> -fn void InterfaceList.free(&self) -{ - if (!self.allocator) return; - self.clear(); - allocator::free(self.allocator, self.entries); - self.capacity = 0; - self.entries = null; -} - -<* - Swap two elements in a list. - - @param i : "Index of one of the elements" - @param j : "Index of the other element" - @require i < self.size : "The first index is out of range" - @require j < self.size : "The second index is out of range" -*> -fn void InterfaceList.swap(&self, usz i, usz j) -{ - Type temp = self.entries[i]; - self.entries[i] = self.entries[j]; - self.entries[j] = temp; -} - -<* - Print the list to a formatter. -*> -fn usz? InterfaceList.to_format(&self, Formatter* formatter) @dynamic -{ - switch (self.size) - { - case 0: - return formatter.print("[]")!; - case 1: - return formatter.printf("[%s]", self.entries[0])!; - default: - usz n = formatter.print("[")!; - foreach (i, element : self.entries[:self.size]) - { - if (i != 0) formatter.print(", ")!; - n += formatter.printf("%s", element)!; - } - n += formatter.print("]")!; - return n; - } -} - -<* - Remove Type elements matching the predicate. - - @param filter : "The function to determine if it should be removed or not" - @return "the number of deleted elements" -*> -fn usz InterfaceList.remove_if(&self, InterfacePredicate filter) -{ - return self._remove_if(filter, false); -} - -<* - Retain the elements matching the predicate. - - @param selection : "The function to determine if it should be kept or not" - @return "the number of deleted elements" -*> -fn usz InterfaceList.retain_if(&self, InterfacePredicate selection) -{ - return self._remove_if(selection, true); -} - -<* - Remove Type elements matching the predicate. - - @param filter : "The function to determine if it should be removed or not" - @param context : "The context to the function" - @return "the number of deleted elements" -*> -fn usz InterfaceList.remove_using_test(&self, InterfaceTest filter, Type context) -{ - return self._remove_using_test(filter, false, context); -} - -<* - Retain Type elements matching the predicate. - - @param selection : "The function to determine if it should be retained or not" - @param context : "The context to the function" - @return "the number of deleted elements" -*> -fn usz InterfaceList.retain_using_test(&self, InterfaceTest selection, Type context) -{ - return self._remove_using_test(selection, true, context); -} - -<* - Reserve memory so that at least the `min_capacity` exists. - - @param min_capacity : "The min capacity to hold" -*> -fn void InterfaceList.reserve(&self, usz min_capacity) -{ - if (!min_capacity) return; - if (self.capacity >= min_capacity) return; - if (!self.allocator) self.allocator = tmem; - min_capacity = math::next_power_of_2(min_capacity); - self.entries = allocator::realloc(self.allocator, self.entries, Type.sizeof * min_capacity); - self.capacity = min_capacity; -} - -<* - Set the element at Type index. - - @param index : "The index where to set the value." - @param value : "The value to set" - @require index <= self.size : "Index out of range" - @require $defined(Type t = &value) : "Value must implement the interface" -*> -macro void InterfaceList.set(&self, usz index, value) -{ - if (index == self.size) - { - self.push(value); - return; - } - self.free_element(self.entries[index]); - self.entries[index] = allocator::clone(self.allocator, value); -} - -// -- private - -fn void InterfaceList.ensure_capacity(&self, usz added = 1) @inline @private -{ - usz new_size = self.size + added; - if (self.capacity >= new_size) return; - - assert(new_size < usz.max / 2U); - usz new_capacity = self.capacity ? 2U * self.capacity : 16U; - while (new_capacity < new_size) new_capacity *= 2U; - self.reserve(new_capacity); -} - -fn void InterfaceList._append(&self, Type element) @local -{ - self.ensure_capacity(); - self.entries[self.size++] = element; -} - -<* - @require index < self.size -*> -fn void InterfaceList._insert_at(&self, usz index, Type value) @local -{ - self.ensure_capacity(); - for (usz i = self.size; i > index; i--) - { - self.entries[i] = self.entries[i - 1]; - } - self.size++; - self.entries[index] = value; -} - -macro usz InterfaceList._remove_using_test(&self, InterfaceTest filter, bool $invert, ctx) @local -{ - usz size = self.size; - for (usz i = size, usz k = size; k > 0; k = i) - { - // Find last index of item to be deleted. - $if $invert: - while (i > 0 && !filter(self.entries[i - 1], ctx)) i--; - $else - while (i > 0 && filter(self.entries[i - 1], ctx)) i--; - $endif - // Remove the items from this index up to the one not to be deleted. - usz n = self.size - k; - for (usz j = i; j < k; j++) self.free_element(self.entries[j]); - self.entries[i:n] = self.entries[k:n]; - self.size -= k - i; - // Find last index of item not to be deleted. - $if $invert: - while (i > 0 && filter(self.entries[i - 1], ctx)) i--; - $else - while (i > 0 && !filter(self.entries[i - 1], ctx)) i--; - $endif - } - return size - self.size; -} - -macro usz InterfaceList._remove_if(&self, InterfacePredicate filter, bool $invert) @local -{ - usz size = self.size; - for (usz i = size, usz k = size; k > 0; k = i) - { - // Find last index of item to be deleted. - $if $invert: - while (i > 0 && !filter(self.entries[i - 1])) i--; - $else - while (i > 0 && filter(self.entries[i - 1])) i--; - $endif - // Remove the items from this index up to the one not to be deleted. - usz n = self.size - k; - for (usz j = i; j < k; j++) self.free_element(self.entries[j]); - self.entries[i:n] = self.entries[k:n]; - self.size -= k - i; - // Find last index of item not to be deleted. - $if $invert: - while (i > 0 && filter(self.entries[i - 1])) i--; - $else - while (i > 0 && !filter(self.entries[i - 1])) i--; - $endif - } - return size - self.size; -} diff --git a/lib/std/core/allocators/dynamic_arena.c3 b/lib/std/core/allocators/dynamic_arena.c3 index 5faf3f7a7..bb29a9631 100644 --- a/lib/std/core/allocators/dynamic_arena.c3 +++ b/lib/std/core/allocators/dynamic_arena.c3 @@ -13,7 +13,7 @@ import std::math; The advantage over the BackedArenaAllocator, is that when allocating beyond the first "page", it will retain the characteristics of an arena allocator (allocating a large piece of memory then handing off - memory from that memory), whereas the BackedArenaAllocator will have heap allocator characteristics. + memory from that memory), wheras the BackedArenaAllocator will have heap allocator characteristics. *> struct DynamicArenaAllocator (Allocator) { diff --git a/lib/std/core/allocators/tracking_allocator.c3 b/lib/std/core/allocators/tracking_allocator.c3 index 00ce4d90a..3fe0cb77b 100644 --- a/lib/std/core/allocators/tracking_allocator.c3 +++ b/lib/std/core/allocators/tracking_allocator.c3 @@ -19,7 +19,7 @@ alias AllocMap = HashMap { uptr, Allocation }; // It tracks allocations using a hash map but // is not compatible with allocators that uses mark() // -// It is also embarrassingly single-threaded, so +// It is also embarassingly single-threaded, so // do not use it to track allocations that cross threads. struct TrackingAllocator (Allocator) @@ -216,4 +216,4 @@ fn void? TrackingAllocator.fprint_report(&self, OutStream out) => @pool() } } } -} +} \ No newline at end of file diff --git a/lib/std/core/array.c3 b/lib/std/core/array.c3 index 4412019bd..fbd6cba0b 100644 --- a/lib/std/core/array.c3 +++ b/lib/std/core/array.c3 @@ -142,7 +142,7 @@ macro tconcat(arr1, arr2) @nodiscard => concat(tmem, arr1, arr2); @param [in] array @param identity - @param #operation : "The reduction/folding lambda function or function pointer to apply." + @param #operation : "The reduction/folding labmda function or function pointer to apply." @require @is_valid_list(array) : "Expected a valid list" @require $defined($typefrom(@reduce_fn(array, identity)) $func = #operation) : "Invalid lambda or function pointer type" @@ -554,4 +554,4 @@ macro bool @is_valid_fill(left, right, fill_with = ...) $endif } -macro usz find_len(list) => $defined(list.len()) ??? list.len() : list.len; +macro usz find_len(list) => $defined(list.len()) ??? list.len() : list.len; \ No newline at end of file diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index 553e47ab5..473c034f6 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -7,7 +7,7 @@ import libc, std::hash, std::io, std::os::backtrace; <* EMPTY_MACRO_SLOT is a value used for implementing optional arguments for macros in an efficient - way. It relies on the fact that distinct types are not implicitly convertible. + way. It relies on the fact that distinct types are not implicitly convertable. You can use `@is_empty_macro_slot()` and `@is_valid_macro_slot()` to figure out whether the argument has been used or not. diff --git a/lib/std/core/types.c3 b/lib/std/core/types.c3 index 797cfc37f..4fa7d595e 100644 --- a/lib/std/core/types.c3 +++ b/lib/std/core/types.c3 @@ -115,9 +115,7 @@ fn bool TypeKind.is_int(kind) @inline return kind == TypeKind.SIGNED_INT || kind == TypeKind.UNSIGNED_INT; } -macro bool is_slice_convertable($Type) @deprecated("Use is_slice_convertible") => is_slice_convertible($Type); - -macro bool is_slice_convertible($Type) +macro bool is_slice_convertable($Type) { $switch $Type.kindof: $case SLICE: diff --git a/lib/std/crypto/ed25519.c3 b/lib/std/crypto/ed25519.c3 index 8af9093a5..c4e9954b9 100644 --- a/lib/std/crypto/ed25519.c3 +++ b/lib/std/crypto/ed25519.c3 @@ -365,7 +365,7 @@ fn void F25519Int.normalize(&s) { s.reduce_carry((*s)[^1] >> 7); - // Subtract p + // Substract p F25519Int sub @noinit; ushort c = 19; foreach (i, v : (*s)[:^1]) @@ -399,7 +399,7 @@ fn char eq(F25519Int* a, F25519Int* b) } <* - Constant-time conditional selection. Result is undefined if condition is neither 0 nor 1. + Constant-time conditonal selection. Result is undefined if condition is neither 0 nor 1. @param [&in] zero : "selected if condition is 0" @param [&in] one : "selected if condition is 1" @@ -441,7 +441,7 @@ fn F25519Int F25519Int.add(&s, F25519Int* n) @operator(+) macro F25519Int F25519Int.@sub(&s, F25519Int #n) @operator(-) => s.sub(@addr(#n)); <* - Subtraction. + Substraction. @param [&in] s @param [&in] n @@ -638,7 +638,7 @@ fn FBaseInt from_bytes(char[] bytes) } <* - Constant-time conditional selection. Result is undefined if condition is neither 0 nor 1. + Constant-time conditonal selection. Result is undefined if condition is neither 0 nor 1. @param [&in] zero : "selected if condition is 0" @param [&in] one : "selected if condition is 1" @@ -676,7 +676,7 @@ fn FBaseInt FBaseInt.add(&s, FBaseInt* n) @operator(+) } <* - Subtraction if RHS is less than LHS else identity. + Substraction if RHS is less than LHS else identity. @param [&in] s @param [&in] n diff --git a/lib/std/io/file_mmap.c3 b/lib/std/io/file_mmap.c3 index 630a4ebcc..a50f346b0 100644 --- a/lib/std/io/file_mmap.c3 +++ b/lib/std/io/file_mmap.c3 @@ -20,7 +20,7 @@ fn char[] FileMmap.bytes(&self) } <* - Destroys the underlying VirtualMemory object ie. calls munmap()" + Destroys the underlyng VirtualMemory object ie. calls munmap()" *> fn void? FileMmap.destroy(&self) @maydiscard { diff --git a/lib/std/io/stream/bytebuffer.c3 b/lib/std/io/stream/bytebuffer.c3 index 8335e9eaa..3e086314d 100644 --- a/lib/std/io/stream/bytebuffer.c3 +++ b/lib/std/io/stream/bytebuffer.c3 @@ -13,7 +13,7 @@ struct ByteBuffer (InStream, OutStream) <* ByteBuffer provides a streamable read/write buffer. - max_read defines how many bytes might be kept before its internal buffer is shrunk. + max_read defines how many bytes might be kept before its internal buffer is shrinked. @require self.bytes.len == 0 : "Buffer already initialized." *> fn ByteBuffer* ByteBuffer.init(&self, Allocator allocator, usz max_read, usz initial_capacity = 16) @@ -145,4 +145,4 @@ macro ByteBuffer.shrink(&self) self.write_idx = 1 + readable; self.read_idx = 1; } -} +} \ No newline at end of file diff --git a/lib/std/libc/libc.c3 b/lib/std/libc/libc.c3 index b4dfda6fc..8ad3842e3 100644 --- a/lib/std/libc/libc.c3 +++ b/lib/std/libc/libc.c3 @@ -438,7 +438,7 @@ alias TimeOffset @if(!env::WASI) = CLong ; const int TIME_UTC = 1; -// This is a best-effort approximation, but the C standard does not enforce +// This is a best-effort aproximation, but the C standard does not enforce // that this is a compile-time standard. const CLOCKS_PER_SEC @if(env::WIN32) = 1000; const CLOCKS_PER_SEC @if(!env::WIN32) = 1000000; diff --git a/lib/std/libc/os/posix.c3 b/lib/std/libc/os/posix.c3 index ef911768e..31854a684 100644 --- a/lib/std/libc/os/posix.c3 +++ b/lib/std/libc/os/posix.c3 @@ -218,7 +218,7 @@ enum Speed : const CUInt MAX_BAUD = B4000000, } -enum Cc : const inline char +enum Cc : const char { VINTR = 0, VQUIT = 1, diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index a6350cea3..8ce850169 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -252,8 +252,8 @@ macro @ceil($input) @const => $$ceil($input); @return "lower if x < lower, upper if x > upper, otherwise return x." @require types::is_numerical($typeof(x)) : `The input must be a numerical value or numerical vector` - @require $defined(x = lower) : `The lower bound must be convertible to the value type.` - @require $defined(x = upper) : `The upper bound must be convertible to the value type.` + @require $defined(x = lower) : `The lower bound must be convertable to the value type.` + @require $defined(x = upper) : `The upper bound must be convertable to the value type.` *> macro clamp(x, lower, upper) => $$max(($typeof(x))lower, $$min(x, ($typeof(x))upper)); diff --git a/lib/std/net/os/darwin.c3 b/lib/std/net/os/darwin.c3 index 3ef758836..9b74fb24b 100644 --- a/lib/std/net/os/darwin.c3 +++ b/lib/std/net/os/darwin.c3 @@ -67,7 +67,7 @@ const int SO_WANTMORE = 0x4000; // Apple: Give hint when more data re const int SO_WANTOOBFLAG = 0x8000; // Apple: Want OOB in MSG_FLAG on receive const int SO_SNDBUF = 0x1001; // Send buffer size -const int SO_RCVBUF = 0x1002; // Receive buffer size +const int SO_RCVBUF = 0x1002; // Recieve buffer size const int SO_SNDLOWAT = 0x1003; // Send low-water mark const int SO_RCVLOWAT = 0x1004; // Receive low-water mark const int SO_SNDTIMEO = 0x1005; // Send timeout @@ -94,4 +94,4 @@ const CShort POLLATTRIB = 0x0400; // file attributes may have changed const CShort POLLNLINK = 0x0800; // (un)link/rename may have happened const CShort POLLWRITE = 0x1000; // file's contents may have changed -const CInt MSG_PEEK = 0x0002; +const CInt MSG_PEEK = 0x0002; \ No newline at end of file diff --git a/lib/std/os/subprocess.c3 b/lib/std/os/subprocess.c3 index a9be419c3..774aa7855 100644 --- a/lib/std/os/subprocess.c3 +++ b/lib/std/os/subprocess.c3 @@ -35,7 +35,7 @@ bitstruct SubProcessOptions : int { // Combine stdout and stderr to the same file bool combined_stdout_stderr; - // Child process should inherit env variables of parent process + // Child process should inhert env variables of parent process bool inherit_environment; // Enable async reading of stdout/stderr before completion bool read_async; diff --git a/lib/std/os/win32/memoryapi.c3 b/lib/std/os/win32/memoryapi.c3 index 176498844..8e5f9db04 100644 --- a/lib/std/os/win32/memoryapi.c3 +++ b/lib/std/os/win32/memoryapi.c3 @@ -36,7 +36,7 @@ enum Win32_FreeType : const Win32_DWORD MEM_COALESCE_PLACEHOLDERS = 0x00000001, MEM_PRESERVE_PLACEHOLDER = 0x00000002, } -extern fn Win32_LPVOID virtualAlloc(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_AllocationType flAllocationType, Win32_Protect flProtect) @extern("VirtualAlloc"); +extern fn Win32_LPVOID virtualAlloc(Win32_LPVOID lpAddres, Win32_SIZE_T dwSize, Win32_AllocationType flAllocationType, Win32_Protect flProtect) @extern("VirtualAlloc"); extern fn Win32_PVOID virtualAlloc2(Win32_HANDLE process, Win32_PVOID baseAddress, Win32_SIZE_T size, Win32_AllocationType allocationType, Win32_ULONG pageProtection, Win32_MEM_EXTENDED_PARAMETER* extendedParameters, Win32_ULONG parameterCount) @extern("VirtualAlloc2"); extern fn Win32_BOOL virtualFree(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_FreeType dwFreeType) @extern("VirtualFree"); extern fn Win32_BOOL virtualProtect(Win32_LPVOID lpAddress, Win32_SIZE_T dwSize, Win32_Protect flNewProtect, Win32_Protect* lpflOldProtect) @extern("VirtualProtect"); diff --git a/lib/std/os/win32/types.c3 b/lib/std/os/win32/types.c3 index 595385ee3..0fc54df29 100644 --- a/lib/std/os/win32/types.c3 +++ b/lib/std/os/win32/types.c3 @@ -432,7 +432,7 @@ struct Win32_XMM_SAVE_AREA32 Win32_UCHAR tagWord; Win32_UCHAR reserved1; Win32_USHORT errorOpcode; - Win32_ULONG errorOffset; + Win32_ULONG errrorOffset; Win32_USHORT errorSelector; Win32_USHORT reserved2; Win32_ULONG dataOffset; diff --git a/lib/std/sort/quicksort.c3 b/lib/std/sort/quicksort.c3 index 3e326481e..d12e16440 100644 --- a/lib/std/sort/quicksort.c3 +++ b/lib/std/sort/quicksort.c3 @@ -82,8 +82,8 @@ fn void qsort(Type list, isz low, isz high, CmpFn cmp, Context context) } <* -@require low <= k : "kth smallest element is smaller than lower bounds" -@require k <= high : "kth smallest element is larger than upper bounds" +@require low <= k : "kth smalles element is smaller than lower bounds" +@require k <= high : "kth smalles element is larger than upper bounds" *> fn ElementType? qselect(Type list, isz low, isz high, isz k, CmpFn cmp, Context context) { diff --git a/releasenotes.md b/releasenotes.md index daee07764..6318ec34e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -1,20 +1,5 @@ # C3C Release Notes -## 0.7.6 Change list - -### Changes / improvements - -### Fixes -- Compiler assert with var x @noinit = 0 #2452 -- Confusing error message when type has [] overloaded but not []= #2453 -- $defined(x[0] = val) causes an error instead of returning false when a type does not have []= defined #2454 -- Returning pointer to index of slice stored in a struct from method taking self incorrectly detected as returning pointer to local variable #2455. -- Inlining location when accessing #foo symbols. -- Improve inlined-at when checking generic code. - -### Stdlib changes -- Added generic `InterfaceList` to store a list of values that implement a specific interface - ## 0.7.5 Change list ### Changes / improvements @@ -298,7 +283,7 @@ - Linker errors when shadowing @local with public function #2198 - Bug when offsetting pointers of large structs using ++ and --. - `x++` and `x--` works on pointer vectors #2222. -- `x += 1` and `x -= 1` works properly on pointer vectors #2222. +- `x += 1` and `x -= 1` works propertly on pointer vectors #2222. - Fixes to `x += { 1, 1 }` for enum and pointer vectors #2222. - Linking fails on operator method imported as `@public` #2224. - Lambda C-style vaargs were not properly rejected, leading to crash #2229. @@ -425,7 +410,7 @@ - Regression with invalid setup of the WASM temp allocator. - Correctly detect multiple overloads of the same type. - ABI bug on x64 Linux / MacOS when passing a union containing a struct of 3 floats. #2087 -- Bug with slice access as inline struct member #2088. +- Bug with slice acces as inline struct member #2088. - `@if` now does implicit conversion to bool like `$if`. #2086 - Fix broken enum inline -> bool conversions #2094. - `@if` was ignored on attrdef, regression 0.7 #2093. @@ -570,7 +555,7 @@ ### Changes / improvements - Contracts @require/@ensure are no longer treated as conditionals, but must be explicitly bool. - Add `win-debug` setting to be able to pick dwarf for output #1855. -- Error on switch case fallthrough if there is more than one newline #1849. +- Error on switch case fallthough if there is more than one newline #1849. - Added flags to `c3c project view` to filter displayed properties - Compile time array assignment #1806. - Allow `+++` to work on all types of arrays. @@ -597,7 +582,7 @@ - Fix issue with `@const` where the statement `$foo = 1;` was not considered constant. - Const strings and bytes were not properly converted to compile time bools. - Concatenating a const empty slice with another array caused a null pointer access. -- Fix `linux-crt` and `linux-crtbegin` not getting recognized as a project parameter +- Fix `linux-crt` and `linux-crtbegin` not getting recognized as a project paramater - Fix dues to crash when converting a const vector to another vector #1864. - Filter `$exec` output from `\r`, which otherwise would cause a compiler assert #1867. - Fixes to `"exec" use, including issue when compiling with MinGW. @@ -719,7 +704,7 @@ - Prohibit raw vaargs in regular functions with a function body. - Assert on certain slice to slice casts. #1768. - Fix vector float -> bool conversion. -- Fix `+a = 1` erroneously being accepted. +- Fix `+a = 1` erronously being accepted. - Fix not freeing a zero length String - Macros with trailing bodys aren't allowed as the single statement after a while loop with no body #1772. - Deref subscripts as needed for macro ref method arguments. #1789 @@ -1670,7 +1655,7 @@ - Allow any expression as default expression. - Allow using enums for indexing arrays. -- Added $convertible / $castable compile time functions. +- Added $convertable / $castable compile time functions. - Removed ´func´ deprecated keyword - Slicing a distinct type now returns the distinct type. - Renamed @autoimport -> @builtin @@ -1687,7 +1672,7 @@ - Add linker and linked dir arguments to build files. - Auto-import std::core. - LLVM 15 support. -- Better native file handling for MSVC +- Beter native file handling for MSVC - New import rules – recursive imports - Add lld linking for FreeBSD - User defined attributes. @Foo = @inline diff --git a/resources/grammar/grammar.y b/resources/grammar/grammar.y index 0222038aa..c36677344 100644 --- a/resources/grammar/grammar.y +++ b/resources/grammar/grammar.y @@ -887,7 +887,6 @@ statement | asm_block_stmt | ct_echo_stmt | ct_assert_stmt - | ct_error_stmt | ct_if_stmt | ct_switch_stmt | ct_foreach_stmt @@ -928,35 +927,14 @@ optional_label | empty ; -ct_assert_expr_list - : ',' constant_expr - | ct_assert_expr_list ',' constant_expr - ; - ct_assert_stmt : CT_ASSERT constant_expr ':' constant_expr ';' - | CT_ASSERT constant_expr ':' constant_expr ct_assert_expr_list ';' | CT_ASSERT constant_expr ';' - ; - -ct_error_stmt - : CT_ERROR constant_expr ';' - | CT_ERROR constant_expr ct_assert_expr_list ';' + | CT_ERROR constant_expr ';' ; ct_include_stmt - : CT_INCLUDE constant_expr opt_attributes ';' - ; - -ct_exec_list - : constant_expr - | ct_exec_list ',' constant_expr - ; - -ct_exec_stmt - : CT_EXEC '(' string_expr ')' opt_attributes ';' - | CT_EXEC '(' string_expr ',' '{' ct_exec_list opt_comma '}' ')' opt_attributes ';' - | CT_EXEC '(' string_expr ',' '{' ct_exec_list opt_comma '}' ',' constant_expr ')' opt_attributes ';' + : CT_INCLUDE string_expr ';' ; ct_echo_stmt @@ -1099,7 +1077,7 @@ faults | faults ',' CONST_IDENT opt_attributes ; -faultdef_declaration +fault_declaration : FAULTDEF faults ';' ; @@ -1154,12 +1132,12 @@ parameter | CT_IDENT ELLIPSIS ; -func_definition_decl +func_defintion_decl : FN func_header fn_parameter_list opt_attributes ';' ; func_definition - : func_definition_decl + : func_defintion_decl | FN func_header fn_parameter_list opt_attributes macro_func_body ; @@ -1237,23 +1215,19 @@ opt_generic_parameters define_ident : IDENT opt_attributes '=' path_ident opt_generic_parameters - | IDENT opt_attributes '=' MODULE path_ident opt_generic_parameters | CONST_IDENT opt_attributes '=' path_const opt_generic_parameters | AT_IDENT opt_attributes '=' path_at_ident opt_generic_parameters ; -attrdef_declaration - : ATTRDEF define_attribute ';' - ; - -alias_declaration +define_declaration : ALIAS define_ident ';' + | ATTRDEF define_attribute ';' | ALIAS TYPE_IDENT opt_attributes '=' typedef_type opt_attributes ';' ; interface_body - : func_definition_decl - | interface_body func_definition_decl + : func_defintion_decl + | interface_body func_defintion_decl ; interface_declaration @@ -1271,7 +1245,7 @@ interface_declaration_name | TYPE_IDENT ':' interface_parents ; -typedef_declaration +distinct_declaration : TYPEDEF TYPE_IDENT opt_interface_impl opt_attributes '=' opt_inline type ';' ; @@ -1300,44 +1274,46 @@ import_decl ; translation_unit - : module top_level_after_module - | top_level_no_module + : top_level_statements | empty ; -top_level_decl - : import_decl - | func_definition - | EXTERN func_definition - | const_declaration - | EXTERN const_declaration - | global_declaration - | EXTERN global_declaration +top_level_statements + : top_level + | top_level_statements top_level + ; + +opt_extern + : EXTERN + | empty + ; + +exec_decl + : CT_EXEC '(' expr ')' opt_attributes ';' + | CT_EXEC '(' expr ',' initializer_list ')' opt_attributes ';' + | CT_EXEC '(' expr ',' initializer_list ',' expr ')' opt_attributes ';' + ; + +top_level + : module + | import_decl + | exec_decl + | opt_extern func_definition + | opt_extern const_declaration + | opt_extern global_declaration | ct_assert_stmt | ct_echo_stmt | ct_include_stmt - | ct_exec_stmt | struct_declaration - | faultdef_declaration + | fault_declaration | enum_declaration | macro_declaration - | alias_declaration - | attrdef_declaration + | define_declaration | bitstruct_declaration - | typedef_declaration + | distinct_declaration | interface_declaration ; -top_level_after_module - : top_level_decl - | top_level_after_module top_level_decl - ; - -top_level_no_module - : top_level_decl - | top_level_after_module top_level_decl - ; - %% void yyerror(YYLTYPE * yylloc_param , yyscan_t yyscanner, const char *yymsgp) diff --git a/resources/grammar/grammar_proposal.y b/resources/grammar/grammar_proposal.y index 25b694f36..9a5c73e90 100644 --- a/resources/grammar/grammar_proposal.y +++ b/resources/grammar/grammar_proposal.y @@ -1144,12 +1144,12 @@ parameter | CT_IDENT ELLIPSIS ; -func_definition_decl +func_defintion_decl : FN func_header fn_parameter_list opt_attributes ';' ; func_definition - : func_definition_decl + : func_defintion_decl | FN func_header fn_parameter_list opt_attributes macro_func_body ; @@ -1223,8 +1223,8 @@ define_declaration ; interface_body - : func_definition_decl - | interface_body func_definition_decl + : func_defintion_decl + | interface_body func_defintion_decl ; interface_declaration diff --git a/src/build/build_options.c b/src/build/build_options.c index 190b01a1d..02314d09c 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -249,7 +249,7 @@ static void project_view_usage() PRINTF("the results will be printed out like they are in the full view."); PRINTF("Otherwise the \"
: \" is left out."); PRINTF(""); - PRINTF("With flags on, each selected property will be separated by an empty"); + PRINTF("With flags on, each selected property will be seperated by an empty"); PRINTF("line, and properties with multiple values (like --authors) will have"); PRINTF("their values printed each on a new line."); PRINTF(""); @@ -1270,7 +1270,7 @@ static void parse_option(BuildOptions *options) name); } char *name_copy = strdup(name); - str_elide_in_place(name_copy, 32); + str_ellide_in_place(name_copy, 32); if (strchr(name, '/') != NULL || (PLATFORM_WINDOWS && strchr(name, '\\') != NULL)) { error_exit( diff --git a/src/build/libraries.c b/src/build/libraries.c index d322ba283..469c2f0ce 100644 --- a/src/build/libraries.c +++ b/src/build/libraries.c @@ -103,7 +103,7 @@ static Library *add_library(JSONObject *json, const char *dir) if (!str_is_valid_lowercase_name(provides)) { char *res = strdup(provides); - str_elide_in_place(res, 32); + str_ellide_in_place(res, 32); error_exit("Invalid 'provides' module name in %s, was '%s', the name should only contain alphanumerical letters and '_'.", library->dir, res); } library->provides = provides; diff --git a/src/build/project.c b/src/build/project.c index 9bbfd92da..d25b6e4c6 100644 --- a/src/build/project.c +++ b/src/build/project.c @@ -246,7 +246,7 @@ static void load_into_build_target(BuildParseContext context, JSONObject *json, if (!str_is_valid_lowercase_name(name)) { char *name_copy = strdup(name); - str_elide_in_place(name_copy, 32); + str_ellide_in_place(name_copy, 32); error_exit("Error reading %s: invalid library target name '%s' – it should only contain alphanumerical letters and '_'.", context.file, name_copy); } } diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 685539656..87fcb4be3 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -413,7 +413,7 @@ void compiler_parse(void) compiler_parsing_time = bench_mark(); } -bool compiler_should_output_file(const char *file) +bool compiler_should_ouput_file(const char *file) { if (!vec_size(compiler.build.emit_only)) return true; FOREACH(const char *, f, compiler.build.emit_only) @@ -1604,7 +1604,6 @@ Module *compiler_find_or_create_module(Path *module_name, const char **parameter // Set up the module. module = CALLOCS(Module); module->name = module_name; - module->inlined_at = (InliningSpan) { INVALID_SPAN, NULL }; size_t first = 0; for (size_t i = module_name->len; i > 0; i--) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 1d482179c..674bcef76 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -166,25 +166,6 @@ struct ConstInitializer_ }; }; -typedef union -{ - struct - { - FileId file_id; - unsigned char length; - unsigned char col; - uint32_t row; - }; - uint64_t a; -} SourceSpan; - -static_assert(sizeof(SourceSpan) == 8, "Expected 8 bytes"); - -typedef struct InliningSpan_ -{ - SourceSpan span; - struct InliningSpan_ *prev; -} InliningSpan; typedef struct { @@ -230,8 +211,21 @@ typedef struct const char *full_path; } File; +typedef union +{ + struct + { + FileId file_id; + unsigned char length; + unsigned char col; + uint32_t row; + }; + uint64_t a; +} SourceSpan; +static_assert(sizeof(SourceSpan) == 8, "Expected 8 bytes"); + typedef struct { const char *key; @@ -1613,7 +1607,6 @@ typedef struct Module_ Decl **tests; Decl **lambdas_to_evaluate; const char *generic_suffix; - InliningSpan inlined_at; } Module; @@ -1764,7 +1757,11 @@ typedef struct JumpTarget_ AstId defer; } JumpTarget; - +typedef struct InliningSpan_ +{ + SourceSpan span; + struct InliningSpan_ *prev; +} InliningSpan; struct SemaContext_ { @@ -2206,7 +2203,6 @@ Decl **copy_decl_list_macro(Decl **decl_list); Ast *copy_ast_macro(Ast *source_ast); Ast *copy_ast_defer(Ast *source_ast); TypeInfo *copy_type_info_single(TypeInfo *type_info); -InliningSpan *copy_inlining_span(InliningSpan *span); void init_asm(PlatformTarget *target); void print_asm_list(PlatformTarget *target); @@ -2482,7 +2478,7 @@ File *source_file_text_load(const char *filename, char *content); File *compile_and_invoke(const char *file, const char *args, const char *stdin_data, size_t limit); void compiler_parse(void); -bool compiler_should_output_file(const char *file); +bool compiler_should_ouput_file(const char *file); void emit_json(void); void stable_init(STable *table, uint32_t initial_size); diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 6d68e2fce..d2a1472a3 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -1159,11 +1159,3 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) return copy; } -InliningSpan *copy_inlining_span(InliningSpan *span) -{ - if (!span) return NULL; - InliningSpan *copy_span = MALLOCS(InliningSpan); - copy_span->span = span->span; - copy_span->prev = copy_inlining_span(span->prev); - return copy_span; -} \ No newline at end of file diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index ca31074e7..32337a3c8 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -1070,7 +1070,7 @@ static inline void llvm_optimize(GenContext *c) const char *llvm_codegen(void *context) { GenContext *c = context; - if (!compiler_should_output_file(c->base_name)) return NULL; + if (!compiler_should_ouput_file(c->base_name)) return NULL; llvm_optimize(c); // Serialize the LLVM IR, if requested, also verify the IR in this case diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 12cf43fd6..d0641c2de 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4551,7 +4551,7 @@ static void llvm_emit_binary_expr(GenContext *c, BEValue *be_value, Expr *expr) // Operation + assign if (binary_op > BINARYOP_ASSIGN) { - // Find the base op. + // Finde the base op. BinaryOp base_op = binaryop_assign_base_op(binary_op); ASSERT(base_op != BINARYOP_ERROR); diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index b61dd1714..103881140 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -589,7 +589,7 @@ void llvm_emit_for_stmt(GenContext *c, Ast *ast) llvm_emit_br(c, cond_block); break; case LOOP_INFINITE: - // We might have an infinite loop + // We might have an infite loop if (!loop_start_block) { SourceSpan loc = ast->span; diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index 8b0ed36f5..51888ddb8 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -1179,7 +1179,7 @@ static Expr *parse_ct_defined(ParseContext *c, Expr *left, SourceSpan lhs_start /** * ct_sizeof ::= CT_SIZEOF '(' expr ')' * - * Note that this is transformed to $typeof(expr).sizeof. + * Note that this is tranformed to $typeof(expr).sizeof. */ static Expr *parse_ct_sizeof(ParseContext *c, Expr *left, SourceSpan lhs_start UNUSED) { @@ -1599,7 +1599,7 @@ EXIT: is_unsigned = false; if (i128_comp(i, INT128_MIN, type_u128) == CMP_GT) { - PRINT_ERROR_AT(expr_int, "The negated integer size would exceed an int128."); + PRINT_ERROR_AT(expr_int, "The negated integer size would exeed an int128."); return poisoned_expr; } if (negated) i = i128_neg(i); diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index b65a8ee2c..6d7099fdb 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -16,7 +16,7 @@ typedef enum FunctionParse_ static inline Decl *parse_func_definition(ParseContext *c, AstId contracts, FunctionParse parse_kind); static inline bool parse_bitstruct_body(ParseContext *c, Decl *decl); static inline bool parse_enum_param_list(ParseContext *c, Decl*** parameters_ref, ArrayIndex *inline_index); -static Decl *parse_ct_include(ParseContext *c); +static Decl *parse_include(ParseContext *c); static Decl *parse_exec(ParseContext *c); static bool parse_attributes_for_global(ParseContext *c, Decl *decl); INLINE bool parse_decl_initializer(ParseContext *c, Decl *decl); @@ -3139,7 +3139,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref) return true; } -static Decl *parse_ct_include(ParseContext *c) +static Decl *parse_include(ParseContext *c) { SourceSpan loc = c->span; Decl *decl = decl_new(DECL_CT_INCLUDE, NULL, loc); @@ -3323,7 +3323,7 @@ Decl *parse_top_level_statement(ParseContext *c, ParseContext **context_out) return NULL; case TOKEN_CT_INCLUDE: if (contracts) goto CONTRACT_NOT_ALLOWED; - decl = parse_ct_include(c); + decl = parse_include(c); break; case TOKEN_CT_EXEC: if (contracts) goto CONTRACT_NOT_ALLOWED; diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index 26b42ab60..c09d6ba44 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -41,7 +41,7 @@ Expr *parse_integer(ParseContext *c, Expr *left, SourceSpan lhs_start); Expr *parse_decl_or_expr(ParseContext *c); void recover_top_level(ParseContext *c); Expr *parse_cond(ParseContext *c); -Ast *parse_compound_stmt(ParseContext *c); +Ast* parse_compound_stmt(ParseContext *c); Ast *parse_short_body(ParseContext *c, TypeInfoId return_type, bool is_regular_fn); bool parse_attribute(ParseContext *c, Attr **attribute_ref, bool expect_eos); diff --git a/src/compiler/sema_asm.c b/src/compiler/sema_asm.c index 05e980b6c..ee21e7515 100644 --- a/src/compiler/sema_asm.c +++ b/src/compiler/sema_asm.c @@ -82,7 +82,7 @@ static inline Decl *sema_resolve_external_symbol(SemaContext *context, Expr *exp } return decl; } -static inline bool sema_reg_int_supported_type(AsmArgType arg, Type *type) +static inline bool sema_reg_int_suported_type(AsmArgType arg, Type *type) { ASSERT(type_flatten(type) == type); unsigned bits = type_bit_size(type); @@ -104,7 +104,7 @@ INLINE bool sema_reg_is_valid_in_slot(AsmRegister *reg, AsmArgType arg_type) UNREACHABLE } -static inline bool sema_reg_float_supported_type(AsmArgType arg, Type *type) +static inline bool sema_reg_float_suported_type(AsmArgType arg, Type *type) { ASSERT(type_flatten(type) == type); if (!arg.float_bits) return false; @@ -415,7 +415,7 @@ static inline bool sema_check_asm_var(SemaContext *context, AsmInlineBlock *bloc SEMA_ERROR(expr, "An integer variable was not expected here."); return false; } - if (!sema_reg_int_supported_type(arg_type, type)) + if (!sema_reg_int_suported_type(arg_type, type)) { unsigned bits = arg_bits_max(arg_type.ireg_bits, 0); ASSERT(bits); @@ -437,7 +437,7 @@ static inline bool sema_check_asm_var(SemaContext *context, AsmInlineBlock *bloc SEMA_ERROR(expr, "A floating point variable was not expected here."); return false; } - if (!sema_reg_float_supported_type(arg_type, type)) + if (!sema_reg_float_suported_type(arg_type, type)) { SEMA_ERROR(expr, "%s is not supported in this position, convert it to a valid type.", type_quoted_error_string(decl->type)); @@ -500,7 +500,7 @@ static inline bool sema_check_asm_arg_value(SemaContext *context, AsmInlineBlock if (type_is_pointer_type(type)) type = type_uptr->canonical; if (type_is_integer(type)) { - if (!sema_reg_int_supported_type(arg_type, type)) + if (!sema_reg_int_suported_type(arg_type, type)) { SEMA_ERROR(expr, "%s is not valid for this slot.", type_quoted_error_string(inner->type)); return false; @@ -511,7 +511,7 @@ static inline bool sema_check_asm_arg_value(SemaContext *context, AsmInlineBlock } if (type_is_float(type)) { - if (!sema_reg_float_supported_type(arg_type, type)) + if (!sema_reg_float_suported_type(arg_type, type)) { SEMA_ERROR(expr, "%s is not valid for this slot.", type_quoted_error_string(inner->type)); return false; diff --git a/src/compiler/sema_builtins.c b/src/compiler/sema_builtins.c index 88beba663..f64104adc 100644 --- a/src/compiler/sema_builtins.c +++ b/src/compiler/sema_builtins.c @@ -472,7 +472,7 @@ bool sema_expr_analyse_str_wide(SemaContext *context, Expr *expr, BuiltinFunctio data += increment - 1; if (!from_codepoint) { - RETURN_SEMA_ERROR(inner, "Unparsable codepoint in string."); + RETURN_SEMA_ERROR(inner, "Unparseable codepoint in string."); } if (type == type_ushort && from_codepoint & 0xFFFF0000) { diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 882d6698a..063fadba6 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -273,7 +273,7 @@ bool sema_error_failed_cast(SemaContext *context, Expr *expr, Type *from, Type * */ Type *type_infer_len_from_actual_type(Type *to_infer, Type *actual_type) { - // This may be called on types not inferable, + // This may be called on types not inferrable, // if so we assume the original type if (!type_len_is_inferred(to_infer)) return to_infer; diff --git a/src/compiler/sema_const.c b/src/compiler/sema_const.c index 3b1a3dfcb..3ed085605 100644 --- a/src/compiler/sema_const.c +++ b/src/compiler/sema_const.c @@ -297,7 +297,7 @@ static inline ConstInitializer *expr_const_initializer_from_expr(Expr *expr) * * 1. String/Bytes + ... => String/Bytes * 2. Vector/slice/array + Untyped list => Merged untyped list - * 3. Vector/slice/array + arraylike => vector/array iff canonical match, otherwise Untyped list + * 3. Vector/slice/array + arraylike => vector/array iff canoncial match, otherwise Untyped list * 4. Untyped list + Vector/array/slice => Merged untyped list * 5. Vector/array/slice + element => Vector/array/slice + 1 len iff canonical match, Untyped list otherwise * 6. Untyped list + element => Untyped list diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 4f6631ea5..abf68a5d1 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -48,7 +48,7 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit); -static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params, SourceSpan from_span); +static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params); static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param); static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl); @@ -541,7 +541,7 @@ static bool sema_analyse_struct_members(SemaContext *context, Decl *decl) AlignSize member_type_alignment; if (type_is_user_defined(member_type) && member_type->decl->resolve_status == RESOLVE_RUNNING) { - SEMA_ERROR(member, "Recursive definition of %s.", type_quoted_error_string(member_type)); + SEMA_ERROR(member, "Recursive defintion of %s.", type_quoted_error_string(member_type)); return decl_poison(decl); } if (!sema_set_abi_alignment(context, member->type, &member_type_alignment)) return decl_poison(decl); @@ -4626,11 +4626,6 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local, bool *c return decl_poison(decl); } - if (decl->var.no_init && decl->var.init_expr) - { - SEMA_ERROR(decl->var.init_expr, "'@noinit' variables may not have initializers."); - return decl_poison(decl); - } if (erase_decl) { decl->decl_kind = DECL_ERASED; @@ -4851,7 +4846,7 @@ static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit) return copy; } -static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params, SourceSpan from_span) +static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params) { unsigned decls = 0; Decl* params_decls[MAX_PARAMS]; @@ -4902,7 +4897,6 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, new_module->contracts = astid(copy_ast_macro(astptr(module->contracts))); copy_end(); } - new_module->inlined_at = (InliningSpan) { .span = from_span, .prev = copy_inlining_span(context->inlined_at) }; return new_module; } @@ -5152,15 +5146,15 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con AnalysisStage stage = c->unit->module->generic_module ? c->unit->module->stage : c->unit->module->stage - 1; - bool instantiation = false; + bool instatiation = false; if (!instantiated_module) { - instantiation = true; + instatiation = true; Path *path = CALLOCS(Path); path->module = path_string; path->span = module->name->span; path->len = scratch_buffer.len; - instantiated_module = module_instantiate_generic(c, module, path, params, invocation_span); + instantiated_module = module_instantiate_generic(c, module, path, params); if (!instantiated_module) return poisoned_decl; if (!sema_generate_parameterized_name_to_scratch(c, module, params, false, NULL)) return poisoned_decl; instantiated_module->generic_suffix = scratch_buffer_copy(); @@ -5173,7 +5167,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con sema_error_at(c, span, "The generic module '%s' does not have '%s' for this parameterization.", module->name->module, name); return poisoned_decl; } - if (instantiation) + if (instatiation) { if (instantiated_module->contracts) { diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 5c9c887dd..4c01626a3 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -216,22 +216,19 @@ static Type *defer_iptr_cast(Expr *maybe_pointer); typedef struct { bool in_no_eval; - InliningSpan *old_inlining; } ContextSwitchState; static inline ContextSwitchState context_switch_state_push(SemaContext *context, SemaContext *new_context) { - ContextSwitchState state = { .in_no_eval = new_context->call_env.in_no_eval, .old_inlining = new_context->inlined_at }; + ContextSwitchState state = { .in_no_eval = new_context->call_env.in_no_eval, }; new_context->call_env.in_no_eval = context->call_env.in_no_eval; - new_context->inlined_at = context->inlined_at; return state; } static inline void context_switch_stat_pop(SemaContext *swapped, ContextSwitchState state) { swapped->call_env.in_no_eval = state.in_no_eval; - swapped->inlined_at = state.old_inlining; } Expr *sema_enter_inline_member(Expr *parent, CanonicalType *type) @@ -3810,15 +3807,11 @@ static inline bool sema_expr_resolve_subscript_index(SemaContext *context, Expr if (!subscript_type) { if (check_valid) return false; - switch (overload_type) + if (overload_type == OVERLOAD_ELEMENT_REF) { - case OVERLOAD_ELEMENT_REF: - RETURN_SEMA_ERROR(expr, "Getting a reference to a subscript of %s is not possible.", type_quoted_error_string(subscripted->type)); - case OVERLOAD_ELEMENT_SET: - RETURN_SEMA_ERROR(expr, "Assigning to a subscript of %s is not possible.", type_quoted_error_string(subscripted->type)); - default: - RETURN_SEMA_ERROR(expr, "Indexing a value of type %s is not possible.", type_quoted_error_string(subscripted->type)); + RETURN_SEMA_ERROR(expr, "Getting a reference to a subscript of %s is not possible.", type_quoted_error_string(subscripted->type)); } + RETURN_SEMA_ERROR(expr, "Indexing a value of type %s is not possible.", type_quoted_error_string(subscripted->type)); } if (!overload) current_type = type_flatten(current_expr->type); } @@ -3912,7 +3905,7 @@ SKIP: return true; } -static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr *expr, bool *failed_ref) +static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr *expr, bool check_valid) { // Evaluate the expression to index. Expr *subscripted = exprptr(expr->subscript_expr.expr); @@ -3951,11 +3944,12 @@ static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr Decl *overload; Type *subscript_type; int64_t index_value; - if (!sema_expr_resolve_subscript_index(context, expr, subscripted, index, ¤t_type, ¤t_expr, &subscript_type, &overload, &index_value, false, OVERLOAD_ELEMENT_SET, failed_ref != NULL)) + if (!sema_expr_resolve_subscript_index(context, expr, subscripted, index, ¤t_type, ¤t_expr, &subscript_type, &overload, &index_value, false, OVERLOAD_ELEMENT_SET, check_valid)) { - if (failed_ref && expr_ok(index)) + if (check_valid && expr_ok(index)) { - *failed_ref = true; + expr_poison(expr); + return true; } return false; } @@ -3965,7 +3959,7 @@ static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr { if (index_value == -1) { - if (failed_ref) goto VALID_FAIL_POISON; + if (check_valid) goto VALID_FAIL_POISON; RETURN_SEMA_ERROR(index, "Assigning to a compile time constant requires a constant index."); } expr->expr_kind = EXPR_CT_SUBSCRIPT; @@ -3984,7 +3978,7 @@ static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr Decl *len = sema_find_untyped_operator(current_expr->type, OVERLOAD_LEN, NULL); if (!len) { - if (failed_ref) goto VALID_FAIL_POISON; + if (check_valid) goto VALID_FAIL_POISON; RETURN_SEMA_ERROR(subscripted, "Cannot index '%s' from the end, since there is no 'len' overload.", type_to_error_string(subscripted->type)); } if (!sema_analyse_expr(context, current_expr)) return false; @@ -4018,9 +4012,9 @@ static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr // Check range bool remove_from_back = false; if (!sema_slice_index_is_in_range(context, current_type, index, false, start_from_end, &remove_from_back, - failed_ref != NULL)) + check_valid)) { - if (failed_ref) goto VALID_FAIL_POISON; + if (check_valid) goto VALID_FAIL_POISON; return false; } if (remove_from_back) @@ -4032,8 +4026,8 @@ static inline bool sema_expr_analyse_subscript_lvalue(SemaContext *context, Expr expr->type = type_add_optional(subscript_type, optional); return true; VALID_FAIL_POISON: - *failed_ref = true; - return false; + expr_poison(expr); + return true; } static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr, CheckType check, bool check_valid) @@ -5965,7 +5959,7 @@ static inline bool sema_expr_analyse_swizzle(SemaContext *context, Expr *expr, E }; if (is_lvalue) { - if (!sema_expr_analyse_subscript_lvalue(context, expr, NULL)) return false; + if (!sema_expr_analyse_subscript_lvalue(context, expr, false)) return false; } else { @@ -9123,7 +9117,7 @@ static inline bool sema_expr_analyse_or_error(SemaContext *context, Expr *expr, EndJump active_scope_jump = context->active_scope.end_jump; - // First we analyse the "else" and try to implicitly cast. + // First we analyse the "else" and try to implictly cast. if (!sema_analyse_inferred_expr(context, infer_type, right, NULL)) return false; if (left->expr_kind == EXPR_OPTIONAL) @@ -9195,7 +9189,7 @@ static inline bool sema_expr_analyse_binary(SemaContext *context, Type *infer_ty { if (left->expr_kind != EXPR_TYPEINFO) { - if (!sema_analyse_expr_lvalue(context, left, failed_ref)) return false; + if (!sema_analyse_expr_lvalue(context, left, NULL)) return false; } } else @@ -11004,7 +10998,7 @@ static inline bool sema_expr_analyse_builtin(SemaContext *context, Expr *expr, b static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr *expr, bool *no_match_ref) { TypeInfo *type_info = expr->expr_compound_literal.type_info; - // We allow inferring the size of arrays. + // We allow infering the size of arrays. if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_INFER)) return false; Type *type = type_info->type; if (type_is_optional(type)) @@ -11456,7 +11450,7 @@ RETRY: case EXPR_CT_IDENT: return sema_expr_resolve_ct_identifier(context, expr); case EXPR_SUBSCRIPT: - return sema_expr_analyse_subscript_lvalue(context, expr, failed_ref); + return sema_expr_analyse_subscript_lvalue(context, expr, false); case EXPR_OTHER_CONTEXT: { DEBUG_LOG("Switch context"); diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 8b21eee99..eece104fd 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -327,7 +327,6 @@ static inline Expr *sema_dive_into_expression(Expr *expr) { case EXPR_RVALUE: case EXPR_RECAST: - case EXPR_PTR_ACCESS: expr = expr->inner_expr; continue; case EXPR_MAKE_SLICE: @@ -631,18 +630,8 @@ INLINE bool sema_check_not_stack_variable_escape(SemaContext *context, Expr *exp expr = expr->unary_expr.expr; CHECK_ACCESS: ASSERT_SPAN(expr, expr->resolve_status == RESOLVE_DONE); - // &foo.bar.baz => foo - while (expr->expr_kind == EXPR_ACCESS_RESOLVED) - { - // If we indexed into something, like &foo.bar.baz[3] - if (allow_pointer) - { - // Then if foo.bar.baz was a pointer or slice, that's ok. - TypeKind kind = type_flatten(expr->type)->type_kind; - if (kind == TYPE_POINTER || kind == TYPE_SLICE) return true; - } - expr = expr->access_resolved_expr.parent; - } + while (expr->expr_kind == EXPR_ACCESS_RESOLVED) expr = expr->access_resolved_expr.parent; + if (expr->expr_kind != EXPR_IDENTIFIER) return true; Decl *decl = expr->ident_expr; if (decl->decl_kind != DECL_VAR) return true; @@ -650,8 +639,6 @@ CHECK_ACCESS: { case VARDECL_LOCAL: if (decl->var.is_static) return true; - FALLTHROUGH; - case VARDECL_PARAM: switch (type_flatten(decl->type)->type_kind) { case TYPE_POINTER: @@ -662,12 +649,15 @@ CHECK_ACCESS: default: break; } + FALLTHROUGH; + case VARDECL_PARAM: break; default: return true; } - RETURN_SEMA_ERROR(outer, "A pointer to a local variable will be invalid once the function returns. " + SEMA_ERROR(outer, "A pointer to a local variable will be invalid once the function returns. " "Allocate the data on the heap or temp memory to return a pointer."); + return false; } /** diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 75bea07ba..9fdfedd76 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -592,17 +592,6 @@ void sema_print_inline(SemaContext *context, SourceSpan original) } inlined_at = inlined_at->prev; } - InliningSpan span = context->compilation_unit->module->inlined_at; - if (span.span.a == INVALID_SPAN.a) return; - inlined_at = &span; - while (inlined_at) - { - if (inlined_at->span.a != original.a) - { - sema_note_prev_at(inlined_at->span, "Inlined from here."); - } - inlined_at = inlined_at->prev; - } } void sema_error_at(SemaContext *context, SourceSpan span, const char *message, ...) diff --git a/src/compiler_tests/tests.c b/src/compiler_tests/tests.c index 0c9ef5433..9863ac6f9 100644 --- a/src/compiler_tests/tests.c +++ b/src/compiler_tests/tests.c @@ -19,146 +19,146 @@ void test_file(void) void test128() { printf("Begin i128 testing.\n"); - Int128 address = i128_add(i128(0x123, 0x123), i128(0x222, 0x333)); - TEST_ASSERTF(address.high == 0x345 && address.low == 0x456, "i128 add failed with small numbers was %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_add(i128(0x123, UINT64_MAX), i128(0x222, 0x1)); - TEST_ASSERT(address.high == 0x346 && address.low == 0, "i128 add failed with simple overflow"); - address = i128_add(i128(0x123, UINT64_MAX), i128(0x222, UINT64_MAX)); - TEST_ASSERT(address.high == 0x346 && address.low == UINT64_MAX - 1, "i128 add failed with simple overflow2"); - address = i128_add(i128(UINT64_MAX, UINT64_MAX), i128(0x0, 0x1)); - TEST_ASSERT(address.high == 0 && address.low == 0, "i128 add failed with wrap"); - address = i128_add(i128(UINT64_MAX, UINT64_MAX), i128(UINT64_MAX, UINT64_MAX)); - TEST_ASSERT(address.high == UINT64_MAX && address.low == UINT64_MAX - 1, "i128 add failed overflow with wrap"); + Int128 addres = i128_add(i128(0x123, 0x123), i128(0x222, 0x333)); + TEST_ASSERTF(addres.high == 0x345 && addres.low == 0x456, "i128 add failed with small numbers was %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_add(i128(0x123, UINT64_MAX), i128(0x222, 0x1)); + TEST_ASSERT(addres.high == 0x346 && addres.low == 0, "i128 add failed with simple overflow"); + addres = i128_add(i128(0x123, UINT64_MAX), i128(0x222, UINT64_MAX)); + TEST_ASSERT(addres.high == 0x346 && addres.low == UINT64_MAX - 1, "i128 add failed with simple overflow2"); + addres = i128_add(i128(UINT64_MAX, UINT64_MAX), i128(0x0, 0x1)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "i128 add failed with wrap"); + addres = i128_add(i128(UINT64_MAX, UINT64_MAX), i128(UINT64_MAX, UINT64_MAX)); + TEST_ASSERT(addres.high == UINT64_MAX && addres.low == UINT64_MAX - 1, "i128 add failed overflow with wrap"); printf("-- i128 Add - Ok.\n"); - address = i128_sub(i128(0x345, 0x457), i128(0x222, 0x333)); - TEST_ASSERTF(address.high == 0x123 && address.low == 0x124, "i128 sub failed with small numbers was %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_sub(i128(0x346, 0), i128(0x222, 0x1)); - TEST_ASSERTF(address.high == 0x123 && address.low == UINT64_MAX, "i128 sub failed with simple overflow %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_sub(i128(0x346, UINT64_MAX - 1), i128(0x222, UINT64_MAX)); - TEST_ASSERT(address.high == 0x123 && address.low == UINT64_MAX, "i128 sub failed with simple overflow2"); - address = i128_sub(i128(0, 0), i128(0x0, 0x1)); - TEST_ASSERTF(address.high == UINT64_MAX && address.low == UINT64_MAX, "i128 sub failed with wrap %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_sub(i128(UINT64_MAX, UINT64_MAX - 1), i128(UINT64_MAX, UINT64_MAX)); - TEST_ASSERT(address.high == UINT64_MAX && address.low == UINT64_MAX, "i128 sub failed overflow with wrap"); + addres = i128_sub(i128(0x345, 0x457), i128(0x222, 0x333)); + TEST_ASSERTF(addres.high == 0x123 && addres.low == 0x124, "i128 sub failed with small numbers was %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_sub(i128(0x346, 0), i128(0x222, 0x1)); + TEST_ASSERTF(addres.high == 0x123 && addres.low == UINT64_MAX, "i128 sub failed with simple overflow %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_sub(i128(0x346, UINT64_MAX - 1), i128(0x222, UINT64_MAX)); + TEST_ASSERT(addres.high == 0x123 && addres.low == UINT64_MAX, "i128 sub failed with simple overflow2"); + addres = i128_sub(i128(0, 0), i128(0x0, 0x1)); + TEST_ASSERTF(addres.high == UINT64_MAX && addres.low == UINT64_MAX, "i128 sub failed with wrap %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_sub(i128(UINT64_MAX, UINT64_MAX - 1), i128(UINT64_MAX, UINT64_MAX)); + TEST_ASSERT(addres.high == UINT64_MAX && addres.low == UINT64_MAX, "i128 sub failed overflow with wrap"); printf("-- i128 Sub - Ok.\n"); - address = i128_and(i128(0x0, 0x0), i128(UINT64_MAX, UINT64_MAX)); - TEST_ASSERT(address.high == 0 && address.low == 0, "And failed"); - address = i128_and(i128(0x123, 0x123456789abcdef1), i128(UINT64_MAX, UINT64_MAX)); - TEST_ASSERT(address.high == 0x123 && address.low == 0x123456789abcdef1, "And failed"); - address = i128_and(i128(0xabcdef2233, 0x123456789A), i128(0x0F0F0F0F0F0F, 0xF0F0F0F0F0F0)); - TEST_ASSERT(address.high == 0x0b0d0f0203 && address.low == 0x1030507090, "And failed"); + addres = i128_and(i128(0x0, 0x0), i128(UINT64_MAX, UINT64_MAX)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "And failed"); + addres = i128_and(i128(0x123, 0x123456789abcdef1), i128(UINT64_MAX, UINT64_MAX)); + TEST_ASSERT(addres.high == 0x123 && addres.low == 0x123456789abcdef1, "And failed"); + addres = i128_and(i128(0xabcdef2233, 0x123456789A), i128(0x0F0F0F0F0F0F, 0xF0F0F0F0F0F0)); + TEST_ASSERT(addres.high == 0x0b0d0f0203 && addres.low == 0x1030507090, "And failed"); printf("-- i128 And - Ok.\n"); - address = i128_or(i128(0x0, 0x0), i128(UINT64_MAX, UINT64_MAX)); - TEST_ASSERT(address.high == UINT64_MAX && address.low == UINT64_MAX, "Or failed"); - address = i128_or(i128(0x123, 0x123456789abcdef1), i128(0x123203, 0x0)); - TEST_ASSERT(address.high == 0x123323 && address.low == 0x123456789abcdef1, "Or failed"); - address = i128_or(i128(0xabcdef2233, 0x123456789A), i128(0x0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0)); - TEST_ASSERTF(address.high == 0x0FAFCFEF2F3F && address.low == 0xF0F0F2F4F6F8FA, "Or failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + addres = i128_or(i128(0x0, 0x0), i128(UINT64_MAX, UINT64_MAX)); + TEST_ASSERT(addres.high == UINT64_MAX && addres.low == UINT64_MAX, "Or failed"); + addres = i128_or(i128(0x123, 0x123456789abcdef1), i128(0x123203, 0x0)); + TEST_ASSERT(addres.high == 0x123323 && addres.low == 0x123456789abcdef1, "Or failed"); + addres = i128_or(i128(0xabcdef2233, 0x123456789A), i128(0x0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0)); + TEST_ASSERTF(addres.high == 0x0FAFCFEF2F3F && addres.low == 0xF0F0F2F4F6F8FA, "Or failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Or - Ok.\n"); - address = i128_xor(i128(0x0, 0x0), i128(UINT64_MAX, UINT64_MAX)); - TEST_ASSERT(address.high == UINT64_MAX && address.low == UINT64_MAX, "Xor failed"); - address = i128_xor(i128(0x123, 0x123456789abcdef1), i128(0x123223, 0x0)); - TEST_ASSERT(address.high == 0x123300 && address.low == 0x123456789abcdef1, "Xor failed"); - address = i128_xor(i128(0xabcdef2233, 0x123456789A), i128(0x0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0)); - TEST_ASSERTF(address.high == 0x0FA4C2E02d3c && address.low == 0xF0F0e2c4a6886A, "Xor failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + addres = i128_xor(i128(0x0, 0x0), i128(UINT64_MAX, UINT64_MAX)); + TEST_ASSERT(addres.high == UINT64_MAX && addres.low == UINT64_MAX, "Xor failed"); + addres = i128_xor(i128(0x123, 0x123456789abcdef1), i128(0x123223, 0x0)); + TEST_ASSERT(addres.high == 0x123300 && addres.low == 0x123456789abcdef1, "Xor failed"); + addres = i128_xor(i128(0xabcdef2233, 0x123456789A), i128(0x0F0F0F0F0F0F, 0xF0F0F0F0F0F0F0)); + TEST_ASSERTF(addres.high == 0x0FA4C2E02d3c && addres.low == 0xF0F0e2c4a6886A, "Xor failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Xor - Ok.\n"); - address = i128_neg(i128(0x0, 0x0)); - TEST_ASSERT(address.high == 0 && address.low == 0, "Neg failed"); - address = i128_neg(i128(0x123, 0x123456789abcdef1)); - TEST_ASSERT(address.high == ~((uint64_t)0x123) && address.low == ~(uint64_t)0x123456789abcdef0, "Neg failed"); - address = i128_neg(i128(0xabcdef2233, 0x123456789A)); - TEST_ASSERTF(address.high == ~(uint64_t)0xabcdef2233 && address.low == ~(uint64_t)0x1234567899, "Neg failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + addres = i128_neg(i128(0x0, 0x0)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "Neg failed"); + addres = i128_neg(i128(0x123, 0x123456789abcdef1)); + TEST_ASSERT(addres.high == ~((uint64_t)0x123) && addres.low == ~(uint64_t)0x123456789abcdef0, "Neg failed"); + addres = i128_neg(i128(0xabcdef2233, 0x123456789A)); + TEST_ASSERTF(addres.high == ~(uint64_t)0xabcdef2233 && addres.low == ~(uint64_t)0x1234567899, "Neg failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Neg - Ok.\n"); - address = i128_from_str("1123"); - TEST_ASSERT(address.high == 0 && address.low == 1123, "Init failed"); - address = i128_from_str("10000000000000000000012344434232"); - TEST_ASSERT(address.high == 0x7e37be2022 && address.low == 0xc0914b295fc91e38, "Init failed"); + addres = i128_from_str("1123"); + TEST_ASSERT(addres.high == 0 && addres.low == 1123, "Init failed"); + addres = i128_from_str("10000000000000000000012344434232"); + TEST_ASSERT(addres.high == 0x7e37be2022 && addres.low == 0xc0914b295fc91e38, "Init failed"); - address = i128_mult(i128(0x111, 0x222), i128(0, 2)); - TEST_ASSERTF(address.high == 0x222 && address.low == 0x444, "Mult failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_mult(i128(0x111, 0x222), i128(2, 0)); - TEST_ASSERTF(address.high == 0x444 && address.low == 0, "Mult failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_mult(i128_from_str("523871293871232000123"), i128_from_str("283712312938293299")); + addres = i128_mult(i128(0x111, 0x222), i128(0, 2)); + TEST_ASSERTF(addres.high == 0x222 && addres.low == 0x444, "Mult failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_mult(i128(0x111, 0x222), i128(2, 0)); + TEST_ASSERTF(addres.high == 0x444 && addres.low == 0, "Mult failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_mult(i128_from_str("523871293871232000123"), i128_from_str("283712312938293299")); - TEST_ASSERTF(i128_ucomp(i128_from_str("148628736466183585621117368965778075777"), address) == CMP_EQ, "Mult failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + TEST_ASSERTF(i128_ucomp(i128_from_str("148628736466183585621117368965778075777"), addres) == CMP_EQ, "Mult failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Mult ok.\n"); - TEST_ASSERTF(i128_ucomp(i128_from_str("123"), i128_from_str("123")) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128_from_str("123"), i128_from_str("124")) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128_from_str("123"), i128_from_str("121")) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128(0x222, 0x111), i128(0x111, 0x222)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128(0x111, 0x222), i128(0x222, 0x111)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128(0x222, 0x111), i128(0x222, 0x111)) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128(UINT64_MAX, 0x111), i128(0x111, 0x222)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_ucomp(i128(0x111, 0x222), i128(UINT64_MAX, 0x111)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + TEST_ASSERTF(i128_ucomp(i128_from_str("123"), i128_from_str("123")) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128_from_str("123"), i128_from_str("124")) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128_from_str("123"), i128_from_str("121")) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128(0x222, 0x111), i128(0x111, 0x222)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128(0x111, 0x222), i128(0x222, 0x111)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128(0x222, 0x111), i128(0x222, 0x111)) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128(UINT64_MAX, 0x111), i128(0x111, 0x222)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_ucomp(i128(0x111, 0x222), i128(UINT64_MAX, 0x111)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Ucomp ok.\n"); - TEST_ASSERTF(i128_scomp(i128_from_str("123"), i128_from_str("123")) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128_from_str("123"), i128_from_str("124")) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128_from_str("123"), i128_from_str("121")) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128(0x222, 0x111), i128(0x111, 0x222)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128(0x111, 0x222), i128(0x222, 0x111)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128(0x222, 0x111), i128(0x222, 0x111)) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128(UINT64_MAX, 0x111), i128(0x111, 0x222)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - TEST_ASSERTF(i128_scomp(i128(0x111, 0x222), i128(UINT64_MAX, 0x111)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + TEST_ASSERTF(i128_scomp(i128_from_str("123"), i128_from_str("123")) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128_from_str("123"), i128_from_str("124")) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128_from_str("123"), i128_from_str("121")) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128(0x222, 0x111), i128(0x111, 0x222)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128(0x111, 0x222), i128(0x222, 0x111)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128(0x222, 0x111), i128(0x222, 0x111)) == CMP_EQ, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128(UINT64_MAX, 0x111), i128(0x111, 0x222)) == CMP_LT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + TEST_ASSERTF(i128_scomp(i128(0x111, 0x222), i128(UINT64_MAX, 0x111)) == CMP_GT, "Comp failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Scomp ok.\n"); - address = i128_shl(i128(0x234, 0x123456), i128(0, 0x4)); - TEST_ASSERT(address.high == 0x2340 && address.low == 0x1234560, "shl failed"); - address = i128_shl(i128(0x234, 0x1234561), i128(0, 128)); - TEST_ASSERT(address.high == 0 && address.low == 0, "shl failed"); - address = i128_shl(i128(0x234, 0x1234561), i128(1, 1)); - TEST_ASSERT(address.high == 0 && address.low == 0, "shl failed"); - address = i128_shl(i128(0x234, 0x1234561), i128(0, 64)); - TEST_ASSERT(address.high == 0x1234561 && address.low == 0, "shl failed"); + addres = i128_shl(i128(0x234, 0x123456), i128(0, 0x4)); + TEST_ASSERT(addres.high == 0x2340 && addres.low == 0x1234560, "shl failed"); + addres = i128_shl(i128(0x234, 0x1234561), i128(0, 128)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "shl failed"); + addres = i128_shl(i128(0x234, 0x1234561), i128(1, 1)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "shl failed"); + addres = i128_shl(i128(0x234, 0x1234561), i128(0, 64)); + TEST_ASSERT(addres.high == 0x1234561 && addres.low == 0, "shl failed"); printf("-- i128 Shl ok.\n"); - address = i128_lshr(i128(0x234, 0x123456), i128(0, 0x4)); - TEST_ASSERTF(address.high == 0x23 && address.low == 0x4000000000012345, "lshr failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_lshr(i128(0x234, 0x1234561), i128(0, 128)); - TEST_ASSERT(address.high == 0 && address.low == 0, "lshr failed"); - address = i128_lshr(i128(0x234, 0x1234561), i128(1, 1)); - TEST_ASSERT(address.high == 0 && address.low == 0, "lshr failed"); - address = i128_lshr(i128(0x234, 0x1234561), i128(0, 64)); - TEST_ASSERTF(address.high == 0 && address.low == 0x234, "lshr failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + addres = i128_lshr(i128(0x234, 0x123456), i128(0, 0x4)); + TEST_ASSERTF(addres.high == 0x23 && addres.low == 0x4000000000012345, "lshr failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_lshr(i128(0x234, 0x1234561), i128(0, 128)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "lshr failed"); + addres = i128_lshr(i128(0x234, 0x1234561), i128(1, 1)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "lshr failed"); + addres = i128_lshr(i128(0x234, 0x1234561), i128(0, 64)); + TEST_ASSERTF(addres.high == 0 && addres.low == 0x234, "lshr failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Lshr ok.\n"); - address = i128_ashr(i128(0x234, 0x123456), i128(0, 0x4)); - TEST_ASSERTF(address.high == 0x23 && address.low == 0x4000000000012345, "ashr failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_ashr(i128(0xF000000000000234, 0x123456), i128(0, 0x4)); - TEST_ASSERTF(address.high == 0xFF00000000000023 && address.low == 0x4000000000012345, "ashr failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_ashr(i128(0x234, 0x1234561), i128(0, 128)); - TEST_ASSERT(address.high == 0 && address.low == 0, "ashr failed"); - address = i128_ashr(i128(0xF000000000000234, 0x1234561), i128(0, 128)); - TEST_ASSERT(address.high == UINT64_MAX && address.low == UINT64_MAX, "ashr failed"); - address = i128_ashr(i128(0x234, 0x1234561), i128(1, 1)); - TEST_ASSERT(address.high == 0 && address.low == 0, "ashr failed"); - address = i128_ashr(i128(0xF000000000000234, 0x1234561), i128(1, 1)); - TEST_ASSERT(address.high == UINT64_MAX && address.low == UINT64_MAX, "ashr failed"); - address = i128_ashr(i128(0x234, 0x1234561), i128(0, 64)); - TEST_ASSERTF(address.high == 0 && address.low == 0x234, "ashr failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); - address = i128_ashr(i128(0xF000000000000234, 0x1234561), i128(0, 64)); - TEST_ASSERTF(address.high == UINT64_MAX && address.low == 0xF000000000000234, "ashr failed %llx, %llx", (unsigned long long)address.high, (unsigned long long)address.low); + addres = i128_ashr(i128(0x234, 0x123456), i128(0, 0x4)); + TEST_ASSERTF(addres.high == 0x23 && addres.low == 0x4000000000012345, "ashr failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_ashr(i128(0xF000000000000234, 0x123456), i128(0, 0x4)); + TEST_ASSERTF(addres.high == 0xFF00000000000023 && addres.low == 0x4000000000012345, "ashr failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_ashr(i128(0x234, 0x1234561), i128(0, 128)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "ashr failed"); + addres = i128_ashr(i128(0xF000000000000234, 0x1234561), i128(0, 128)); + TEST_ASSERT(addres.high == UINT64_MAX && addres.low == UINT64_MAX, "ashr failed"); + addres = i128_ashr(i128(0x234, 0x1234561), i128(1, 1)); + TEST_ASSERT(addres.high == 0 && addres.low == 0, "ashr failed"); + addres = i128_ashr(i128(0xF000000000000234, 0x1234561), i128(1, 1)); + TEST_ASSERT(addres.high == UINT64_MAX && addres.low == UINT64_MAX, "ashr failed"); + addres = i128_ashr(i128(0x234, 0x1234561), i128(0, 64)); + TEST_ASSERTF(addres.high == 0 && addres.low == 0x234, "ashr failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); + addres = i128_ashr(i128(0xF000000000000234, 0x1234561), i128(0, 64)); + TEST_ASSERTF(addres.high == UINT64_MAX && addres.low == 0xF000000000000234, "ashr failed %llx, %llx", (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Ashr ok.\n"); TEST_ASSERT(i128_ucomp(i128_udiv(i128_from_str("123"), i128_from_str("123")), i128_from_str("1")) == CMP_EQ, "Div failed"); TEST_ASSERT(i128_ucomp(i128_udiv(i128_from_str("123"), i128_from_str("124")), i128_from_str("0")) == CMP_EQ, "Div failed"); TEST_ASSERT(i128_ucomp(i128_udiv(i128_from_str("245"), i128_from_str("123")), i128_from_str("1")) == CMP_EQ, "Div failed"); - address = i128_udiv(i128(0x12345, UINT64_MAX), i128(1, 0)); - TEST_ASSERT(address.low == 0x12345 && address.high == 0, "Div failed"); - address = i128_sdiv(i128(0x12345, UINT64_MAX), i128(1, 0)); - TEST_ASSERT(address.low == 0x12345 && address.high == 0, "Div failed"); - address = i128_udiv(i128(UINT64_MAX, 0), i128(1, 0)); - TEST_ASSERT(address.low == UINT64_MAX && address.high == 0, "Div failed"); - address = i128_sdiv(i128(UINT64_MAX - 1, UINT64_MAX - 1), i128(1, 0)); - TEST_ASSERTF(address.low == UINT64_MAX && address.high == UINT64_MAX, "Div failed %s", i128_to_string(address, 10, + addres = i128_udiv(i128(0x12345, UINT64_MAX), i128(1, 0)); + TEST_ASSERT(addres.low == 0x12345 && addres.high == 0, "Div failed"); + addres = i128_sdiv(i128(0x12345, UINT64_MAX), i128(1, 0)); + TEST_ASSERT(addres.low == 0x12345 && addres.high == 0, "Div failed"); + addres = i128_udiv(i128(UINT64_MAX, 0), i128(1, 0)); + TEST_ASSERT(addres.low == UINT64_MAX && addres.high == 0, "Div failed"); + addres = i128_sdiv(i128(UINT64_MAX - 1, UINT64_MAX - 1), i128(1, 0)); + TEST_ASSERTF(addres.low == UINT64_MAX && addres.high == UINT64_MAX, "Div failed %s", i128_to_string(addres, 10, true, false)); - address = i128_sdiv(i128(2, 0), i128(UINT64_MAX - 1, UINT64_MAX - 1)); + addres = i128_sdiv(i128(2, 0), i128(UINT64_MAX - 1, UINT64_MAX - 1)); printf("-- i128 Div okfefe %x.\n", (unsigned)-2); - TEST_ASSERTF(address.low == UINT64_MAX && address.high == UINT64_MAX, "Div failed: %s %llx, %llx", i128_to_string( - address, 10, true, false), (unsigned long long)address.high, (unsigned long long)address.low); + TEST_ASSERTF(addres.low == UINT64_MAX && addres.high == UINT64_MAX, "Div failed: %s %llx, %llx", i128_to_string( + addres, 10, true, false), (unsigned long long)addres.high, (unsigned long long)addres.low); printf("-- i128 Div ok.\n"); diff --git a/src/utils/lib.h b/src/utils/lib.h index 42eab7569..5d150067b 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -147,7 +147,7 @@ int str_findlist(const char *value, unsigned count, const char** elements); // Sprintf style, saved to an arena allocated string char *str_printf(const char *var, ...) __printflike(1, 2); char *str_vprintf(const char *var, va_list list); -void str_elide_in_place(char *string, size_t max_size_shown); +void str_ellide_in_place(char *string, size_t max_size_shown); bool str_is_valid_lowercase_name(const char *string); bool str_is_valid_constant(const char *string); const char *str_unescape(char *string); diff --git a/src/utils/stringutils.c b/src/utils/stringutils.c index 1a6d65e47..ec39c0a82 100644 --- a/src/utils/stringutils.c +++ b/src/utils/stringutils.c @@ -168,7 +168,7 @@ bool str_is_valid_constant(const char *string) return true; } -void str_elide_in_place(char *string, size_t max_size_shown) +void str_ellide_in_place(char *string, size_t max_size_shown) { size_t len = strlen(string); if (max_size_shown > len) return; diff --git a/src/version.h b/src/version.h index d92f017ad..877a52b0b 100644 --- a/src/version.h +++ b/src/version.h @@ -1,2 +1,2 @@ -#define COMPILER_VERSION "0.7.6" -#define PRERELEASE 1 +#define COMPILER_VERSION "0.7.5" +#define PRERELEASE 0 diff --git a/test/src/test_suite_runner.c3 b/test/src/test_suite_runner.c3 index 5fe827a04..73098da91 100644 --- a/test/src/test_suite_runner.c3 +++ b/test/src/test_suite_runner.c3 @@ -24,7 +24,7 @@ fn int main(String[] args) // Retain our current path. start_cwd = path::tcwd()!!; - // Create our test path, note that this prevents us from doing tests in parallel + // Create our test path, note that this prevents us from doing tests in parallell test_dir = start_cwd.tappend("_c3test_")!!; defer (void)path::rmtree(test_dir); diff --git a/test/test_suite/cast/cast_string_to_inferred_array.c3 b/test/test_suite/cast/cast_string_to_infered_array.c3 similarity index 100% rename from test/test_suite/cast/cast_string_to_inferred_array.c3 rename to test/test_suite/cast/cast_string_to_infered_array.c3 diff --git a/test/test_suite/compile_time_introspection/defined_subscript_assign.c3 b/test/test_suite/compile_time_introspection/defined_subscript_assign.c3 deleted file mode 100644 index ee696e61a..000000000 --- a/test/test_suite/compile_time_introspection/defined_subscript_assign.c3 +++ /dev/null @@ -1,14 +0,0 @@ -fn int main(String[] args) -{ - MyArray a = {{1, 4, 3, 6, 5}}; - $assert(!$defined(a[0] = 2)); - return 0; -} - -struct MyArray -{ - int[] val; -} - -fn int MyArray.get(self, usz idx) @operator([]) => self.val[idx]; -fn usz MyArray.len(self) @operator(len) => self.val.len; \ No newline at end of file diff --git a/test/test_suite/expressions/check_implicit_conversion_signed_unsigned.c3t b/test/test_suite/expressions/check_implict_conversion_signed_unsigned.c3t similarity index 100% rename from test/test_suite/expressions/check_implicit_conversion_signed_unsigned.c3t rename to test/test_suite/expressions/check_implict_conversion_signed_unsigned.c3t diff --git a/test/test_suite/expressions/fail_index_usize.c3 b/test/test_suite/expressions/fail_index_usize.c3 index f1f113d5b..438d83cde 100644 --- a/test/test_suite/expressions/fail_index_usize.c3 +++ b/test/test_suite/expressions/fail_index_usize.c3 @@ -1,5 +1,5 @@ fn void test(int* array, usz n) { array[n] = 33; - n[array] = 33; // #error: Assigning to a subscript of + n[array] = 33; // #error: Indexing a value of type } diff --git a/test/test_suite/functions/deferred_default_arguments.c3t b/test/test_suite/functions/defered_default_arguments.c3t similarity index 100% rename from test/test_suite/functions/deferred_default_arguments.c3t rename to test/test_suite/functions/defered_default_arguments.c3t diff --git a/test/test_suite/functions/slice_escape.c3 b/test/test_suite/functions/slice_escape.c3 deleted file mode 100644 index 57475cb17..000000000 --- a/test/test_suite/functions/slice_escape.c3 +++ /dev/null @@ -1,16 +0,0 @@ -fn int* test() -{ - int[3] x = { 1, 2, 4 }; - return (int[])&x; // #error: A pointer to a local variable will be invalid once the function returns. Allocate the data on the heap or temp memory to return a pointer -} -fn int main(String[] args) -{ - MyArray a; - - return 0; -} -struct MyArray -{ - int[] val; -} -fn int* MyArray.get_ref(self, usz idx) => &self.val[idx]; \ No newline at end of file diff --git a/test/test_suite/methods/subscript_set_error.c3 b/test/test_suite/methods/subscript_set_error.c3 deleted file mode 100644 index 723c936e1..000000000 --- a/test/test_suite/methods/subscript_set_error.c3 +++ /dev/null @@ -1,14 +0,0 @@ -fn int main(String[] args) -{ - MyArray a = {{1, 4, 3, 6, 5}}; - a[0] = a[1]; // #error: Assigning to a subscript of 'MyArray' is not possible - return 0; -} - -struct MyArray -{ - int[] val; -} - -fn int MyArray.get(self, usz idx) @operator([]) => self.val[idx]; -fn usz MyArray.len(self) @operator(len) => self.val.len; \ No newline at end of file diff --git a/test/test_suite/statements/fallthrough_do.c3t b/test/test_suite/statements/fallthough_do.c3t similarity index 100% rename from test/test_suite/statements/fallthrough_do.c3t rename to test/test_suite/statements/fallthough_do.c3t diff --git a/test/test_suite/struct/member_expr.c3 b/test/test_suite/struct/member_expr.c3 index fac6c326e..fc0cbbb8d 100644 --- a/test/test_suite/struct/member_expr.c3 +++ b/test/test_suite/struct/member_expr.c3 @@ -20,12 +20,12 @@ fn void test_unknown_member() } -fn void test_nonstatic_struct_func1() +fn void test_nonstatic_stuct_func1() { Func2 a = &Foo.func2; } -fn void test_nonstatic_struct_func2() +fn void test_nonstatic_stuct_func2() { int b = Foo.func2(null, 2); } diff --git a/test/test_suite/struct/struct_recursive.c3 b/test/test_suite/struct/struct_recursive.c3 index ebbfb76c4..3e45e317c 100644 --- a/test/test_suite/struct/struct_recursive.c3 +++ b/test/test_suite/struct/struct_recursive.c3 @@ -5,5 +5,5 @@ struct GlobalNode struct Ast { - GlobalNode global; // #error: Recursive definition of 'GlobalNode' -} + GlobalNode global; // #error: Recursive defintion of 'GlobalNode' +} \ No newline at end of file diff --git a/test/test_suite/switch/switch_in_defer_macro.c3t b/test/test_suite/switch/switch_in_defer_macro.c3t index 007b66ca0..5f2433cb2 100644 --- a/test/test_suite/switch/switch_in_defer_macro.c3t +++ b/test/test_suite/switch/switch_in_defer_macro.c3t @@ -409,7 +409,7 @@ alias Kind = Kind{Token, Comment}; enum Token : char (String token) { - KEYWORD1 = "keyword1", + KEYWORD1 = "keword1", KEYWORD2 = "keyword2", SINGLE = "//", MULTI = "/*", @@ -686,11 +686,11 @@ fn void test() @.enum.MULTI = internal constant [6 x i8] c"MULTI\00", align 1 @"$ct.char" = linkonce global %.introspect { i8 3, i64 0, ptr null, i64 1, i64 0, i64 0, [0 x i64] zeroinitializer }, align 8 @"$ct.lexer_test.Token" = linkonce global { i8, i64, ptr, i64, i64, i64, [4 x %"char[]"] } { i8 8, i64 0, ptr null, i64 1, i64 ptrtoint (ptr @"$ct.char" to i64), i64 4, [4 x %"char[]"] [%"char[]" { ptr @.enum.KEYWORD1, i64 8 }, %"char[]" { ptr @.enum.KEYWORD2, i64 8 }, %"char[]" { ptr @.enum.SINGLE, i64 6 }, %"char[]" { ptr @.enum.MULTI, i64 5 }] }, align 8 -@.str = private unnamed_addr constant [9 x i8] c"keyword1\00", align 1 +@.str = private unnamed_addr constant [8 x i8] c"keword1\00", align 1 @.str.1 = private unnamed_addr constant [9 x i8] c"keyword2\00", align 1 @.str.2 = private unnamed_addr constant [3 x i8] c"//\00", align 1 @.str.3 = private unnamed_addr constant [3 x i8] c"/*\00", align 1 -@"lexer_test.Token$token" = linkonce constant [4 x %"char[]"] [%"char[]" { ptr @.str, i64 8 }, %"char[]" { ptr @.str.1, i64 8 }, %"char[]" { ptr @.str.2, i64 2 }, %"char[]" { ptr @.str.3, i64 2 }], align 8 +@"lexer_test.Token$token" = linkonce constant [4 x %"char[]"] [%"char[]" { ptr @.str, i64 7 }, %"char[]" { ptr @.str.1, i64 8 }, %"char[]" { ptr @.str.2, i64 2 }, %"char[]" { ptr @.str.3, i64 2 }], align 8 @"$ct.lexer_test.Comment" = linkonce global { i8, i64, ptr, i64, i64, i64, [2 x %"char[]"] } { i8 8, i64 0, ptr null, i64 1, i64 ptrtoint (ptr @"$ct.char" to i64), i64 2, [2 x %"char[]"] [%"char[]" { ptr @.enum.SINGLE, i64 6 }, %"char[]" { ptr @.enum.MULTI, i64 5 }] }, align 8 @"lexer_test.Comment$start" = linkonce constant [2 x i8] c"\02\03", align 1 @.str.4 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 diff --git a/test/test_suite/variables/noinit_with_val.c3 b/test/test_suite/variables/noinit_with_val.c3 deleted file mode 100644 index 09f114f03..000000000 --- a/test/test_suite/variables/noinit_with_val.c3 +++ /dev/null @@ -1,10 +0,0 @@ -fn int main() -{ - test(); - return 0; -} - -macro test() -{ - var x @noinit = 0; // #error: '@noinit' variables may not have initializers -} diff --git a/test/unit/stdlib/collections/anylist.c3 b/test/unit/stdlib/collections/anylist.c3 deleted file mode 100644 index 21c5186e0..000000000 --- a/test/unit/stdlib/collections/anylist.c3 +++ /dev/null @@ -1,28 +0,0 @@ -module anylist_test @test; -import std::collections::anylist; - -fn void pop() => @pool() -{ - AnyList l; - l.push(1.0); - l.push(1); - l.push("hello"); - assert(l.pop(String)!! == "hello"); - assert(l.pop(int)!! == 1); - assert(l.copy_pop(tmem)!!.type == double.typeid); -} - -fn void predicates() => @pool() -{ - AnyList l; - l.push(123u); - l.push(-1); - l.push("abc"); - l.push(5.0); - l.remove_using_test(fn (x, p) => x.type == p.type, &&456u); - assert(l[0].type == int.typeid); - assert(l.get(0, int)!! == -1); - l.retain_if(fn (x) => x.type == double.typeid); - assert(l.len() == 1); - assert(l.get(0, double)!! == 5.0); -} diff --git a/test/unit/stdlib/collections/interfacelist.c3 b/test/unit/stdlib/collections/interfacelist.c3 deleted file mode 100644 index d00ba6032..000000000 --- a/test/unit/stdlib/collections/interfacelist.c3 +++ /dev/null @@ -1,126 +0,0 @@ -module interfacelist_test @test; -import std::collections::interfacelist; -interface Test -{ - fn int test(); -} - -alias TestL = InterfaceList {Test}; - -struct Test1 (Test) -{ - int a; -} -fn int Test1.test(&self) @dynamic => self.a; - -struct Test2 (Test) -{ - String b; -} -fn int Test2.test(&self) @dynamic => (int)self.b.len; - - -fn void initialized() => @pool() -{ - TestL l; - assert(!l.is_initialized()); - l.tinit(); - assert(l.is_initialized()); -} - -fn void basic_interation() => @pool() -{ - TestL l; - l.push((Test1){1}); - l.push((Test1){1234}); - assert(to_ints(l) == {1, 1234}); - assert(l.pop_retained().test()!! == 1234); - l.push((Test1){56789}); - assert(to_ints(l) == {1, 56789}); - l.set(2, (Test2){"abc"}); - assert(to_ints(l) == {1, 56789, 3}); -} - -fn void remove_at() => @pool() -{ - TestL l; - for (int i = 0; i < 5; i++) - { - l.push((Test1){i}); - } - assert(to_ints(l) == {0, 1, 2, 3, 4}); - l.remove_at(1); - assert(to_ints(l) == {0, 2, 3, 4}); - l.remove_at(3); - assert(to_ints(l) == {0, 2, 3}); -} - -fn void remove_with_predicate() => @pool() -{ - TestL l; - l.push((Test1){1}); - l.push((Test1){1234}); - l.push((Test2){"wefhewoifw"}); - l.push((Test1){-1290987}); - l.push((Test2){"abc"}); - assert(to_ints(l) == {1, 1234, 10, -1290987, 3}); - l.remove_if(fn (val) => val.test() < 5); - assert(to_ints(l) == {1234, 10}); - l.remove_if(fn (val) => val.type == Test2.typeid); - assert(to_ints(l) == {1234}); -} - -fn void retain_with_predicate() => @pool() -{ - TestL l; - l.push((Test1){1234}); - l.push((Test1){2345}); - l.push((Test1){3456}); - l.push((Test2){"abc"}); - l.push((Test2){"defg"}); - assert(to_ints(l) == {1234, 2345, 3456, 3, 4}); - l.retain_if(fn (val) => val.test() % 2 == 0); - assert(to_ints(l) == {1234, 3456, 4}); -} - -fn void remove_with_test() => @pool() -{ - TestL l; - l.push((Test1){532}); - l.push((Test2){"hello"}); - l.push((Test2){"abcdef"}); - l.push((Test1){765}); - assert(to_ints(l) == {532, 5, 6, 765}); - l.remove_using_test(fn (x, p) => x.type == p.type, &&(Test1){}); - assert(to_ints(l) == {5, 6}); - l.remove_using_test(fn (x, p) => x.test() == p.test(), &&(Test2){"abcdef"}); - assert(to_ints(l) == {5}); -} - -fn void retain_with_test() => @pool() -{ - TestL l; - l.push((Test1){345}); - l.push((Test1){3535}); - l.push((Test1){7654}); - l.push((Test2){"abdef"}); - l.push((Test1){6432}); - l.push((Test1){585868}); - assert(to_ints(l) == {345, 3535, 7654, 5, 6432, 585868}); - l.retain_using_test(fn (x, p) => x.test() < p.test(), &&(Test1){1000}); - assert(to_ints(l) == {345, 5}); - l.retain_using_test(fn (x, p) => x.type == p.type && x.test() == p.test(), &&(Test1){0}); - assert(to_ints(l) == {}); -} - -module interfacelist_test; - -fn int[] to_ints(TestL l) => @map(tmem, l.array_view(), fn int(Test x) => x.test()); - -import std::core::array @public; -macro @map(Allocator alloc, array, operation) -{ - var res = allocator::alloc_array(alloc, $typeof(operation).returns, array::find_len(array)); - foreach (i, val : array) res[i] = operation(val); - return res; -} diff --git a/test/unit/stdlib/core/string.c3 b/test/unit/stdlib/core/string.c3 index 4f3fb580e..e84932fe7 100644 --- a/test/unit/stdlib/core/string.c3 +++ b/test/unit/stdlib/core/string.c3 @@ -273,7 +273,7 @@ fn void contains_char() assert(!test.contains_char('x')); } -fn void test_base_13_conversion() +fn void test_base_13_convesion() { assert("13".to_long(13)!! == 13 + 3); assert("1a".to_long(13)!! == 13 + 10); @@ -382,4 +382,4 @@ fn void test_snake_pascal_self_modify() s2.convert_snake_to_pascal(); test::eq(s2, s[1]); } -} +} \ No newline at end of file diff --git a/test/unit/stdlib/libc/libc.c3 b/test/unit/stdlib/libc/libc.c3 index 9c55019ff..aa0b88e78 100644 --- a/test/unit/stdlib/libc/libc.c3 +++ b/test/unit/stdlib/libc/libc.c3 @@ -135,8 +135,8 @@ fn void bsearch() @test key = 6; found = (CInt*) libc::bsearch(&key, int_ar, 7, CInt.sizeof, &compare_cint); assert(*found == 6); - CInt non_existent_key = 12; - found = (CInt*) libc::bsearch(&non_existent_key, int_ar, 7, CInt.sizeof, &compare_cint); + CInt non_existant_key = 12; + found = (CInt*) libc::bsearch(&non_existant_key, int_ar, 7, CInt.sizeof, &compare_cint); assert(found == null); Event[] events = {