From: Brendan Hansen Date: Sat, 26 Jun 2021 03:08:57 +0000 (-0500) Subject: added 'Any' type and any typed varargs X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=30fc4c268dbfe42afd2b2910c901f6ac32188572;p=onyx.git added 'Any' type and any typed varargs --- diff --git a/bin/onyx b/bin/onyx index f7c894b3..04e726d9 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/builtin.onyx b/core/builtin.onyx index f43a1bb7..977d37c0 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -180,3 +180,10 @@ CallSite :: struct { line : u32; column : u32; } + + + +Any :: struct { + data: rawptr; + type: type_expr; +} diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index fb6c3943..e6fbfed6 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -467,6 +467,7 @@ typedef enum ParamPassType { typedef enum VarArgKind { VA_Kind_Not_VA, VA_Kind_Typed, + VA_Kind_Any, VA_Kind_Untyped, } VarArgKind; @@ -1204,6 +1205,7 @@ extern AstTyped *builtin_context_variable; extern AstType *builtin_allocator_type; extern AstType *builtin_iterator_type; extern AstType *builtin_callsite_type; +extern AstType *builtin_any_type; extern AstTyped *type_table_node; typedef struct BuiltinSymbol { diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 85bdd5d7..65fe57ad 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -47,6 +47,7 @@ AstTyped *builtin_context_variable; AstType *builtin_allocator_type; AstType *builtin_iterator_type; AstType *builtin_callsite_type; +AstType *builtin_any_type; AstTyped *type_table_node = NULL; @@ -391,6 +392,12 @@ void initialize_builtins(bh_allocator a) { return; } + builtin_any_type = (AstType *) symbol_raw_resolve(p->scope, "Any"); + if (builtin_any_type == NULL) { + onyx_report_error((OnyxFilePos) { 0 }, "'Any' struct not found in builtin package."); + return; + } + p = package_lookup("builtin.type_info"); if (p != NULL) { type_table_node = (AstTyped *) symbol_raw_resolve(p->scope, "type_table"); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index bb46103b..b01fcbda 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -555,6 +555,9 @@ CheckStatus check_call(AstCall* call) { Type* variadic_type = NULL; AstParam* variadic_param = NULL; + // SPEED CLEANUP: Caching the any type here. + Type* any_type = type_build_from_ast(context.ast_alloc, builtin_any_type); + ArgState arg_state = AS_Expecting_Exact; u32 arg_pos = 0; while (1) { @@ -592,9 +595,18 @@ CheckStatus check_call(AstCall* call) { } case AS_Expecting_Typed_VA: { + if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done; + + if (variadic_type->id == any_type->id) { + call->va_kind = VA_Kind_Any; + + resolve_expression_type(arg_arr[arg_pos]->value); + arg_arr[arg_pos]->va_kind = VA_Kind_Any; + break; + } + call->va_kind = VA_Kind_Typed; - if (arg_pos >= (u32) bh_arr_length(arg_arr)) goto type_checking_done; if (!type_check_or_auto_cast(&arg_arr[arg_pos]->value, variadic_type)) { onyx_report_error(arg_arr[arg_pos]->token->pos, "The procedure '%s' expects a value of type '%s' for the variadic parameter, '%b', got '%s'.", diff --git a/src/onyxwasm.c b/src/onyxwasm.c index a8823798..6ea30958 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -1391,6 +1391,13 @@ EMIT_FUNC(call, AstCall* call) { u32 vararg_count = 0; i32 vararg_offset = -1; + u32* vararg_any_offsets=NULL; + u32* vararg_any_types=NULL; + if (call->va_kind == VA_Kind_Any) { + vararg_any_offsets = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(call->args.values)); + vararg_any_types = bh_alloc_array(global_scratch_allocator, u32, bh_arr_length(call->args.values)); + } + bh_arr_each(AstTyped *, parg, call->args.values) { AstArgument* arg = (AstArgument *) *parg; if (arg->is_baked) continue; @@ -1425,11 +1432,38 @@ EMIT_FUNC(call, AstCall* call) { WI(WI_PTR_ADD); } + if (arg->va_kind == VA_Kind_Any) { + vararg_any_offsets[vararg_count - 1] = reserve_size; + vararg_any_types[vararg_count - 1] = arg->value->type->id; + } + reserve_size += type_size_of(arg->value->type); } } switch (call->va_kind) { + case VA_Kind_Any: { + vararg_offset = reserve_size; + + i32 any_size = type_size_of(type_build_from_ast(context.ast_alloc, builtin_any_type)); + + fori (i, 0, vararg_count) { + WIL(WI_LOCAL_GET, stack_top_store_local); + WIL(WI_LOCAL_GET, stack_top_store_local); + WID(WI_PTR_CONST, vararg_any_offsets[i]); + WI(WI_PTR_ADD); + emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Rawptr], vararg_offset + i * any_size); + + WIL(WI_LOCAL_GET, stack_top_store_local); + WID(WI_I32_CONST, vararg_any_types[i]); + emit_store_instruction(mod, &code, &basic_types[Basic_Kind_Type_Index], vararg_offset + i * any_size + 8); + + reserve_size += any_size; + } + + // fallthrough + } + case VA_Kind_Typed: { WIL(WI_LOCAL_GET, stack_top_store_local); if (vararg_offset > 0) {