From e77d1fb646fd1f5c24cd96a1621420a6724fa819 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 18 Feb 2025 00:07:09 +0100 Subject: [PATCH] - Increase precedence of `(Foo) { 1, 2 }` - Add `--enable-new-generics` to enable `Foo{int}` generic syntax. --- lib/std/collections/hashmap.c3 | 2 +- lib/std/collections/list_common.c3 | 4 +- lib/std/core/allocators/arena_allocator.c3 | 2 +- lib/std/core/builtin.c3 | 4 +- lib/std/core/dstring.c3 | 2 +- lib/std/core/private/cpu_detect.c3 | 16 +++--- lib/std/core/private/macho_runtime.c3 | 2 +- lib/std/core/types.c3 | 4 +- lib/std/encoding/json.c3 | 4 +- lib/std/hash/sha1.c3 | 4 +- lib/std/io/path.c3 | 2 +- lib/std/io/stream.c3 | 6 +-- lib/std/math/math_complex.c3 | 16 +++--- lib/std/math/math_matrix.c3 | 8 +-- lib/std/math/math_quaternion.c3 | 12 ++--- lib/std/math/math_vector.c3 | 6 +-- lib/std/sort/countingsort.c3 | 6 +-- lib/std/sort/insertionsort.c3 | 2 +- lib/std/sort/quicksort.c3 | 2 +- releasenotes.md | 4 ++ src/build/build.h | 2 + src/build/build_options.c | 7 +++ src/build/builder.c | 1 + src/compiler/parse_expr.c | 24 +++++++-- src/compiler/parse_global.c | 60 +++++++++++++++++----- src/compiler/sema_expr.c | 2 +- src/compiler/sema_types.c | 8 ++- 27 files changed, 139 insertions(+), 73 deletions(-) diff --git a/lib/std/collections/hashmap.c3 b/lib/std/collections/hashmap.c3 index 39f1f9e6b..36588b796 100644 --- a/lib/std/collections/hashmap.c3 +++ b/lib/std/collections/hashmap.c3 @@ -2,7 +2,7 @@ // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. <* - @require $defined(Key{}.hash()) `No .hash function found on the key` + @require $defined((Key){}.hash()) `No .hash function found on the key` *> module std::collections::map(); import std::math; diff --git a/lib/std/collections/list_common.c3 b/lib/std/collections/list_common.c3 index eee4ef397..dccbf7afa 100644 --- a/lib/std/collections/list_common.c3 +++ b/lib/std/collections/list_common.c3 @@ -5,7 +5,7 @@ module std::collections::list_common; *> macro list_to_new_aligned_array($Type, self, Allocator allocator) { - if (!self.size) return $Type[] {}; + if (!self.size) return ($Type[]){}; $Type[] result = allocator::alloc_array_aligned(allocator, $Type, self.size); result[..] = self.entries[:self.size]; return result; @@ -13,7 +13,7 @@ macro list_to_new_aligned_array($Type, self, Allocator allocator) macro list_to_new_array($Type, self, Allocator allocator) { - if (!self.size) return $Type[] {}; + if (!self.size) return ($Type[]){}; $Type[] result = allocator::alloc_array(allocator, $Type, self.size); result[..] = self.entries[:self.size]; return result; diff --git a/lib/std/core/allocators/arena_allocator.c3 b/lib/std/core/allocators/arena_allocator.c3 index f988a6635..952e3cad5 100644 --- a/lib/std/core/allocators/arena_allocator.c3 +++ b/lib/std/core/allocators/arena_allocator.c3 @@ -33,7 +33,7 @@ struct ArenaAllocatorHeader @local macro ArenaAllocator* wrap(char[] bytes) { - return ArenaAllocator{}.init(bytes); + return (ArenaAllocator){}.init(bytes); } <* diff --git a/lib/std/core/builtin.c3 b/lib/std/core/builtin.c3 index f9644f763..c99121688 100644 --- a/lib/std/core/builtin.c3 +++ b/lib/std/core/builtin.c3 @@ -238,7 +238,7 @@ macro enum_by_name($Type, String enum_name) @builtin @param $Type `The type of the enum` @require $Type.kindof == ENUM `Only enums may be used` @require $defined($Type.#value) `Expected '#value' to match an enum associated value` - @require $assignable(value, $typeof($Type{}.#value)) `Expected the value to match the type of the associated value` + @require $assignable(value, $typeof(($Type){}.#value)) `Expected the value to match the type of the associated value` @ensure @typeis(return, $Type) @return! SearchResult.MISSING *> @@ -351,7 +351,7 @@ macro swizzle2(v, v2, ...) @builtin macro anyfault @catch(#expr) @builtin { if (catch f = #expr) return f; - return anyfault {}; + return {}; } <* diff --git a/lib/std/core/dstring.c3 b/lib/std/core/dstring.c3 index 0d4ab30c2..a9b584c07 100644 --- a/lib/std/core/dstring.c3 +++ b/lib/std/core/dstring.c3 @@ -30,7 +30,7 @@ fn DString DString.temp_init(&self, usz capacity = MIN_CAPACITY) fn DString new_with_capacity(usz capacity, Allocator allocator = allocator::heap()) { - return DString{}.new_init(capacity, allocator); + return (DString){}.new_init(capacity, allocator); } fn DString temp_with_capacity(usz capacity) => new_with_capacity(capacity, allocator::temp()) @inline; diff --git a/lib/std/core/private/cpu_detect.c3 b/lib/std/core/private/cpu_detect.c3 index f18ba5308..75d20ce77 100644 --- a/lib/std/core/private/cpu_detect.c3 +++ b/lib/std/core/private/cpu_detect.c3 @@ -150,14 +150,14 @@ fn void x86_initialize_cpu_features() { uint max_level = x86_cpuid(0).eax; CpuId feat = x86_cpuid(1); - CpuId leaf7 = max_level >= 8 ? x86_cpuid(7) : CpuId {}; - CpuId leaf7s1 = leaf7.eax >= 1 ? x86_cpuid(7, 1) : CpuId {}; - CpuId ext1 = x86_cpuid(0x80000000).eax >= 0x80000001 ? x86_cpuid(0x80000001) : CpuId {}; - CpuId ext8 = x86_cpuid(0x80000000).eax >= 0x80000008 ? x86_cpuid(0x80000008) : CpuId {}; - CpuId leaf_d = max_level >= 0xd ? x86_cpuid(0xd, 0x1) : CpuId {}; - CpuId leaf_14 = max_level >= 0x14 ? x86_cpuid(0x14) : CpuId {}; - CpuId leaf_19 = max_level >= 0x19 ? x86_cpuid(0x19) : CpuId {}; - CpuId leaf_24 = max_level >= 0x24 ? x86_cpuid(0x24) : CpuId {}; + CpuId leaf7 = max_level >= 8 ? x86_cpuid(7) : {}; + CpuId leaf7s1 = leaf7.eax >= 1 ? x86_cpuid(7, 1) : {}; + CpuId ext1 = x86_cpuid(0x80000000).eax >= 0x80000001 ? x86_cpuid(0x80000001) : {}; + CpuId ext8 = x86_cpuid(0x80000000).eax >= 0x80000008 ? x86_cpuid(0x80000008) : {}; + CpuId leaf_d = max_level >= 0xd ? x86_cpuid(0xd, 0x1) : {}; + CpuId leaf_14 = max_level >= 0x14 ? x86_cpuid(0x14) : {}; + CpuId leaf_19 = max_level >= 0x19 ? x86_cpuid(0x19) : {}; + CpuId leaf_24 = max_level >= 0x24 ? x86_cpuid(0x24) : {}; add_feature_if_bit(ADX, leaf7.ebx, 19); add_feature_if_bit(AES, feat.ecx, 25); add_feature_if_bit(AMX_BF16, leaf7.edx, 22); diff --git a/lib/std/core/private/macho_runtime.c3 b/lib/std/core/private/macho_runtime.c3 index 1a937ddb7..d21b9ff46 100644 --- a/lib/std/core/private/macho_runtime.c3 +++ b/lib/std/core/private/macho_runtime.c3 @@ -101,7 +101,7 @@ macro find_segment_section_body(MachHeader* header, char* segname, char* sectnam Section64*! section = find_section(find_segment(header, segname), sectname); if (catch section) { - return $Type[] {}; + return ($Type[]){}; } $Type* ptr = (void*)header + section.offset; return ptr[:section.size / $Type.sizeof]; diff --git a/lib/std/core/types.c3 b/lib/std/core/types.c3 index cf6d9d6c1..29fe07ab7 100644 --- a/lib/std/core/types.c3 +++ b/lib/std/core/types.c3 @@ -162,12 +162,12 @@ macro bool is_unsigned($Type) @const macro bool is_indexable($Type) @const { - return $defined($Type{}[0]); + return $defined(($Type){}[0]); } macro bool is_ref_indexable($Type) @const { - return $defined(&$Type{}[0]); + return $defined(&($Type){}[0]); } macro bool is_intlike($Type) @const diff --git a/lib/std/encoding/json.c3 b/lib/std/encoding/json.c3 index 894e175e8..4cea7cebf 100644 --- a/lib/std/encoding/json.c3 +++ b/lib/std/encoding/json.c3 @@ -17,12 +17,12 @@ fault JsonParsingError fn Object*! parse_string(String s, Allocator allocator = allocator::heap()) { - return parse(ByteReader{}.init(s), allocator); + return parse((ByteReader){}.init(s), allocator); } fn Object*! temp_parse_string(String s) { - return parse(ByteReader{}.init(s), allocator::temp()); + return parse((ByteReader){}.init(s), allocator::temp()); } fn Object*! parse(InStream s, Allocator allocator = allocator::heap()) diff --git a/lib/std/hash/sha1.c3 b/lib/std/hash/sha1.c3 index 391061b80..4ddb27b60 100644 --- a/lib/std/hash/sha1.c3 +++ b/lib/std/hash/sha1.c3 @@ -78,10 +78,10 @@ fn char[HASH_BYTES] Sha1.final(&self) { finalcount[i] = (char)((self.count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 0xFF); } - self.update(char[] { 0o200 }); + self.update((char[]){ 0o200 }); while ((self.count[0] & 504) != 448) { - self.update(char[] { 0 }); + self.update((char[]){ 0 }); } self.update(&finalcount); diff --git a/lib/std/io/path.c3 b/lib/std/io/path.c3 index ce5af06b4..39f419866 100644 --- a/lib/std/io/path.c3 +++ b/lib/std/io/path.c3 @@ -274,7 +274,7 @@ fn Path! Path.new_absolute(self, Allocator allocator = allocator::heap()) }; $else String cwd = os::getcwd(allocator::temp())!; - return Path { cwd, self.env }.new_append(path_str, allocator)!; + return (Path){ cwd, self.env }.new_append(path_str, allocator)!; $endif } diff --git a/lib/std/io/stream.c3 b/lib/std/io/stream.c3 index 090d53796..a545bf084 100644 --- a/lib/std/io/stream.c3 +++ b/lib/std/io/stream.c3 @@ -181,12 +181,12 @@ fn usz! copy_to(InStream in, OutStream dst, char[] buffer = {}) if (&dst.read_to) return dst.read_to(in); $switch (env::MEMORY_ENV) $case NORMAL: - return copy_through_buffer(in, dst, &&char[4096]{}); + return copy_through_buffer(in, dst, &&(char[4096]){}); $case SMALL: - return copy_through_buffer(in, dst, &&char[1024]{}); + return copy_through_buffer(in, dst, &&(char[1024]){}); $case TINY: $case NONE: - return copy_through_buffer(in, dst, &&(char[256]{})); + return copy_through_buffer(in, dst, &&(char[256]){}); $endswitch } diff --git a/lib/std/math/math_complex.c3 b/lib/std/math/math_complex.c3 index 4dc6ea7f6..7843fec2e 100644 --- a/lib/std/math/math_complex.c3 +++ b/lib/std/math/math_complex.c3 @@ -11,21 +11,21 @@ union Complex const Complex IDENTITY = { 1, 0 }; const Complex IMAGINARY = { 0, 1 }; -macro Complex Complex.add(self, Complex b) => Complex { .v = self.v + b.v }; -macro Complex Complex.add_each(self, Real b) => Complex { .v = self.v + b }; -macro Complex Complex.sub(self, Complex b) => Complex { .v = self.v - b.v }; -macro Complex Complex.sub_each(self, Real b) => Complex { .v = self.v - b }; -macro Complex Complex.scale(self, Real s) => Complex { .v = self.v * s }; +macro Complex Complex.add(self, Complex b) => { .v = self.v + b.v }; +macro Complex Complex.add_each(self, Real b) => { .v = self.v + b }; +macro Complex Complex.sub(self, Complex b) => { .v = self.v - b.v }; +macro Complex Complex.sub_each(self, Real b) => { .v = self.v - b }; +macro Complex Complex.scale(self, Real s) => { .v = self.v * s }; macro Complex Complex.mul(self, Complex b) => { self.r * b.r - self.c * b.c, self.r * b.c + b.r * self.c }; macro Complex Complex.div(self, Complex b) { Real div = b.v.dot(b.v); - return Complex{ (self.r * b.r + self.c * b.c) / div, (self.c * b.r - self.r * b.c) / div }; + return { (self.r * b.r + self.c * b.c) / div, (self.c * b.r - self.r * b.c) / div }; } macro Complex Complex.inverse(self) { Real sqr = self.v.dot(self.v); - return Complex{ self.r / sqr, -self.c / sqr }; + return { self.r / sqr, -self.c / sqr }; } -macro Complex Complex.conjugate(self) => Complex { .r = self.r, .c = -self.c }; +macro Complex Complex.conjugate(self) => { .r = self.r, .c = -self.c }; macro bool Complex.equals(self, Complex b) => self.v == b.v; diff --git a/lib/std/math/math_matrix.c3 b/lib/std/math/math_matrix.c3 index 11a9978c1..c9486ea0b 100644 --- a/lib/std/math/math_matrix.c3 +++ b/lib/std/math/math_matrix.c3 @@ -420,19 +420,19 @@ const Matrix4x4 IDENTITY4 = { .m = { [0] = 1, [5] = 1, [10] = 1, [15] = 1 } }; macro matrix_component_mul(mat, val) @private { var $Type = Real[<$typeof(mat.m).len>]; - return $typeof(*mat) { .m = val * ($Type)mat.m }; + return ($typeof(*mat)) { .m = val * ($Type)mat.m }; } macro matrix_add(mat, mat2) @private { var $Type = Real[<$typeof(mat.m).len>]; - return $typeof(*mat) { .m = ($Type)mat.m + ($Type)mat2.m }; + return ($typeof(*mat)) { .m = ($Type)mat.m + ($Type)mat2.m }; } macro matrix_sub(mat, mat2) @private { var $Type = Real[<$typeof(mat.m).len>]; - return $typeof(*mat) { .m = ($Type)mat.m - ($Type)mat2.m }; + return ($typeof(*mat)) { .m = ($Type)mat.m - ($Type)mat2.m }; } macro matrix_look_at($Type, eye, target, up) @private @@ -441,7 +441,7 @@ macro matrix_look_at($Type, eye, target, up) @private var vx = up.cross(vz).normalize(); var vy = vz.cross(vx); - return $Type { + return ($Type){ vx[0], vx[1], vx[2], - (Real)vx.dot(eye), vy[0], vy[1], vy[2], - (Real)vy.dot(eye), vz[0], vz[1], vz[2], - (Real)vz.dot(eye), diff --git a/lib/std/math/math_quaternion.c3 b/lib/std/math/math_quaternion.c3 index efbd0bf13..226c76231 100644 --- a/lib/std/math/math_quaternion.c3 +++ b/lib/std/math/math_quaternion.c3 @@ -11,11 +11,11 @@ union Quaternion const Quaternion IDENTITY = { 0, 0, 0, 1 }; -macro Quaternion Quaternion.add(Quaternion a, Quaternion b) => Quaternion { .v = a.v + b.v }; -macro Quaternion Quaternion.add_each(Quaternion a, Real b) => Quaternion { .v = a.v + b }; -macro Quaternion Quaternion.sub(Quaternion a, Quaternion b) => Quaternion { .v = a.v - b.v }; -macro Quaternion Quaternion.sub_each(Quaternion a, Real b) => Quaternion { .v = a.v - b }; -macro Quaternion Quaternion.scale(Quaternion a, Real s) => Quaternion { .v = a.v * s }; +macro Quaternion Quaternion.add(Quaternion a, Quaternion b) => { .v = a.v + b.v }; +macro Quaternion Quaternion.add_each(Quaternion a, Real b) => { .v = a.v + b }; +macro Quaternion Quaternion.sub(Quaternion a, Quaternion b) => { .v = a.v - b.v }; +macro Quaternion Quaternion.sub_each(Quaternion a, Real b) => { .v = a.v - b }; +macro Quaternion Quaternion.scale(Quaternion a, Real s) => { .v = a.v * s }; macro Quaternion Quaternion.normalize(Quaternion q) => { .v = q.v.normalize() }; macro Real Quaternion.length(Quaternion q) => q.v.length(); macro Quaternion Quaternion.lerp(Quaternion q1, Quaternion q2, Real amount) => { .v = q1.v.lerp(q2.v, amount) }; @@ -76,7 +76,7 @@ macro into_matrix(Quaternion* q, $Type) @private var z = rotation.k; var w = rotation.l; - return $Type { + return ($Type) { 1 - 2*y*y - 2*z*z, 2*x*y - 2*z*w, 2*x*z + 2*y*w, 0, 2*x*y + 2*z*w, 1 - 2*x*x - 2*z*z, 2*y*z - 2*x*w, 0, 2*x*z - 2*y*w, 2*y*z + 2*x*w , 1 - 2*x*x - 2*y*y, 0, diff --git a/lib/std/math/math_vector.c3 b/lib/std/math/math_vector.c3 index f2613c5ac..48c2bd80a 100644 --- a/lib/std/math/math_vector.c3 +++ b/lib/std/math/math_vector.c3 @@ -145,7 +145,7 @@ macro transform2(v, mat) @private macro transform3(v, mat) @private { - return $typeof(v) { + return ($typeof(v)){ mat.m00 * v[0] + mat.m10 * v[1] + mat.m20 * v[2] + mat.m30, mat.m01 * v[0] + mat.m11 * v[1] + mat.m21 * v[2] + mat.m31, mat.m02 * v[0] + mat.m12 * v[1] + mat.m22 * v[2] + mat.m32 @@ -169,7 +169,7 @@ macro void ortho_normalize3(v1, v2) @private macro rotate_by_quat3(v, q) @private { - return $typeof(v) { + return ($typeof(v)){ v[0] * (q.i * q.i + q.l * q.l - q.j * q.j - q.k * q.k) + v[1] * (2 * q.i * q.j - 2 * q.l * q.k) + v[2] * (2 * q.i * q.k - 2 * q.l * q.j), @@ -233,7 +233,7 @@ macro barycenter3(p, a, b, c) @private var denom = d00 * d11 - d01 * d01; var y = (d11 * d20 - d01 * d21) / denom; var z = (d00 * d21 - d01 * d20) / denom; - return $typeof(p) { 1 - y - z, y, z }; + return ($typeof(p)){ 1 - y - z, y, z }; } macro refract3(v, n, r) @private diff --git a/lib/std/sort/countingsort.c3 b/lib/std/sort/countingsort.c3 index fa28f2cb9..38598059e 100644 --- a/lib/std/sort/countingsort.c3 +++ b/lib/std/sort/countingsort.c3 @@ -29,11 +29,11 @@ module std::sort::cs(); def Counts = usz[256] @private; def Ranges = usz[257] @private; def Indexs = char[256] @private; -def ElementType = $typeof(Type{}[0]); +def ElementType = $typeof((Type){}[0]); const bool NO_KEY_FN @private = types::is_same(KeyFn, EmptySlot); -const bool KEY_BY_VALUE @private = NO_KEY_FN ||| $assignable(Type{}[0], $typefrom(KeyFn.paramsof[0].type)); -const bool LIST_HAS_REF @private = $defined(&Type{}[0]); +const bool KEY_BY_VALUE @private = NO_KEY_FN ||| $assignable((Type){}[0], $typefrom(KeyFn.paramsof[0].type)); +const bool LIST_HAS_REF @private = $defined(&(Type){}[0]); def KeyFnReturnType = $typefrom(KeyFn.returns) @if(!NO_KEY_FN); def KeyFnReturnType = ElementType @if(NO_KEY_FN); diff --git a/lib/std/sort/insertionsort.c3 b/lib/std/sort/insertionsort.c3 index ab1c6b371..6e1ed6953 100644 --- a/lib/std/sort/insertionsort.c3 +++ b/lib/std/sort/insertionsort.c3 @@ -19,7 +19,7 @@ macro insertionsort(list, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLOT) @b module std::sort::is(); -def ElementType = $typeof(Type{}[0]); +def ElementType = $typeof(((Type){})[0]); fn void isort(Type list, usz low, usz high, CmpFn comp, Context context) { diff --git a/lib/std/sort/quicksort.c3 b/lib/std/sort/quicksort.c3 index 156d6a2f6..1dcb22d85 100644 --- a/lib/std/sort/quicksort.c3 +++ b/lib/std/sort/quicksort.c3 @@ -35,7 +35,7 @@ macro quickselect(list, isz k, cmp = EMPTY_MACRO_SLOT, context = EMPTY_MACRO_SLO module std::sort::qs(); -def ElementType = $typeof(Type{}[0]); +def ElementType = $typeof(((Type){})[0]); struct StackElementItem @private { diff --git a/releasenotes.md b/releasenotes.md index 42116eaa3..086c157a2 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -3,7 +3,11 @@ ## 0.6.8 Change list ### Changes / improvements +- Increase precedence of `(Foo) { 1, 2 }` +- Add `--enable-new-generics` to enable `Foo{int}` generic syntax. + ### Fixes + ### Stdlib changes ## 0.6.7 Change list diff --git a/src/build/build.h b/src/build/build.h index 9103f7790..6b0b5f568 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -469,6 +469,7 @@ typedef struct BuildOptions_ size_t linker_lib_count; const char* std_lib_dir; VectorConv vector_conv; + bool enable_new_generics; struct { const char *sdk; @@ -680,6 +681,7 @@ typedef struct OptimizationSetting optsetting; OptimizationLevel optlevel; VectorConv vector_conv; + bool enable_new_generics; MemoryEnvironment memory_environment; SizeOptimizationLevel optsize; SingleModule single_module; diff --git a/src/build/build_options.c b/src/build/build_options.c index 1752c8dec..df1b11382 100644 --- a/src/build/build_options.c +++ b/src/build/build_options.c @@ -193,6 +193,7 @@ static void usage(bool full) print_opt("--linux-crt ", "Set the directory to use for finding crt1.o and related files."); print_opt("--linux-crtbegin ", "Set the directory to use for finding crtbegin.o and related files."); PRINTF(""); + print_opt("--enable-new-generics", "Enable Foo{int} generics, this will disable the old Foo { ... } initializers."); print_opt("--vector-conv=