From 0fc3c0f21181a8c77c2f1ecd4ae8ad1b440035c4 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Mon, 23 May 2022 20:13:34 -0500 Subject: [PATCH] __zero_value(T) -> T.{} --- core/alloc/auto_heap.onyx | 4 +--- core/container/array.onyx | 10 ++++---- core/container/bucket_array.onyx | 2 +- core/container/iter.onyx | 15 ++++++------ core/container/list.onyx | 9 +++----- core/container/map.onyx | 6 ++--- core/container/set.onyx | 9 ++++---- core/intrinsics/onyx.onyx | 1 - core/net/tcp.onyx | 4 +--- core/os/os.onyx | 5 ++-- examples/22_interfaces.onyx | 4 ++-- include/astnodes.h | 14 +++++++++--- misc/vscode/onyx-0.0.3.vsix | Bin 250872 -> 250880 bytes misc/vscode/syntaxes/onyx.tmLanguage | 16 +++++++++---- misc/vscode/textmate-configuration.json | 3 ++- modules/ui/components/workspace.onyx | 2 +- modules/vecmath/vector2.onyx | 5 ++-- modules/wasm_utils/instructions.onyx | 4 +--- scripts/onyx-pkg.onyx | 2 +- src/astnodes.c | 29 +++++++++++++++++++++++- src/builtins.c | 1 - src/checker.c | 25 ++++++++++++++++++-- src/utils.c | 13 +++++++---- src/wasm_emit.c | 19 ++++++++++------ 24 files changed, 130 insertions(+), 72 deletions(-) diff --git a/core/alloc/auto_heap.onyx b/core/alloc/auto_heap.onyx index 05349be2..bd8cbe0b 100644 --- a/core/alloc/auto_heap.onyx +++ b/core/alloc/auto_heap.onyx @@ -1,10 +1,8 @@ package core.alloc.heap -#local _Z :: (package core.intrinsics.onyx).__zero_value - AutoHeapState :: struct { backing_allocator: Allocator; - set := _Z(Set(rawptr)); + set := Set(rawptr).{}; } #local auto_heap_alloc_proc :: (data: ^AutoHeapState, aa: AllocationAction, size: u32, align: u32, oldptr: rawptr) -> rawptr { diff --git a/core/container/array.onyx b/core/container/array.onyx index a643a4b7..7a5bc4fc 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -1,7 +1,5 @@ package core.array -use package core.intrinsics.onyx { __zero_value } - // [..] T == Array(T) // where // Array :: struct (T: type_expr) { @@ -152,7 +150,7 @@ remove :: (arr: ^[..] $T, elem: T) { } delete :: (arr: ^[..] $T, idx: u32) -> T { - if idx >= arr.count do return __zero_value(T); + if idx >= arr.count do return .{}; to_return := arr.data[idx]; for i: idx .. arr.count - 1 { @@ -164,7 +162,7 @@ delete :: (arr: ^[..] $T, idx: u32) -> T { } fast_delete :: (arr: ^[..] $T, idx: u32) -> T { - if idx >= arr.count do return __zero_value(T); + if idx >= arr.count do return .{}; to_return := arr.data[idx]; if idx != arr.count - 1 do arr.data[idx] = arr.data[arr.count - 1]; @@ -174,7 +172,7 @@ fast_delete :: (arr: ^[..] $T, idx: u32) -> T { } pop :: (arr: ^[..] $T) -> T { - if arr.count == 0 do return __zero_value(T); + if arr.count == 0 do return .{}; arr.count -= 1; return arr.data[arr.count]; @@ -265,7 +263,7 @@ transplant :: (arr: [] $T, old_index: i32, new_index: i32) -> bool { } get :: (arr: [] $T, idx: i32) -> T { - if arr.count == 0 do return __zero_value(T); + if arr.count == 0 do return .{}; while idx < 0 do idx += arr.count; while idx >= arr.count do idx -= arr.count; diff --git a/core/container/bucket_array.onyx b/core/container/bucket_array.onyx index f28e89f2..14cc2847 100644 --- a/core/container/bucket_array.onyx +++ b/core/container/bucket_array.onyx @@ -121,7 +121,7 @@ iterator :: (b: ^Bucket_Array($T)) -> Iterator(T) { bucket := ^ba.buckets[bucket_idx]; while elem_idx == bucket.count { bucket_idx += 1; - if bucket_idx == ba.buckets.count do return __zero_value(T), false; + if bucket_idx == ba.buckets.count do return .{}, false; bucket = ^ba.buckets[bucket_idx]; elem_idx = 0; diff --git a/core/container/iter.onyx b/core/container/iter.onyx index a2c6813d..2ca0b67e 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -1,6 +1,5 @@ package core.iter -use package core.intrinsics.onyx { __zero_value } #local memory :: package core.memory #local alloc :: package core.alloc @@ -132,7 +131,7 @@ map :: #match {} next :: (mi: ^MapIterator($T, $R)) -> (R, bool) { value, cont := mi.iterator.next(mi.iterator.data); - if !cont do return __zero_value(R), false; + if !cont do return .{}, false; return mi.transform(value), true; } @@ -165,7 +164,7 @@ map :: #match {} next :: (mi: ^MapIterator($T, $R, $Ctx)) -> (R, bool) { value, cont := mi.iterator.next(mi.iterator.data); - if !cont do return __zero_value(R), false; + if !cont do return .{}, false; return mi.transform(value, mi.ctx), true; } @@ -219,7 +218,7 @@ take :: (it: Iterator($T), count: u32, allocator := iter_allocator) -> Iterator( take_iterator.allocator = allocator; next :: ($T: type_expr, ti: ^TakeIterator(T)) -> (T, bool) { - if ti.remaining == 0 do return __zero_value(T), false; + if ti.remaining == 0 do return .{}, false; ti.remaining -= 1; return ti.iterator.next(ti.iterator.data); @@ -356,7 +355,7 @@ concat :: (iters: ..Iterator($T)) -> Iterator(T) { next :: (use c: ^Context($T)) -> (T, bool) { while true { - if idx >= iters.count do return __zero_value(T), false; + if idx >= iters.count do return .{}, false; curr_iter := ^iters[idx]; value, valid := curr_iter.next(curr_iter.data); @@ -426,7 +425,7 @@ enumerate :: #match {} next :: (use data: ^Enumeration_Context($T)) -> (Enumeration_Value(T), bool) { value, cont := iterator.next(iterator.data); - if !cont do return .{ current_index, __zero_value(T) }, false; + if !cont do return .{ current_index, .{} }, false; defer current_index += 1; return .{ current_index, value }, true; @@ -489,7 +488,7 @@ from_array :: (arr: [] $T) -> Iterator(^T) { return arr.data[current], true; } else { - return __zero_value(T), false; + return .{}, false; } } @@ -659,7 +658,7 @@ to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T { } next :: (use c: ^Context($T)) -> (T, bool) { - if ended do return __zero_value(T), false; + if ended do return .{}, false; sync.scoped_mutex(^mutex); if v, success := take_one(iterator); !success { diff --git a/core/container/list.onyx b/core/container/list.onyx index 56e2f240..ec6022ec 100644 --- a/core/container/list.onyx +++ b/core/container/list.onyx @@ -1,7 +1,5 @@ package core.list -use package core.intrinsics.onyx { __zero_value } - ListElem :: struct (T: type_expr) { next: ^ListElem(T) = null; prev: ^ListElem(T) = null; @@ -63,7 +61,7 @@ push_begin :: (list: ^List, x: list.Elem_Type) { if list.last == null do list.last = new_elem; } -pop_end :: (list: ^List($T), default: T = __zero_value(T)) -> T { +pop_end :: (list: ^List($T), default: T = .{}) -> T { if list.last == null do return default; end := list.last; @@ -74,7 +72,7 @@ pop_end :: (list: ^List($T), default: T = __zero_value(T)) -> T { return end.data; } -pop_begin :: (list: ^List($T), default: T = __zero_value(T)) -> T { +pop_begin :: (list: ^List($T), default: T = .{}) -> T { if list.last == null do return default; begin := list.first; @@ -151,8 +149,7 @@ map :: #match {} #match iter.as_iterator get_iterator get_iterator :: (list: ^List($T)) -> Iterator(T) { iterator_next :: (list_iter: ^ListIterator($T)) -> (T, bool) { - use package core.intrinsics.onyx { __zero_value } - if list_iter.current == null do return __zero_value(T), false; + if list_iter.current == null do return .{}, false; defer list_iter.current = list_iter.current.next; return list_iter.current.data, true; diff --git a/core/container/map.onyx b/core/container/map.onyx index b8db2fb8..5f62d2ef 100644 --- a/core/container/map.onyx +++ b/core/container/map.onyx @@ -7,7 +7,7 @@ package core.map math :: package core.math conv :: package core.conv - use package core.intrinsics.onyx { __zero_value, __initialize } + use package core.intrinsics.onyx { __initialize } } #local { @@ -55,7 +55,7 @@ Map :: struct (Key_Type: type_expr, Value_Type: type_expr) where ValidKey(Key_Ty empty :: (package core.map).empty } -make :: ($Key: type_expr, $Value: type_expr, default := __zero_value(Value)) -> Map(Key, Value) { +make :: ($Key: type_expr, $Value: type_expr, default := Value.{}) -> Map(Key, Value) { map : Map(Key, Value); init(^map, default = default); return map; @@ -63,7 +63,7 @@ make :: ($Key: type_expr, $Value: type_expr, default := __zero_value(Value)) -> #match (package builtin).__make_overload macro (x: ^Map($K, $V), allocator := context.allocator) => (package core.map).make(K, V); -init :: (use map: ^Map($K, $V), default := __zero_value(V)) { +init :: (use map: ^Map($K, $V), default := V.{}) { __initialize(map); allocator = context.allocator; diff --git a/core/container/set.onyx b/core/container/set.onyx index 2738e292..c758f0ad 100644 --- a/core/container/set.onyx +++ b/core/container/set.onyx @@ -6,7 +6,6 @@ package core.set memory :: package core.memory math :: package core.math } -use package core.intrinsics.onyx { __zero_value } #local SetValue :: interface (t: $T) { { hash.to_u32(t) } -> u32; @@ -39,7 +38,7 @@ Set :: struct (Elem_Type: type_expr) where SetValue(Elem_Type) { iterator :: iterator } -make :: ($T: type_expr, default := __zero_value(T), allocator := context.allocator) -> Set(T) { +make :: ($T: type_expr, default := T.{}, allocator := context.allocator) -> Set(T) { set : Set(T); init(^set, default=default, allocator=allocator); return set; @@ -47,7 +46,7 @@ make :: ($T: type_expr, default := __zero_value(T), allocator := context.allocat #match (package builtin).__make_overload macro (x: ^Set, allocator: Allocator) => (package core.set).make(x.Elem_Type, allocator = allocator); -init :: (set: ^Set($T), default := __zero_value(T), allocator := context.allocator) { +init :: (set: ^Set($T), default := T.{}, allocator := context.allocator) { set.allocator = allocator; set.default_value = default; @@ -85,7 +84,7 @@ has :: (use set: ^Set, value: set.Elem_Type) -> bool { get :: (use set: ^Set, value: set.Elem_Type) -> set.Elem_Type { lr := lookup(set, value); - return entries[lr.entry_index].value if lr.entry_index >= 0 else __zero_value(set.Elem_Type); + return entries[lr.entry_index].value if lr.entry_index >= 0 else set.Elem_Type.{}; } get_ptr :: (use set: ^Set, value: set.Elem_Type) -> ^set.Elem_Type { @@ -137,7 +136,7 @@ iterator :: (set: ^Set($T)) -> Iterator(T) { return set.entries[position].value, true; } else { - return __zero_value(T), false; + return .{}, false; } } diff --git a/core/intrinsics/onyx.onyx b/core/intrinsics/onyx.onyx index ad706468..ff060005 100644 --- a/core/intrinsics/onyx.onyx +++ b/core/intrinsics/onyx.onyx @@ -1,7 +1,6 @@ package core.intrinsics.onyx __initialize :: (val: ^$T) -> void #intrinsic --- -__zero_value :: ($T: type_expr) -> T #intrinsic --- init :: macro ($T: type_expr) -> T { __initialize :: __initialize diff --git a/core/net/tcp.onyx b/core/net/tcp.onyx index e845ea18..7c1c917e 100644 --- a/core/net/tcp.onyx +++ b/core/net/tcp.onyx @@ -8,8 +8,6 @@ package core.net memory :: package core.memory alloc :: package core.alloc os :: package core.os - - use package core.intrinsics.onyx { __zero_value } } #if !runtime.Multi_Threading_Enabled { @@ -62,7 +60,7 @@ TCP_Event :: struct { tcp_get_events :: (use conn: ^TCP_Connection) -> Iterator(TCP_Event) { next :: (use conn: ^TCP_Connection) -> (TCP_Event, bool) { - if event_cursor == events.count do return __zero_value(TCP_Event), false; + if event_cursor == events.count do return .{}, false; defer event_cursor += 1; return events[event_cursor], true; diff --git a/core/os/os.onyx b/core/os/os.onyx index 6eb4c57a..dc16daca 100644 --- a/core/os/os.onyx +++ b/core/os/os.onyx @@ -17,12 +17,11 @@ list_directory :: (path: str) -> Iterator(DirectoryEntry) { } next :: (use c: ^Context) -> (DirectoryEntry, bool) { - use package core.intrinsics.onyx {__zero_value} - if !opened do return __zero_value(DirectoryEntry), false; + if !opened do return .{}, false; entry: DirectoryEntry; if !dir_read(dir, ^entry) { - return __zero_value(DirectoryEntry), false; + return .{}, false; } return entry, true; diff --git a/examples/22_interfaces.onyx b/examples/22_interfaces.onyx index d2dcbd9e..1bf958af 100644 --- a/examples/22_interfaces.onyx +++ b/examples/22_interfaces.onyx @@ -72,8 +72,8 @@ NumberLike :: interface (t: $T) { // Here, Vector2 has the type constraint of NumberLike for T. This constraint // is checked when Vector2 is constructed with any parameters. Vector2 :: struct (T: type_expr) where NumberLike(T) { - x := __zero_value(T); - y := __zero_value(T); + x := T.{}; + y := T.{}; } #operator + (x, y: Vector2($T)) => Vector2(T).{ x.x + y.x, x.y + y.y }; diff --git a/include/astnodes.h b/include/astnodes.h index b337faa4..89b0f082 100644 --- a/include/astnodes.h +++ b/include/astnodes.h @@ -102,7 +102,9 @@ \ NODE(ForeignBlock) \ \ - NODE(Package) + NODE(Package) \ + \ + NODE(ZeroValue) #define NODE(name) typedef struct Ast ## name Ast ## name; AST_NODES @@ -222,6 +224,8 @@ typedef enum AstKind { Ast_Kind_Foreign_Block, + Ast_Kind_Zero_Value, + Ast_Kind_Note, Ast_Kind_Count @@ -342,7 +346,7 @@ typedef enum OnyxIntrinsic { ONYX_INTRINSIC_MEMORY_SIZE, ONYX_INTRINSIC_MEMORY_GROW, ONYX_INTRINSIC_MEMORY_COPY, ONYX_INTRINSIC_MEMORY_FILL, - ONYX_INTRINSIC_INITIALIZE, ONYX_INTRINSIC_ZERO_VALUE, + ONYX_INTRINSIC_INITIALIZE, ONYX_INTRINSIC_I32_CLZ, ONYX_INTRINSIC_I32_CTZ, ONYX_INTRINSIC_I32_POPCNT, ONYX_INTRINSIC_I32_AND, ONYX_INTRINSIC_I32_OR, ONYX_INTRINSIC_I32_XOR, @@ -718,6 +722,9 @@ struct AstDoBlock { AstBlock* block; }; +struct AstZeroValue { + AstTyped_base; +}; struct AstDirectiveSolidify { AstTyped_base; @@ -1656,9 +1663,10 @@ AstAddressOf* make_address_of(bh_allocator a, AstTyped* node); AstLocal* make_local(bh_allocator a, OnyxToken* token, AstType* type_node); AstNode* make_symbol(bh_allocator a, OnyxToken* sym); AstUnaryOp* make_cast(bh_allocator a, AstTyped* expr, Type* to); +AstZeroValue* make_zero_value(bh_allocator a, OnyxToken *token, Type* type); void arguments_initialize(Arguments* args); -b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg); +b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg, b32 insert_zero_values); void arguments_ensure_length(Arguments* args, u32 count); void arguments_copy(Arguments* dest, Arguments* src); void arguments_clone(Arguments* dest, Arguments* src); diff --git a/misc/vscode/onyx-0.0.3.vsix b/misc/vscode/onyx-0.0.3.vsix index cbf41e65aaa3d4b541b70e21a9a709251c2665e7..6768cd37cd54653daa1aedc129809523e40fc0e8 100644 GIT binary patch delta 6127 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 b3cdiG8$}I*z0N5D_YLB*oa}+{JD=_ULvPCy delta 5791 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 U>7OFStNTcj`^PExpHq(i0~uE+ZvX%Q diff --git a/misc/vscode/syntaxes/onyx.tmLanguage b/misc/vscode/syntaxes/onyx.tmLanguage index df335efd..b35555aa 100644 --- a/misc/vscode/syntaxes/onyx.tmLanguage +++ b/misc/vscode/syntaxes/onyx.tmLanguage @@ -404,6 +404,18 @@ + + match + \b([#]\s*foreign) + captures + + 1 + + name + keyword.tag.onyx entity.name.block.onyx + + + match \b(\b[[:alpha:]_]+[[:alnum:]_\.]*\b)\s*[\(] @@ -465,10 +477,6 @@ string.quoted.double.onyx patterns - - include - #string_placeholder - include #string_escaped_char diff --git a/misc/vscode/textmate-configuration.json b/misc/vscode/textmate-configuration.json index d61a8ec9..23901782 100644 --- a/misc/vscode/textmate-configuration.json +++ b/misc/vscode/textmate-configuration.json @@ -21,7 +21,8 @@ }, "declarations": [ "entity.name.function.onyx", - "entity.name.type.onyx" + "entity.name.type.onyx", + "entity.name.block.onyx" ], "indentation": { "punctuation.block.begin.onyx": 1, diff --git a/modules/ui/components/workspace.onyx b/modules/ui/components/workspace.onyx index 853c28b0..8dfadd7b 100644 --- a/modules/ui/components/workspace.onyx +++ b/modules/ui/components/workspace.onyx @@ -1,7 +1,7 @@ package ui use package core -use package core.intrinsics.onyx { __zero_value, __initialize } +use package core.intrinsics.onyx { __initialize } Workspace_State :: struct { transform: gfx.Transform = .{ diff --git a/modules/vecmath/vector2.onyx b/modules/vecmath/vector2.onyx index cd186480..1daf4b9f 100644 --- a/modules/vecmath/vector2.onyx +++ b/modules/vecmath/vector2.onyx @@ -1,14 +1,13 @@ package vecmath #local io :: package core.io -use package core.intrinsics.onyx { __zero_value } Vector2i :: #type Vector2(i32); Vector2f :: #type Vector2(f32); Vector2 :: struct (T: type_expr) { - x := __zero_value(T); - y := __zero_value(T); + x := T.{}; + y := T.{}; } #operator + vector2_add diff --git a/modules/wasm_utils/instructions.onyx b/modules/wasm_utils/instructions.onyx index 72380e3c..e5bb6cf8 100644 --- a/modules/wasm_utils/instructions.onyx +++ b/modules/wasm_utils/instructions.onyx @@ -1,7 +1,5 @@ package wasm_utils -Z :: (package core.intrinsics.onyx).__zero_value - WasmInstructionCode :: enum { unreachable :: 0x00; nop :: 0x01; @@ -252,7 +250,7 @@ instruction_iterator :: (binary: ^WasmBinary, code: ^WasmCode, allocator := cont data.reader = io.reader_make(^data.stream); next :: (use c: ^CodeContext) -> (WasmInstruction, bool) { - if current_block_depth == 0 do return Z(WasmInstruction), false; + if current_block_depth == 0 do return .{}, false; return parse_instruction(^reader, binary, code.code_offset, ^current_block_depth), true; } diff --git a/scripts/onyx-pkg.onyx b/scripts/onyx-pkg.onyx index 8c7183e2..ad021424 100644 --- a/scripts/onyx-pkg.onyx +++ b/scripts/onyx-pkg.onyx @@ -4,7 +4,7 @@ Version :: SemVer.{0, 1, 1} use core -use core.intrinsics.onyx {__initialize, __zero_value} +use core.intrinsics.onyx {__initialize} global_arguments: struct { #tag "--config-file" diff --git a/src/astnodes.c b/src/astnodes.c index 2d276316..a2068921 100644 --- a/src/astnodes.c +++ b/src/astnodes.c @@ -105,6 +105,7 @@ static const char* ast_node_names[] = { "DO BLOCK", "FOREIGN BLOCK", + "ZERO VALUE", "NOTE", @@ -567,7 +568,18 @@ TypeMatch unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) { if (node->kind == Ast_Kind_Struct_Literal && (node->type_node == NULL && node->type == NULL)) { if (node->entity != NULL) return TYPE_MATCH_SUCCESS; if (type->kind == Type_Kind_VarArgs) type = type->VarArgs.elem; - if (!type_is_sl_constructable(type)) return TYPE_MATCH_FAILED; + + // + // If the structure literal has arguments, and the type is not constructable + // using a struct literal, then they cannot be unified. However, if no arguments + // are given, e.g. .{}, then any type should be matched, as that is the universal + // zero-value. + if (!type_is_sl_constructable(type)) { + AstStructLiteral *sl = (AstStructLiteral *) node; + if (bh_arr_length(sl->args.values) != 0 || bh_arr_length(sl->args.named_values) != 0) { + return TYPE_MATCH_FAILED; + } + } // If this shouldn't make permanent changes and submit entities, // just assume that it works and don't submit the entities. @@ -781,6 +793,13 @@ TypeMatch unify_node_and_type_(AstTyped** pnode, Type* type, b32 permanent) { } } + else if (node->kind == Ast_Kind_Zero_Value) { + if (node_type == NULL) { + node->type = type; + return TYPE_MATCH_SUCCESS; + } + } + return TYPE_MATCH_FAILED; } @@ -1195,6 +1214,14 @@ AstUnaryOp* make_cast(bh_allocator a, AstTyped* expr, Type* to) { return cast; } +AstZeroValue* make_zero_value(bh_allocator a, OnyxToken* token, Type* type) { + AstZeroValue* zero_value = onyx_ast_node_new(a, sizeof(AstZeroValue), Ast_Kind_Zero_Value); + zero_value->token = token; + zero_value->flags |= Ast_Flag_Comptime; + zero_value->type = type; + return zero_value; +} + void arguments_initialize(Arguments* args) { if (args->values == NULL) bh_arr_new(global_heap_allocator, args->values, 2); if (args->named_values == NULL) bh_arr_new(global_heap_allocator, args->named_values, 2); diff --git a/src/builtins.c b/src/builtins.c index 0c3520e1..a102fa11 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -109,7 +109,6 @@ static IntrinsicMap builtin_intrinsics[] = { { "memory_fill", ONYX_INTRINSIC_MEMORY_FILL }, { "__initialize", ONYX_INTRINSIC_INITIALIZE }, - { "__zero_value", ONYX_INTRINSIC_ZERO_VALUE }, { "clz_i32", ONYX_INTRINSIC_I32_CLZ }, { "ctz_i32", ONYX_INTRINSIC_I32_CTZ }, diff --git a/src/checker.c b/src/checker.c index 6b198e7f..b7980be8 100644 --- a/src/checker.c +++ b/src/checker.c @@ -635,7 +635,7 @@ CheckStatus check_call(AstCall** pcall) { arguments_ensure_length(&call->args, arg_count); char* err_msg = NULL; - fill_in_arguments(&call->args, (AstNode *) callee, &err_msg); + fill_in_arguments(&call->args, (AstNode *) callee, &err_msg, 0); if (err_msg != NULL) ERROR(call->token->pos, err_msg); bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values; @@ -1226,6 +1226,26 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) { } if (!type_is_structlike_strict(sl->type)) { + // + // If there are no given arguments to a structure literal, it is treated as a 'zero-value', + // and can be used to create a completely zeroed value of any type. + if (bh_arr_length(sl->args.values) == 0 && bh_arr_length(sl->args.named_values) == 0) { + AstZeroValue *zv = make_zero_value(context.ast_alloc, sl->token, sl->type); + bh_arr_push(sl->args.values, (AstTyped *) zv); + + sl->flags |= Ast_Flag_Has_Been_Checked; + return Check_Success; + } + + if ((sl->flags & Ast_Flag_Has_Been_Checked) != 0) { + assert(sl->args.values); + assert(sl->args.values[0]); + assert(sl->args.values[0]->kind == Ast_Kind_Zero_Value); + return Check_Success; + } + + // + // Otherwise, it is not possible to construct the type if it is not a structure. ERROR_(sl->token->pos, "'%s' is not constructable using a struct literal.", type_get_name(sl->type)); @@ -1237,7 +1257,7 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) { // :Idempotency if ((sl->flags & Ast_Flag_Has_Been_Checked) == 0) { char* err_msg = NULL; - if (!fill_in_arguments(&sl->args, (AstNode *) sl, &err_msg)) { + if (!fill_in_arguments(&sl->args, (AstNode *) sl, &err_msg, 1)) { onyx_report_error(sl->token->pos, Error_Critical, err_msg); bh_arr_each(AstTyped *, value, sl->args.values) { @@ -1908,6 +1928,7 @@ CheckStatus check_expression(AstTyped** pexpr) { case Ast_Kind_Constraint_Sentinel: break; case Ast_Kind_Switch_Case: break; case Ast_Kind_Foreign_Block: break; + case Ast_Kind_Zero_Value: break; default: retval = Check_Error; diff --git a/src/utils.c b/src/utils.c index 79114df6..27802c51 100644 --- a/src/utils.c +++ b/src/utils.c @@ -449,7 +449,7 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, arguments_ensure_length(&args, get_argument_buffer_size(&overload->type->Function, &args)); // NOTE: If the arguments cannot be placed successfully in the parameters list - if (!fill_in_arguments(&args, (AstNode *) overload, NULL)) continue; + if (!fill_in_arguments(&args, (AstNode *) overload, NULL, 0)) continue; VarArgKind va_kind; TypeMatch tm = check_arguments_against_type(&args, &overload->type->Function, &va_kind, NULL, NULL, NULL); @@ -747,7 +747,7 @@ i32 get_argument_buffer_size(TypeFunction* type, Arguments* args) { // NOTE: The values array can be partially filled out, and is the resulting array. // Returns if all the values were filled in. -b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg) { +b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg, b32 insert_zero_values) { { // Delete baked arguments // :ArgumentResolvingIsComplicated @@ -808,8 +808,13 @@ b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg) { fori (idx, 0, bh_arr_length(args->values)) { if (args->values[idx] == NULL) args->values[idx] = (AstTyped *) lookup_default_value_by_idx(provider, idx); if (args->values[idx] == NULL) { - if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "No value given for %d%s argument.", idx + 1, bh_num_suffix(idx + 1)); - success = 0; + if (insert_zero_values) { + assert(provider->token); + args->values[idx] = (AstTyped *) make_zero_value(context.ast_alloc, provider->token, NULL); + } else { + if (err_msg) *err_msg = bh_aprintf(global_scratch_allocator, "No value given for %d%s argument.", idx + 1, bh_num_suffix(idx + 1)); + success = 0; + } } } diff --git a/src/wasm_emit.c b/src/wasm_emit.c index 8fde864b..d97b811f 100644 --- a/src/wasm_emit.c +++ b/src/wasm_emit.c @@ -1835,13 +1835,6 @@ EMIT_FUNC(intrinsic_call, AstCall* call) { break; } - case ONYX_INTRINSIC_ZERO_VALUE: { - // NOTE: This probably will not have to make an allocation. - Type* zero_type = type_build_from_ast(context.ast_alloc, (AstType *) ((AstArgument *) call->original_args.values[0])->value); - emit_zero_value_for_type(mod, &code, zero_type, call->token); - break; - } - case ONYX_INTRINSIC_I32_CLZ: WI(WI_I32_CLZ); break; case ONYX_INTRINSIC_I32_CTZ: WI(WI_I32_CTZ); break; case ONYX_INTRINSIC_I32_POPCNT: WI(WI_I32_POPCNT); break; @@ -3019,6 +3012,13 @@ EMIT_FUNC(expression, AstTyped* expr) { break; } + case Ast_Kind_Zero_Value: { + AstZeroValue *zv = (AstZeroValue *) expr; + assert(zv->type); + emit_zero_value_for_type(mod, &code, zv->type, zv->token); + break; + } + default: bh_printf("Unhandled case: %d\n", expr->kind); DEBUG_HERE; @@ -3667,6 +3667,11 @@ static b32 emit_raw_data_(OnyxWasmModule* mod, ptr data, AstTyped* node) { break; } + case Ast_Kind_Zero_Value: { + memset(data, 0, type_size_of(node->type)); + break; + } + case Ast_Kind_NumLit: { // NOTE: This makes a big assumption that we are running on a // little endian machine, since WebAssembly is little endian -- 2.25.1