From c21b22b28cea160a8aba85990bbb8e8f289ce6c5 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Thu, 23 Mar 2023 09:20:17 -0500 Subject: [PATCH] added: basics of multi-pointers need to work on ergonomics --- compiler/include/astnodes.h | 3 + compiler/include/types.h | 11 +++- compiler/src/astnodes.c | 4 +- compiler/src/checker.c | 20 ++++-- compiler/src/clone.c | 5 ++ compiler/src/parser.c | 7 ++ compiler/src/polymorph.h | 11 ++++ compiler/src/symres.c | 1 + compiler/src/types.c | 102 ++++++++++++++++++++++------- compiler/src/wasm_emit.c | 13 ++-- compiler/src/wasm_type_table.h | 9 +++ core/alloc/alloc.onyx | 6 +- core/alloc/arena.onyx | 4 +- core/alloc/gc.onyx | 6 +- core/alloc/heap.onyx | 2 +- core/alloc/ring.onyx | 2 +- core/builtin.onyx | 4 +- core/container/bucket_array.onyx | 4 +- core/container/set.onyx | 2 +- core/conv/conv.onyx | 34 +++++----- core/conv/format.onyx | 12 ++-- core/encoding/csv.onyx | 2 +- core/encoding/osad.onyx | 14 ++-- core/io/stdio.onyx | 2 +- core/misc/any_utils.onyx | 10 +-- core/misc/arg_parse.onyx | 6 +- core/net/net.onyx | 2 +- core/os/file.onyx | 2 +- core/runtime/info/helper.onyx | 6 ++ core/runtime/info/types.onyx | 28 +++++--- core/runtime/platform/onyx/fs.onyx | 2 +- core/string/buffer.onyx | 2 +- core/string/string.onyx | 12 ++-- tests/aoc-2020/day13.onyx | 2 +- tests/aoc-2020/day16.onyx | 4 +- tests/aoc-2020/day18.onyx | 6 +- tests/aoc-2020/day19.onyx | 14 ++-- tests/aoc-2020/day20.onyx | 10 +-- tests/aoc-2020/day21.onyx | 6 +- tests/aoc-2020/day22.onyx | 2 +- tests/aoc-2021/day14.onyx | 2 +- tests/baked_parameters.onyx | 2 +- 42 files changed, 264 insertions(+), 134 deletions(-) diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index 19722988..bb0422f2 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -60,6 +60,7 @@ NODE(Type) \ NODE(BasicType) \ NODE(PointerType) \ + NODE(MultiPointerType) \ NODE(FunctionType) \ NODE(ArrayType) \ NODE(SliceType) \ @@ -158,6 +159,7 @@ typedef enum AstKind { Ast_Kind_Type, Ast_Kind_Basic_Type, Ast_Kind_Pointer_Type, + Ast_Kind_Multi_Pointer_Type, Ast_Kind_Function_Type, Ast_Kind_Array_Type, Ast_Kind_Slice_Type, @@ -924,6 +926,7 @@ struct AstArrayType { AstType_base; AstType* elem; AstTyped *count_expr; }; struct AstSliceType { AstType_base; AstType* elem; }; struct AstDynArrType { AstType_base; AstType* elem; }; struct AstVarArgType { AstType_base; AstType* elem; }; +struct AstMultiPointerType { AstType_base; AstType* elem; }; struct AstFunctionType { AstType_base; diff --git a/compiler/include/types.h b/compiler/include/types.h index dc8c979f..dfde3023 100644 --- a/compiler/include/types.h +++ b/compiler/include/types.h @@ -104,7 +104,14 @@ typedef enum StructProcessingStatus { #define TYPE_KINDS \ TYPE_KIND(Basic, TypeBasic) \ - TYPE_KIND(Pointer, struct { TypeBasic base; Type *elem; }) \ + TYPE_KIND(Pointer, struct { \ + TypeBasic base; \ + Type *elem; \ + }) \ + TYPE_KIND(MultiPointer, struct { \ + TypeBasic base; \ + Type *elem; \ + }) \ TYPE_KIND(Function, struct { \ Type *return_type; \ u16 param_count; \ @@ -207,6 +214,7 @@ Type* type_build_function_type(bh_allocator alloc, struct AstFunction* func); Type* type_build_compound_type(bh_allocator alloc, struct AstCompound* compound); Type* type_make_pointer(bh_allocator alloc, Type* to); +Type* type_make_multi_pointer(bh_allocator alloc, Type* to); Type* type_make_array(bh_allocator alloc, Type* to, u32 count); Type* type_make_slice(bh_allocator alloc, Type* of); Type* type_make_dynarray(bh_allocator alloc, Type* of); @@ -231,6 +239,7 @@ i32 type_get_idx_of_linear_member_with_offset(Type* type, u32 offset); b32 type_struct_is_simple(Type* type); b32 type_is_pointer(Type* type); +b32 type_is_multi_pointer(Type* type); b32 type_is_rawptr(Type* type); b32 type_is_array(Type* tyoe); b32 type_is_struct(Type* type); diff --git a/compiler/src/astnodes.c b/compiler/src/astnodes.c index f53943e8..98c520bc 100644 --- a/compiler/src/astnodes.c +++ b/compiler/src/astnodes.c @@ -36,6 +36,7 @@ static const char* ast_node_names[] = { "TYPE", "BASIC_TYPE", "POINTER_TYPE", + "MULTI POINTER TYPE", "FUNCTION_TYPE", "ARRAY TYPE", "SLICE TYPE", @@ -1355,7 +1356,8 @@ TypeMatch implicit_cast_to_bool(AstTyped **pnode) { AstTyped *node = *pnode; if ((node->type->kind == Type_Kind_Basic && node->type->Basic.kind == Basic_Kind_Rawptr) - || (node->type->kind == Type_Kind_Pointer)) { + || (node->type->kind == Type_Kind_Pointer) + || (node->type->kind == Type_Kind_MultiPointer)) { AstNumLit *zero = make_int_literal(context.ast_alloc, 0); zero->type = &basic_types[Basic_Kind_Rawptr]; diff --git a/compiler/src/checker.c b/compiler/src/checker.c index a60be7c6..fea13d0b 100644 --- a/compiler/src/checker.c +++ b/compiler/src/checker.c @@ -1071,10 +1071,11 @@ static b32 binary_op_is_allowed(BinaryOp operation, Type* type) { enum BasicFlag effective_flags = 0; switch (type->kind) { - case Type_Kind_Basic: effective_flags = type->Basic.flags; break; - case Type_Kind_Pointer: effective_flags = Basic_Flag_Pointer; break; - case Type_Kind_Enum: effective_flags = Basic_Flag_Integer; break; - case Type_Kind_Function: effective_flags = Basic_Flag_Equality; break; + case Type_Kind_Basic: effective_flags = type->Basic.flags; break; + case Type_Kind_Pointer: // nocheckin REMOVE THIS + case Type_Kind_MultiPointer: effective_flags = Basic_Flag_Pointer; break; + case Type_Kind_Enum: effective_flags = Basic_Flag_Integer; break; + case Type_Kind_Function: effective_flags = Basic_Flag_Equality; break; } return (binop_allowed[operation] & effective_flags) != 0; @@ -1290,13 +1291,16 @@ CheckStatus check_binaryop(AstBinaryOp** pbinop) { } // NOTE: Handle basic pointer math. - if (type_is_pointer(binop->left->type)) { + if (type_is_multi_pointer(binop->left->type) || type_is_pointer(binop->left->type)) { if (binop->operation != Binary_Op_Add && binop->operation != Binary_Op_Minus) goto bad_binaryop; + if (type_is_pointer(binop->left->type)) + onyx_report_warning(binop->token->pos, "Doing pointer math on non-multi-pointer!"); + resolve_expression_type(binop->right); if (!type_is_integer(binop->right->type)) goto bad_binaryop; - AstNumLit* numlit = make_int_literal(context.ast_alloc, type_size_of(binop->left->type->Pointer.elem)); + AstNumLit* numlit = make_int_literal(context.ast_alloc, type_size_of(binop->left->type->MultiPointer.elem)); numlit->token = binop->right->token; numlit->type = binop->right->type; @@ -1519,6 +1523,10 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) { } sl->flags |= Ast_Flag_Has_Been_Checked; + if (!type_is_ready_for_lookup(sl->type)) { + YIELD(sl->token->pos, "Waiting for structure type to be ready."); + } + AstTyped** actual = sl->args.values; StructMember smem; diff --git a/compiler/src/clone.c b/compiler/src/clone.c index f5b31188..f0c02fab 100644 --- a/compiler/src/clone.c +++ b/compiler/src/clone.c @@ -58,6 +58,7 @@ static inline i32 ast_kind_to_size(AstNode* node) { case Ast_Kind_Type: return sizeof(AstType); case Ast_Kind_Basic_Type: return sizeof(AstBasicType); case Ast_Kind_Pointer_Type: return sizeof(AstPointerType); + case Ast_Kind_Multi_Pointer_Type: return sizeof(AstMultiPointerType); case Ast_Kind_Function_Type: return sizeof(AstFunctionType) + ((AstFunctionType *) node)->param_count * sizeof(AstType *); case Ast_Kind_Array_Type: return sizeof(AstArrayType); case Ast_Kind_Slice_Type: return sizeof(AstSliceType); @@ -330,6 +331,10 @@ AstNode* ast_clone(bh_allocator a, void* n) { C(AstPointerType, elem); break; + case Ast_Kind_Multi_Pointer_Type: + C(AstMultiPointerType, elem); + break; + case Ast_Kind_Array_Type: C(AstArrayType, count_expr); C(AstArrayType, elem); diff --git a/compiler/src/parser.c b/compiler/src/parser.c index 1a81139f..aa18ca87 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -1923,6 +1923,13 @@ static AstType* parse_type(OnyxParser* parser) { new = make_node(AstSliceType, Ast_Kind_Slice_Type); new->token = open_bracket; + } else if (parser->curr->type == '&' || parser->curr->type == '^') { + consume_token(parser); + + new = make_node(AstMultiPointerType, Ast_Kind_Multi_Pointer_Type); + new->flags |= Basic_Flag_Pointer; + new->token = open_bracket; + } else if (parser->curr->type == Token_Type_Dot_Dot) { new = make_node(AstDynArrType, Ast_Kind_DynArr_Type); new->token = open_bracket; diff --git a/compiler/src/polymorph.h b/compiler/src/polymorph.h index b9b296a6..78e443f4 100644 --- a/compiler/src/polymorph.h +++ b/compiler/src/polymorph.h @@ -281,6 +281,17 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type break; } + case Ast_Kind_Multi_Pointer_Type: { + if (elem.actual->kind != Type_Kind_MultiPointer) break; + + bh_arr_push(elem_queue, ((PolySolveElem) { + .type_expr = ((AstMultiPointerType *) elem.type_expr)->elem, + .kind = PSK_Type, + .actual = elem.actual->MultiPointer.elem, + })); + break; + } + case Ast_Kind_Address_Of: { if (elem.actual->kind != Type_Kind_Pointer) break; diff --git a/compiler/src/symres.c b/compiler/src/symres.c index 0ce2c63f..fb889375 100644 --- a/compiler/src/symres.c +++ b/compiler/src/symres.c @@ -182,6 +182,7 @@ static SymresStatus symres_type(AstType** type) { case Ast_Kind_Slice_Type: SYMRES(type, &((AstSliceType *) *type)->elem); break; case Ast_Kind_DynArr_Type: SYMRES(type, &((AstDynArrType *) *type)->elem); break; case Ast_Kind_VarArg_Type: SYMRES(type, &((AstVarArgType *) *type)->elem); break; + case Ast_Kind_Multi_Pointer_Type: SYMRES(type, &((AstMultiPointerType *) *type)->elem); break; case Ast_Kind_Function_Type: { AstFunctionType* ftype = (AstFunctionType *) *type; diff --git a/compiler/src/types.c b/compiler/src/types.c index 0d632996..7dd126a6 100644 --- a/compiler/src/types.c +++ b/compiler/src/types.c @@ -41,6 +41,7 @@ Type basic_types[] = { // TODO: Document this!! bh_imap type_map; static bh_imap type_pointer_map; +static bh_imap type_multi_pointer_map; static bh_imap type_array_map; static bh_imap type_slice_map; static bh_imap type_dynarr_map; @@ -65,12 +66,13 @@ static void type_register(Type* type) { } void types_init() { - bh_imap_init(&type_map, global_heap_allocator, 255); - bh_imap_init(&type_pointer_map, global_heap_allocator, 255); - bh_imap_init(&type_array_map, global_heap_allocator, 255); - bh_imap_init(&type_slice_map, global_heap_allocator, 255); - bh_imap_init(&type_dynarr_map, global_heap_allocator, 255); - bh_imap_init(&type_vararg_map, global_heap_allocator, 255); + bh_imap_init(&type_map, global_heap_allocator, 255); + bh_imap_init(&type_pointer_map, global_heap_allocator, 255); + bh_imap_init(&type_multi_pointer_map, global_heap_allocator, 255); + bh_imap_init(&type_array_map, global_heap_allocator, 255); + bh_imap_init(&type_slice_map, global_heap_allocator, 255); + bh_imap_init(&type_dynarr_map, global_heap_allocator, 255); + bh_imap_init(&type_vararg_map, global_heap_allocator, 255); sh_new_arena(type_func_map); fori (i, 0, Basic_Kind_Count) type_register(&basic_types[i]); @@ -112,7 +114,7 @@ b32 types_are_compatible_(Type* t1, Type* t2, b32 recurse_pointers) { if (t1->Basic.kind == Basic_Kind_V128 || t2->Basic.kind == Basic_Kind_V128) return 1; } - if (t1->Basic.kind == Basic_Kind_Rawptr && type_is_pointer(t2)) { + if (t1->Basic.kind == Basic_Kind_Rawptr && (type_is_pointer(t2) || type_is_multi_pointer(t2))) { return 1; } break; @@ -138,6 +140,21 @@ b32 types_are_compatible_(Type* t1, Type* t2, b32 recurse_pointers) { break; } + case Type_Kind_MultiPointer: { + // Multi-pointer decays to pointer + // [&] u8 -> &u8 + if (t2->kind == Type_Kind_Pointer) { + if (!recurse_pointers) return 1; + + if (types_are_compatible(t1->MultiPointer.elem, t2->Pointer.elem)) return 1; + } + + // Multi-pointer decays to rawptr + if (t2->kind == Type_Kind_Basic && t2->Basic.kind == Basic_Kind_Rawptr) return 1; + + break; + } + case Type_Kind_Array: { if (t2->kind != Type_Kind_Array) return 0; @@ -223,6 +240,7 @@ u32 type_size_of(Type* type) { switch (type->kind) { case Type_Kind_Basic: return type->Basic.size; + case Type_Kind_MultiPointer: case Type_Kind_Pointer: return POINTER_SIZE; case Type_Kind_Function: return 4; case Type_Kind_Array: return type->Array.size; @@ -242,6 +260,7 @@ u32 type_alignment_of(Type* type) { switch (type->kind) { case Type_Kind_Basic: return type->Basic.alignment; + case Type_Kind_MultiPointer: case Type_Kind_Pointer: return POINTER_SIZE; case Type_Kind_Function: return 4; case Type_Kind_Array: return type_alignment_of(type->Array.elem); @@ -267,6 +286,13 @@ static Type* type_build_from_ast_inner(bh_allocator alloc, AstType* type_node, b return ptr_type; } + case Ast_Kind_Multi_Pointer_Type: { + Type *inner_type = type_build_from_ast_inner(alloc, ((AstMultiPointerType *) type_node)->elem, 1); + Type *ptr_type = type_make_multi_pointer(alloc, inner_type); + if (ptr_type) ptr_type->ast_type = type_node; + return ptr_type; + } + case Ast_Kind_Function_Type: { AstFunctionType* ftype_node = (AstFunctionType *) type_node; u64 param_count = ftype_node->param_count; @@ -832,6 +858,29 @@ Type* type_make_pointer(bh_allocator alloc, Type* to) { } } +Type* type_make_multi_pointer(bh_allocator alloc, Type* to) { + if (to == NULL) return NULL; + if (to == (Type *) &node_that_signals_failure) return to; + + assert(to->id > 0); + u64 ptr_id = bh_imap_get(&type_multi_pointer_map, to->id); + if (ptr_id > 0) { + Type* ptr_type = (Type *) bh_imap_get(&type_map, ptr_id); + return ptr_type; + + } else { + Type* ptr_type = type_create(Type_Kind_MultiPointer, alloc, 0); + ptr_type->MultiPointer.base.flags |= Basic_Flag_Pointer; + ptr_type->MultiPointer.base.size = POINTER_SIZE; + ptr_type->MultiPointer.elem = to; + + type_register(ptr_type); + bh_imap_put(&type_multi_pointer_map, to->id, ptr_type->id); + + return ptr_type; + } +} + Type* type_make_array(bh_allocator alloc, Type* to, u32 count) { if (to == NULL) return NULL; if (to == (Type *) &node_that_signals_failure) return to; @@ -871,7 +920,7 @@ Type* type_make_slice(bh_allocator alloc, Type* of) { type_register(slice_type); bh_imap_put(&type_slice_map, of->id, slice_type->id); - type_make_pointer(alloc, of); + type_make_multi_pointer(alloc, of); slice_type->Slice.elem = of; return slice_type; @@ -893,7 +942,7 @@ Type* type_make_dynarray(bh_allocator alloc, Type* of) { type_register(dynarr); bh_imap_put(&type_dynarr_map, of->id, dynarr->id); - type_make_pointer(alloc, of); + type_make_multi_pointer(alloc, of); dynarr->DynArray.elem = of; return dynarr; @@ -915,7 +964,7 @@ Type* type_make_varargs(bh_allocator alloc, Type* of) { type_register(va_type); bh_imap_put(&type_vararg_map, of->id, va_type->id); - type_make_pointer(alloc, of); + type_make_multi_pointer(alloc, of); va_type->VarArgs.elem = of; return va_type; @@ -1013,6 +1062,7 @@ const char* type_get_unique_name(Type* type) { switch (type->kind) { case Type_Kind_Basic: return type->Basic.name; case Type_Kind_Pointer: return bh_aprintf(global_scratch_allocator, "&%s", type_get_unique_name(type->Pointer.elem)); + case Type_Kind_MultiPointer: return bh_aprintf(global_scratch_allocator, "[&] %s", type_get_unique_name(type->Pointer.elem)); case Type_Kind_Array: return bh_aprintf(global_scratch_allocator, "[%d] %s", type->Array.count, type_get_unique_name(type->Array.elem)); case Type_Kind_Struct: if (type->Struct.name) @@ -1079,6 +1129,7 @@ const char* type_get_name(Type* type) { switch (type->kind) { case Type_Kind_Basic: return type->Basic.name; case Type_Kind_Pointer: return bh_aprintf(global_scratch_allocator, "&%s", type_get_name(type->Pointer.elem)); + case Type_Kind_MultiPointer: return bh_aprintf(global_scratch_allocator, "[&] %s", type_get_name(type->Pointer.elem)); case Type_Kind_Array: return bh_aprintf(global_scratch_allocator, "[%d] %s", type->Array.count, type_get_name(type->Array.elem)); case Type_Kind_PolyStruct: @@ -1153,11 +1204,12 @@ u32 type_get_alignment_log2(Type* type) { Type* type_get_contained_type(Type* type) { if (type == NULL) return NULL; switch (type->kind) { - case Type_Kind_Pointer: return type->Pointer.elem; - case Type_Kind_Array: return type->Array.elem; - case Type_Kind_Slice: return type->Slice.elem; - case Type_Kind_DynArray: return type->DynArray.elem; - case Type_Kind_VarArgs: return type->VarArgs.elem; + case Type_Kind_Pointer: return type->Pointer.elem; + case Type_Kind_MultiPointer: return type->MultiPointer.elem; + case Type_Kind_Array: return type->Array.elem; + case Type_Kind_Slice: return type->Slice.elem; + case Type_Kind_DynArray: return type->DynArray.elem; + case Type_Kind_VarArgs: return type->VarArgs.elem; default: return NULL; } } @@ -1206,7 +1258,7 @@ b32 type_lookup_member(Type* type, char* member, StructMember* smem) { fori (i, 0, (i64) (sizeof(slice_members) / sizeof(StructMember))) { if (strcmp(slice_members[i].name, member) == 0) { *smem = slice_members[i]; - if (smem->idx == 0) smem->type = type_make_pointer(context.ast_alloc, type->Slice.elem); + if (smem->idx == 0) smem->type = type_make_multi_pointer(context.ast_alloc, type->Slice.elem); return 1; } @@ -1218,7 +1270,7 @@ b32 type_lookup_member(Type* type, char* member, StructMember* smem) { fori (i, 0, (i64) (sizeof(array_members) / sizeof(StructMember))) { if (strcmp(array_members[i].name, member) == 0) { *smem = array_members[i]; - if (smem->idx == 0) smem->type = type_make_pointer(context.ast_alloc, type->DynArray.elem); + if (smem->idx == 0) smem->type = type_make_multi_pointer(context.ast_alloc, type->DynArray.elem); if (smem->idx == 3) smem->type = type_build_from_ast(context.ast_alloc, builtin_allocator_type); return 1; @@ -1250,7 +1302,7 @@ b32 type_lookup_member_by_idx(Type* type, i32 idx, StructMember* smem) { if (idx > 2) return 0; *smem = slice_members[idx]; - if (smem->idx == 0) smem->type = type_make_pointer(context.ast_alloc, type->Slice.elem); + if (smem->idx == 0) smem->type = type_make_multi_pointer(context.ast_alloc, type->Slice.elem); return 1; } @@ -1259,7 +1311,7 @@ b32 type_lookup_member_by_idx(Type* type, i32 idx, StructMember* smem) { if (idx > 4) return 0; *smem = array_members[idx]; - if (idx == 0) smem->type = type_make_pointer(context.ast_alloc, type->DynArray.elem); + if (idx == 0) smem->type = type_make_multi_pointer(context.ast_alloc, type->DynArray.elem); if (idx == 3) smem->type = type_build_from_ast(context.ast_alloc, builtin_allocator_type); return 1; @@ -1284,7 +1336,7 @@ b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) { case Type_Kind_Slice: case Type_Kind_VarArgs: { if (idx == 0) { - two->type = type_make_pointer(context.ast_alloc, type->Slice.elem); + two->type = type_make_multi_pointer(context.ast_alloc, type->Slice.elem); two->offset = 0; } if (idx == 1) { @@ -1296,7 +1348,7 @@ b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) { } case Type_Kind_DynArray: { if (idx == 0) { - two->type = type_make_pointer(context.ast_alloc, type->DynArray.elem); + two->type = type_make_multi_pointer(context.ast_alloc, type->DynArray.elem); two->offset = 0; } if (idx == 1) { @@ -1367,6 +1419,11 @@ b32 type_is_pointer(Type* type) { return type->kind == Type_Kind_Pointer; } +b32 type_is_multi_pointer(Type* type) { + if (type == NULL) return 0; + return type->kind == Type_Kind_MultiPointer; +} + b32 type_is_rawptr(Type* type) { if (type == NULL) return 0; return type->kind == Type_Kind_Basic && type->Basic.kind == Basic_Kind_Rawptr; @@ -1438,7 +1495,8 @@ b32 type_results_in_void(Type* type) { b32 type_is_array_accessible(Type* type) { if (type == NULL) return 0; - if (type_is_pointer(type)) return 1; + // if (type_is_pointer(type)) return 1; + if (type_is_multi_pointer(type)) return 1; if (type->kind == Type_Kind_Array) return 1; if (type->kind == Type_Kind_Slice) return 1; if (type->kind == Type_Kind_DynArray) return 1; diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index 8aaac08b..4841b8a2 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -48,6 +48,7 @@ static WasmType onyx_type_to_wasm_type(Type* type) { if (type->kind == Type_Kind_Pointer) return WASM_TYPE_PTR; if (type->kind == Type_Kind_Array) return WASM_TYPE_PTR; if (type->kind == Type_Kind_Function) return WASM_TYPE_FUNC; + if (type->kind == Type_Kind_MultiPointer) return WASM_TYPE_PTR; if (type->kind == Type_Kind_Basic) { TypeBasic* basic = &type->Basic; @@ -91,6 +92,7 @@ static b32 local_is_wasm_local(AstTyped* local) { if (local->type->kind == Type_Kind_Enum && local->type->Enum.backing->kind == Type_Kind_Basic) return 1; if (local->type->kind == Type_Kind_Distinct && local->type->Distinct.base_type->kind == Type_Kind_Basic) return 1; if (local->type->kind == Type_Kind_Pointer) return 1; + if (local->type->kind == Type_Kind_MultiPointer) return 1; return 0; } @@ -972,7 +974,7 @@ EMIT_FUNC(store_instruction, Type* type, u32 offset) { u32 alignment = type_get_alignment_log2(type); i32 store_size = type_size_of(type); - i32 is_basic = type->kind == Type_Kind_Basic || type->kind == Type_Kind_Pointer; + i32 is_basic = type->kind == Type_Kind_Basic || type->kind == Type_Kind_Pointer || type->kind == Type_Kind_MultiPointer; if (is_basic && (type->Basic.flags & Basic_Flag_Pointer)) { WID(NULL, WI_I32_STORE, ((WasmInstructionData) { 2, offset })); @@ -1082,7 +1084,7 @@ EMIT_FUNC(load_instruction, Type* type, u32 offset) { assert(type); i32 load_size = type_size_of(type); - i32 is_basic = type->kind == Type_Kind_Basic || type->kind == Type_Kind_Pointer; + i32 is_basic = type->kind == Type_Kind_Basic || type->kind == Type_Kind_Pointer || type->kind == Type_Kind_MultiPointer; WasmInstructionType instr = WI_NOP; i32 alignment = type_get_alignment_log2(type); @@ -2699,19 +2701,19 @@ EMIT_FUNC(field_access_location, AstFieldAccess* field, u64* offset_return) { } if (source_expr->kind == Ast_Kind_Subscript - && source_expr->type->kind != Type_Kind_Pointer) { + && source_expr->type->kind != Type_Kind_Pointer && source_expr->type->kind != Type_Kind_MultiPointer) { u64 o2 = 0; emit_subscript_location(mod, &code, (AstSubscript *) source_expr, &o2); offset += o2; } else if ((source_expr->kind == Ast_Kind_Local || source_expr->kind == Ast_Kind_Param) - && source_expr->type->kind != Type_Kind_Pointer) { + && source_expr->type->kind != Type_Kind_Pointer && source_expr->type->kind != Type_Kind_MultiPointer) { u64 o2 = 0; emit_local_location(mod, &code, (AstLocal *) source_expr, &o2); offset += o2; } else if (source_expr->kind == Ast_Kind_Memres - && source_expr->type->kind != Type_Kind_Pointer) { + && source_expr->type->kind != Type_Kind_Pointer && source_expr->type->kind != Type_Kind_MultiPointer) { emit_memory_reservation_location(mod, &code, (AstMemRes *) source_expr); } else { @@ -4127,6 +4129,7 @@ static char encode_type_as_dyncall_symbol(Type *t) { if (t->kind == Type_Kind_Slice) return 's'; if (t->kind == Type_Kind_Pointer) return 'p'; + if (t->kind == Type_Kind_MultiPointer) return 'p'; if (t->kind == Type_Kind_Enum) return encode_type_as_dyncall_symbol(t->Enum.backing); if (t->kind == Type_Kind_Basic) { TypeBasic* basic = &t->Basic; diff --git a/compiler/src/wasm_type_table.h b/compiler/src/wasm_type_table.h index d80f2f0e..fc620bce 100644 --- a/compiler/src/wasm_type_table.h +++ b/compiler/src/wasm_type_table.h @@ -69,6 +69,15 @@ static u64 build_type_table(OnyxWasmModule* module) { break; } + case Type_Kind_MultiPointer: { + table_info[type_idx] = table_buffer.length; + bh_buffer_write_u32(&table_buffer, type->kind); + bh_buffer_write_u32(&table_buffer, type_size_of(type)); + bh_buffer_write_u32(&table_buffer, type_alignment_of(type)); + bh_buffer_write_u32(&table_buffer, type->MultiPointer.elem->id); + break; + } + case Type_Kind_Array: { table_info[type_idx] = table_buffer.length; bh_buffer_write_u32(&table_buffer, type->kind); diff --git a/core/alloc/alloc.onyx b/core/alloc/alloc.onyx index 25834be6..b9733c0f 100644 --- a/core/alloc/alloc.onyx +++ b/core/alloc/alloc.onyx @@ -16,13 +16,13 @@ as_allocator :: #match { from_stack :: macro (size: u32) -> rawptr { // This should do something about the alignment... // Everything so far has assume that the stack is aligned to 16 bytes. - defer __stack_top = ~~(cast(&u8) __stack_top + size); + defer __stack_top = ~~(cast([&]u8) __stack_top + size); return __stack_top; } array_from_stack :: macro ($T: type_expr, size: u32) -> [] T { - defer __stack_top = ~~(cast(&u8) __stack_top + size * sizeof T); - return (cast(&T) __stack_top)[0 .. size]; + defer __stack_top = ~~(cast([&]u8) __stack_top + size * sizeof T); + return (cast([&]T) __stack_top)[0 .. size]; } on_heap :: macro (v: $V) -> &V { diff --git a/core/alloc/arena.onyx b/core/alloc/arena.onyx index 0fce91fc..0f5c74f1 100644 --- a/core/alloc/arena.onyx +++ b/core/alloc/arena.onyx @@ -49,7 +49,7 @@ arena_alloc_proc :: (data: rawptr, aa: AllocationAction, size: u32, align: u32, alloc_arena.current_arena = new_arena; - return cast(rawptr) (cast(&u8) ret_arena + sizeof rawptr); + return cast(rawptr) (cast([&] u8) ret_arena + sizeof rawptr); } if alloc_arena.size % align != 0 { @@ -67,7 +67,7 @@ arena_alloc_proc :: (data: rawptr, aa: AllocationAction, size: u32, align: u32, alloc_arena.current_arena = new_arena; } - retval := cast(rawptr) (cast(&u8) alloc_arena.current_arena + alloc_arena.size); + retval := cast(rawptr) (cast([&] u8) alloc_arena.current_arena + alloc_arena.size); alloc_arena.size += size; return retval; diff --git a/core/alloc/gc.onyx b/core/alloc/gc.onyx index 8ff2ebbf..3dc3e11d 100644 --- a/core/alloc/gc.onyx +++ b/core/alloc/gc.onyx @@ -90,7 +90,7 @@ GC_Manually_Free_Magic_Number :: 0xface1337 old: &GCLink; if oldptr != null { - old = (cast(&GCLink) oldptr) - 1; + old = (cast([&] GCLink) oldptr) - 1; // // If this allocated space was not from an gc allocator, @@ -136,11 +136,11 @@ GC_Manually_Free_Magic_Number :: 0xface1337 } } - return newptr + 1; + return cast([&] GCLink, newptr) + 1; } untrack :: (ptr: rawptr) -> bool { - link := (cast(&GCLink) ptr) - 1; + link: &GCLink = (cast([&] GCLink) ptr) - 1; if link.magic_number != GC_Link_Magic_Number { return false; diff --git a/core/alloc/heap.onyx b/core/alloc/heap.onyx index 79f90c8d..f5102f5f 100644 --- a/core/alloc/heap.onyx +++ b/core/alloc/heap.onyx @@ -186,7 +186,7 @@ get_freed_size :: () => { // and then marked an "manually managed", we can free the block // as normal here, but we have to go back some more bytes. if hb_ptr.magic_number == core.alloc.gc.GC_Manually_Free_Magic_Number { - hb_ptr = ~~(cast(uintptr) (cast(&core.alloc.gc.GCLink, ptr) - 1) - sizeof heap_allocated_block); + hb_ptr = ~~(cast(uintptr) (cast([&] core.alloc.gc.GCLink, ptr) - 1) - sizeof heap_allocated_block); } #if runtime.Multi_Threading_Enabled do sync.scoped_mutex(&heap_mutex); diff --git a/core/alloc/ring.onyx b/core/alloc/ring.onyx index a9c68919..493a4572 100644 --- a/core/alloc/ring.onyx +++ b/core/alloc/ring.onyx @@ -23,7 +23,7 @@ ring_alloc_proc :: (data: rawptr, aa: AllocationAction, size: u32, align: u32, o if aa == .Alloc { retval := null; if ss.curr + size < ss.size { - retval = cast(&u8) ss.base_ptr + ss.curr; + retval = cast([&] u8) ss.base_ptr + ss.curr; ss.curr += size; } elseif size <= ss.size { diff --git a/core/builtin.onyx b/core/builtin.onyx index 97544d49..f0ab0944 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -27,7 +27,7 @@ package builtin // A string is simply a slice of bytes, and a c-string is a pointer // to byte, with a null-terminator ('\0') at the end. str :: #type [] u8; -cstr :: #type & u8; +cstr :: #type [&] u8; dyn_str :: #type [..] u8; @@ -292,7 +292,7 @@ cfree :: (ptr: rawptr) => raw_free(context.allocator, ptr); for s_info.members { if it.default != null { member_size := type_info.size_of(it.type); - memory.copy(cast(&u8) res + it.offset, it.default, member_size); + memory.copy(cast([&] u8) res + it.offset, it.default, member_size); } } } diff --git a/core/container/bucket_array.onyx b/core/container/bucket_array.onyx index d54577bb..098f0fcc 100644 --- a/core/container/bucket_array.onyx +++ b/core/container/bucket_array.onyx @@ -11,8 +11,8 @@ Bucket_Array :: struct (T: type_expr) { Bucket :: struct (T: type_expr) { count : i32; - data : &T; // Actually an array of elements_per_bucket things, but putting that - // that into the type system makes these cumbersome to work with. + data : [&] T; // Actually an array of elements_per_bucket things, but putting that + // that into the type system makes these cumbersome to work with. } } diff --git a/core/container/set.onyx b/core/container/set.onyx index 29bc7aa2..6c7352e5 100644 --- a/core/container/set.onyx +++ b/core/container/set.onyx @@ -133,7 +133,7 @@ as_iter :: (s: &Set) => (ctx) => { if ctx.i >= ctx.s.entries.count { - return (typeof &ctx.s.entries.data.value).{}, false; + return (typeof &ctx.s.entries.data[0].value).{}, false; } defer ctx.i += 1; diff --git a/core/conv/conv.onyx b/core/conv/conv.onyx index 4bbd3b81..e3dbdb69 100644 --- a/core/conv/conv.onyx +++ b/core/conv/conv.onyx @@ -155,7 +155,7 @@ i64_to_str :: (n: i64, base: u64, buf: [] u8, min_length := 0, prefix := false) n = -n; } - c := &buf[buf.count - 1]; + c: [&] u8 = ~~&buf[buf.count - 1]; len := 0; BASE64_MAP := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; @@ -163,21 +163,21 @@ i64_to_str :: (n: i64, base: u64, buf: [] u8, min_length := 0, prefix := false) while n > 0 { m := cast(u64) n % base; - *c = BASE64_MAP[cast(u32) m]; + c[0] = BASE64_MAP[cast(u32) m]; len += 1; c -= 1; n /= base; } else { - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } if min_length > 0 && len < min_length { for i: min_length - len { - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } @@ -185,26 +185,26 @@ i64_to_str :: (n: i64, base: u64, buf: [] u8, min_length := 0, prefix := false) if prefix { if base == 16 { - *c = #char "x"; + c[0] = #char "x"; len += 1; c -= 1; - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } if base == 2 { - *c = #char "b"; + c[0] = #char "b"; len += 1; c -= 1; - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } } if is_neg { - *c = #char "-"; + c[0] = #char "-"; len += 1; c -= 1; } @@ -217,7 +217,7 @@ i64_to_str :: (n: i64, base: u64, buf: [] u8, min_length := 0, prefix := false) // Converts an unsigned number into a string using the buffer provided. // Behaves like i64_to_str. u64_to_str :: (n: u64, base: u64, buf: [] u8, min_length := 0, prefix := false) -> str { - c := &buf[buf.count - 1]; + c: [&] u8 = ~~&buf[buf.count - 1]; len := 0; BASE64_MAP := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; @@ -225,21 +225,21 @@ u64_to_str :: (n: u64, base: u64, buf: [] u8, min_length := 0, prefix := false) while n > 0 { m := cast(u64) n % base; - *c = BASE64_MAP[cast(u32) m]; + c[0] = BASE64_MAP[cast(u32) m]; len += 1; c -= 1; n /= base; } else { - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } if min_length > 0 && len < min_length { for i: min_length - len { - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } @@ -247,19 +247,19 @@ u64_to_str :: (n: u64, base: u64, buf: [] u8, min_length := 0, prefix := false) if prefix { if base == 16 { - *c = #char "x"; + c[0] = #char "x"; len += 1; c -= 1; - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } if base == 2 { - *c = #char "b"; + c[0] = #char "b"; len += 1; c -= 1; - *c = #char "0"; + c[0] = #char "0"; len += 1; c -= 1; } diff --git a/core/conv/format.onyx b/core/conv/format.onyx index 1d89927b..2744345c 100644 --- a/core/conv/format.onyx +++ b/core/conv/format.onyx @@ -122,7 +122,7 @@ Custom_Parse_Proc :: struct { // When the internal buffer is filled, `flush` is called to empty the // buffer to the final destination. Format_Output :: struct { - data: &u8; + data: [&] u8; count: u32; capacity: u32; @@ -551,7 +551,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) { format.quote_strings = true; output->write("Some("); - format_any(output, &format, .{ ~~(cast(&u8) v.data + s.members[1].offset), s.members[1].type }); + format_any(output, &format, .{ ~~(cast([&] u8) v.data + s.members[1].offset), s.members[1].type }); output->write(")"); } else { @@ -586,7 +586,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) { output->write(member.name); output->write(" = "); - format_any(output, &format, .{ ~~(cast(&u8) v.data + member.offset), member.type }); + format_any(output, &format, .{ ~~(cast([&] u8) v.data + member.offset), member.type }); } } @@ -612,7 +612,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) { output->write("]"); } - if info.kind == .Pointer { + if info.kind == .Pointer || info.kind == .Multi_Pointer { value := *(cast(&rawptr) v.data); ibuf : [128] u8; @@ -645,7 +645,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) { for _: format.indentation do output->write(#char " "); } - format_any(output, &format, .{ ~~(cast(&u8) data + get_type_info(a.of).size * i), a.of }); + format_any(output, &format, .{ ~~(cast([&] u8) data + get_type_info(a.of).size * i), a.of }); } @@ -669,7 +669,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) { for i: a.count { if i != 0 do output->write(", "); - format_any(output, formatting, .{ ~~(cast(&u8) data + get_type_info(a.of).size * i), a.of }); + format_any(output, formatting, .{ ~~(cast([&] u8) data + get_type_info(a.of).size * i), a.of }); } output->write(" ]"); diff --git a/core/encoding/csv.onyx b/core/encoding/csv.onyx index a223b6ec..69ba266c 100644 --- a/core/encoding/csv.onyx +++ b/core/encoding/csv.onyx @@ -111,7 +111,7 @@ CSV_Column :: struct { header := &any_headers[entry.index]; if header.offset == -1 do continue; - target := cast(&u8) &out + header.offset; + target := cast([&] u8) &out + header.offset; if header.type == str { *cast(&str) target = string.alloc_copy(entry.value); diff --git a/core/encoding/osad.onyx b/core/encoding/osad.onyx index 9ac3ba8d..66edc3b5 100644 --- a/core/encoding/osad.onyx +++ b/core/encoding/osad.onyx @@ -60,7 +60,7 @@ serialize :: (v: any, w: &io.Writer) -> bool { case .Array { a_info := cast(&type_info.Type_Info_Array, info); - base: &u8 = ~~v.data; + base: [&] u8 = ~~v.data; elem_size := type_info.size_of(a_info.of); for a_info.count { @@ -72,8 +72,8 @@ serialize :: (v: any, w: &io.Writer) -> bool { s_info := cast(&type_info.Type_Info_Slice, info); untyped_slice := cast(&array.Untyped_Array, v.data); - base: &u8 = untyped_slice.data; - count: = untyped_slice.count; + base: [&] u8 = untyped_slice.data; + count: = untyped_slice.count; elem_size := type_info.size_of(s_info.of); output_u32(w, count); @@ -95,7 +95,7 @@ serialize :: (v: any, w: &io.Writer) -> bool { case .Struct { s_info := cast(&type_info.Type_Info_Struct, info); - base: &u8 = ~~v.data; + base: [&] u8 = ~~v.data; for& member: s_info.members { try(serialize(any.{ base + member.offset, member.type }, w)); @@ -166,7 +166,7 @@ deserialize :: (target: rawptr, type: type_expr, r: &io.Reader) -> bool { case .Array { a_info := cast(&type_info.Type_Info_Array, info); - base: &u8 = target; + base: [&] u8 = target; elem_size := type_info.size_of(a_info.of); for a_info.count { @@ -190,7 +190,7 @@ deserialize :: (target: rawptr, type: type_expr, r: &io.Reader) -> bool { untyped_slice.allocator = context.allocator; } - base: &u8 = untyped_slice.data; + base: [&] u8 = untyped_slice.data; for count { try(deserialize(base + it * elem_size, s_info.of, r)); @@ -200,7 +200,7 @@ deserialize :: (target: rawptr, type: type_expr, r: &io.Reader) -> bool { case .Struct { s_info := cast(&type_info.Type_Info_Struct, info); - base: &u8 = target; + base: [&] u8 = target; for& member: s_info.members { try(deserialize(base + member.offset, member.type, r)); diff --git a/core/io/stdio.onyx b/core/io/stdio.onyx index 23cc4b27..6a848979 100644 --- a/core/io/stdio.onyx +++ b/core/io/stdio.onyx @@ -133,7 +133,7 @@ tprintf :: (format: str, va: ..any) -> str { __byte_dump :: (ptr: rawptr, byte_count: u32, bytes_per_line := 8) { temp: [3] u8; - u8_ptr := cast(&u8) ptr; + u8_ptr := cast([&] u8) ptr; for i: byte_count { val := u8_ptr[i]; diff --git a/core/misc/any_utils.onyx b/core/misc/any_utils.onyx index c478a035..31d02351 100644 --- a/core/misc/any_utils.onyx +++ b/core/misc/any_utils.onyx @@ -45,7 +45,7 @@ any_subscript :: (v: any, index: i32) -> any { } return any.{ - cast(&u8) base_ptr + get_type_info(elem_type).size * index, + cast([&] u8) base_ptr + get_type_info(elem_type).size * index, elem_type }; } @@ -57,7 +57,7 @@ any_selector :: (v: any, member_name: str) -> any { if t.kind == .Struct { member := get_struct_member(v.type, member_name); if member != null { - return any.{cast(&u8) v.data + member.offset, member.type}; + return any.{cast([&] u8) v.data + member.offset, member.type}; } } @@ -75,11 +75,11 @@ any_nested_selector :: (v: any, member_name: str) -> any { member := get_struct_member(v.type, part_name); if member { if next_name { - return any_nested_selector(any.{cast(&u8) v.data + member.offset, member.type}, next_name); + return any_nested_selector(any.{cast([&] u8) v.data + member.offset, member.type}, next_name); } return any.{ - cast(&u8, v.data) + member.offset, member.type + cast([&] u8, v.data) + member.offset, member.type }; } @@ -139,7 +139,7 @@ any_iter :: (arr: any) -> Iterator(any) { (ctx: $T) -> (any, bool) { if ctx.index < ctx.count { defer ctx.index += 1; - return any.{ cast(&u8) ctx.base_ptr + ctx.elem_size * ctx.index, ctx.elem_type }, true; + return any.{ cast([&] u8) ctx.base_ptr + ctx.elem_size * ctx.index, ctx.elem_type }, true; } return .{}, false; diff --git a/core/misc/arg_parse.onyx b/core/misc/arg_parse.onyx index e3bde370..5e324881 100644 --- a/core/misc/arg_parse.onyx +++ b/core/misc/arg_parse.onyx @@ -49,7 +49,7 @@ arg_parse :: (c_args: [] cstr, output: any) -> bool { switch member.type { case bool { - *(cast(&bool) (cast(&u8) data_base + member.offset)) = !*(cast(&bool) (cast(&u8) data_base + member.offset)); + *(cast(&bool) (cast([&] u8) data_base + member.offset)) = !*(cast(&bool) (cast([&] u8) data_base + member.offset)); } case i32 { @@ -57,14 +57,14 @@ arg_parse :: (c_args: [] cstr, output: any) -> bool { if !success do return false; value := conv.str_to_i64(value_str); - *(cast(&i32) (cast(&u8) data_base + member.offset)) = ~~value; + *(cast(&i32) (cast([&] u8) data_base + member.offset)) = ~~value; } case str { value, success := iter.take_one(arg_iter, no_close=true); if !success do return false; - *(cast(&str) (cast(&u8) data_base + member.offset)) = value; + *(cast(&str) (cast([&] u8) data_base + member.offset)) = value; } case #default { diff --git a/core/net/net.onyx b/core/net/net.onyx index 59886132..810a7cf2 100644 --- a/core/net/net.onyx +++ b/core/net/net.onyx @@ -91,7 +91,7 @@ make_unix_address :: (out: &Socket_Address, path: str) { // at the address where the addr field is in the Socket_Address. // We also have to append a null-terminator, as that is what will // be expected from any C function. - out_path := cast(&u8) &out.addr; + out_path := cast([&] u8) &out.addr; offset := 0; while offset < math.min(path.count, UNIX_SOCKET_PATH_LEN - 1) { defer offset += 1; diff --git a/core/os/file.onyx b/core/os/file.onyx index 70a77314..9a2e7b32 100644 --- a/core/os/file.onyx +++ b/core/os/file.onyx @@ -57,7 +57,7 @@ rename_file :: fs.__file_rename get_contents_from_file :: (file: &File) -> str { size := cast(u32) io.stream_size(file); - data := cast(&u8) raw_alloc(context.allocator, size); + data := cast([&] u8) raw_alloc(context.allocator, size); _, prev_loc := io.stream_tell(file); io.stream_seek(file, 0, .Start); diff --git a/core/runtime/info/helper.onyx b/core/runtime/info/helper.onyx index ce96d012..e063f1a0 100644 --- a/core/runtime/info/helper.onyx +++ b/core/runtime/info/helper.onyx @@ -47,6 +47,12 @@ write_type_name :: (writer: &io.Writer, t: type_expr) { write_type_name(writer, pointer.to); } + case .Multi_Pointer { + pointer := cast(&Type_Info_Multi_Pointer) info; + io.write_str(writer, "[&] "); + write_type_name(writer, pointer.to); + } + case .Array { arr := cast(&Type_Info_Array) info; io.write_format(writer, "[{}] ", arr.count); diff --git a/core/runtime/info/types.onyx b/core/runtime/info/types.onyx index 638da96b..2ed01221 100644 --- a/core/runtime/info/types.onyx +++ b/core/runtime/info/types.onyx @@ -11,16 +11,17 @@ Type_Info :: struct { Invalid :: 0x00; // Unused Basic :: 0x01; Pointer :: 0x02; - Function :: 0x03; - Struct :: 0x04; - Polymorphic_Struct :: 0x05; - Compound :: 0x06; - Array :: 0x07; - Slice :: 0x08; - Dynamic_Array :: 0x09; - Variadic_Argument :: 0x0a; - Enum :: 0x0b; - Distinct :: 0x0c; + Multi_Pointer :: 0x03; + Function :: 0x04; + Struct :: 0x05; + Polymorphic_Struct :: 0x06; + Compound :: 0x07; + Array :: 0x08; + Slice :: 0x09; + Dynamic_Array :: 0x0A; + Variadic_Argument :: 0x0B; + Enum :: 0x0C; + Distinct :: 0x0D; } kind := Kind.Invalid; @@ -75,6 +76,13 @@ Type_Info_Pointer :: struct { to: type_expr; } +Type_Info_Multi_Pointer :: struct { + use base : Type_Info; + + // @Rename + to: type_expr; +} + Type_Info_Function :: struct { use base : Type_Info; diff --git a/core/runtime/platform/onyx/fs.onyx b/core/runtime/platform/onyx/fs.onyx index 3b49f1bf..8ef4f1b9 100644 --- a/core/runtime/platform/onyx/fs.onyx +++ b/core/runtime/platform/onyx/fs.onyx @@ -97,7 +97,7 @@ __file_stream_vtable := io.Stream_Vtable.{ write_byte = (use fs: &os.File, byte: u8) -> io.Error { b := byte; bytes_wrote: u64; - error := __file_write(data, .{ &b, 1 }, &bytes_wrote); + error := __file_write(data, .{ ~~&b, 1 }, &bytes_wrote); return error; }, diff --git a/core/string/buffer.onyx b/core/string/buffer.onyx index cbdd5533..ea912820 100644 --- a/core/string/buffer.onyx +++ b/core/string/buffer.onyx @@ -9,7 +9,7 @@ package core.string use core {math} String_Buffer :: struct { - data : &u8; + data : [&] u8; count : u32; capacity : u32; } diff --git a/core/string/string.onyx b/core/string/string.onyx index f16ae9b1..e0309725 100644 --- a/core/string/string.onyx +++ b/core/string/string.onyx @@ -48,7 +48,7 @@ copy :: (orig: str, dest: str) { #match as_str from_cstr from_cstr :: (s: cstr) -> str { - return .{ data = s, count = length(s) }; + return .{ data = ~~s, count = length(s) }; } @@ -60,8 +60,8 @@ length :: (s: str) => s.count; #overload length :: (s: cstr) -> u32 { len := 0; - c := s; - while *c != #char "\0" { + c: [&] u8 = s; + while c[0] != #char "\0" { len += 1; c += 1; } @@ -77,7 +77,7 @@ concat :: (s1: str, s2: str, allocator := context.allocator) -> str { len1 := length(s1); len2 := length(s2); - data := cast(&u8) raw_alloc(allocator, len1 + len2); + data := cast([&] u8) raw_alloc(allocator, len1 + len2); memory.copy(data, s1.data, len1); memory.copy(data + len1, s2.data, len2); @@ -94,7 +94,7 @@ concat :: (allocator: Allocator, strings: ..str) -> str { total_length := 0; for s: strings do total_length += s.count; - data := cast(&u8) raw_alloc(allocator, total_length); + data := cast([&] u8) raw_alloc(allocator, total_length); offset := 0; for s: strings { memory.copy(data + offset, s.data, s.count); @@ -564,7 +564,7 @@ split :: (s: str, delim: u8, allocator := context.allocator) -> []str { delim_count := 0; for i: 0 .. s.count do if s[i] == delim do delim_count += 1; - strarr := cast(&str) raw_alloc(allocator, sizeof str * (delim_count + 1)); + strarr := cast([&] str) raw_alloc(allocator, sizeof str * (delim_count + 1)); curr_str := 0; begin := 0; diff --git a/tests/aoc-2020/day13.onyx b/tests/aoc-2020/day13.onyx index 65fe309a..ece1646c 100644 --- a/tests/aoc-2020/day13.onyx +++ b/tests/aoc-2020/day13.onyx @@ -51,7 +51,7 @@ main :: (args: [] cstr) { offset: i64 = 0; while !string.empty(file) { - if *file.data == #char "x" { + if file.data[0] == #char "x" { string.advance(&file, 2); } else { bus := conv.parse_int(&file); diff --git a/tests/aoc-2020/day16.onyx b/tests/aoc-2020/day16.onyx index 35331144..d1c29117 100644 --- a/tests/aoc-2020/day16.onyx +++ b/tests/aoc-2020/day16.onyx @@ -19,7 +19,7 @@ field_valid :: (use field: &Field, n: u32) -> bool { total_scanning_error := 0; -read_ticket_and_validate :: (file: &str, fields: [..] Field, ticket_store: &u32) -> bool { +read_ticket_and_validate :: (file: &str, fields: [..] Field, ticket_store: [&] u32) -> bool { retval := true; for i: 0 .. fields.count { @@ -86,7 +86,7 @@ main :: (args: [] cstr) { while !string.empty(file) { array.ensure_capacity(&ticket_data, ticket_data.count + fields.count); - if read_ticket_and_validate(&file, fields, &ticket_data[ticket_data.count]) { + if read_ticket_and_validate(&file, fields, ~~ &ticket_data[ticket_data.count]) { ticket_data.count += fields.count; } } diff --git a/tests/aoc-2020/day18.onyx b/tests/aoc-2020/day18.onyx index ac8c69ce..f690de0d 100644 --- a/tests/aoc-2020/day18.onyx +++ b/tests/aoc-2020/day18.onyx @@ -5,7 +5,7 @@ use package core parse_factor :: (file: &str) -> u64 { string.strip_leading_whitespace(file); - switch *file.data { + switch file.data[0] { case #char "0" .. #char "9" { return conv.parse_int(file); } @@ -31,7 +31,7 @@ parse_expression_add :: (file: &str) -> u64 { left := parse_factor(file); string.strip_leading_whitespace(file); - while *file.data == #char "+" { + while file.data[0] == #char "+" { op := file.data[0]; string.advance(file, 1); @@ -51,7 +51,7 @@ parse_expression_mul :: (file: &str) -> u64 { left := parse_expression_add(file); string.strip_leading_whitespace(file); - while *file.data == #char "*" { + while file.data[0] == #char "*" { op := file.data[0]; string.advance(file, 1); diff --git a/tests/aoc-2020/day19.onyx b/tests/aoc-2020/day19.onyx index 955f5602..da06eabb 100644 --- a/tests/aoc-2020/day19.onyx +++ b/tests/aoc-2020/day19.onyx @@ -76,7 +76,7 @@ cyk_algorithm :: (use grammar: &Grammar, input: str) -> bool { dim_2 := 1; mem_size := sizeof bool * input.count * input.count * max_terminal; - T := cast(&bool) calloc(mem_size); + T := cast([&] bool) calloc(mem_size); defer cfree(T); memory.set(T, ~~false, mem_size); @@ -113,12 +113,12 @@ main :: (args: [] cstr) { grammar_init(&grammar); defer grammar_free(&grammar); - while *file.data != #char "\n" { + while file[0] != #char "\n" { nt0 := cast(u32, conv.parse_int(&file)); string.advance(&file, 2); // ': ' - if *file.data == #char "\"" { + if file[0] == #char "\"" { string.advance(&file, 1); // '"' t := file[0]; string.advance(&file, 1); @@ -129,23 +129,23 @@ main :: (args: [] cstr) { while true { nt1 := cast(u32, conv.parse_int(&file)); - if *file.data == #char "\n" { + if file[0] == #char "\n" { array.push(&grammar.unit_rules, Unit.{ nt0, nt1 }); break; } else { string.advance(&file, 1); // ' ' - if next_ch := *file.data; next_ch >= #char "0" && next_ch <= #char "9" { + if next_ch := file[0]; next_ch >= #char "0" && next_ch <= #char "9" { nt2 := cast(u32, conv.parse_int(&file)); array.push(&grammar.production_rules, Prod.{ nt0, nt1, nt2 }); - if *file.data == #char " " do string.advance(&file, 1); + if file[0] == #char " " do string.advance(&file, 1); } else { array.push(&grammar.unit_rules, Unit.{ nt0, nt1 }); } - if *file.data == #char "|" { + if file[0] == #char "|" { string.advance(&file, 1); // ' |' } else { break; diff --git a/tests/aoc-2020/day20.onyx b/tests/aoc-2020/day20.onyx index 7ddf6a8a..c116d713 100644 --- a/tests/aoc-2020/day20.onyx +++ b/tests/aoc-2020/day20.onyx @@ -179,7 +179,7 @@ apply_orientation :: (t: &Tile, ori: TO) { t.orientation = ori; } -index_square_with_orientation :: (data: &$T, ori: TO, size: i32, x: i32, y: i32) -> &T { +index_square_with_orientation :: (data: [&] $T, ori: TO, size: i32, x: i32, y: i32) -> &T { switch ori { case TO.N do return &data[x + y * size]; case TO.R90 do return &data[y + (size - 1 - x) * size]; @@ -202,7 +202,7 @@ sea_monster := u8.[ #char" ",#char"#",#char" ",#char" ",#char"#",#char" ",#char" ",#char"#",#char" ",#char" ",#char"#",#char" ",#char" ",#char"#",#char" ",#char" ",#char"#",#char" ",#char" ",#char" ", ]; -scan_for_monsters :: (forest: &u8, ori: TO, width: u32, height: u32) -> bool { +scan_for_monsters :: (forest: [&] u8, ori: TO, width: u32, height: u32) -> bool { found_monsters := false; for y: 0 .. height - sea_monster_height { @@ -264,7 +264,7 @@ main :: (args: [] cstr) { string.advance_line(&file); - td := cast(&bool) raw_alloc(tile_allocator, sizeof TileData); + td := cast([&] bool) raw_alloc(tile_allocator, sizeof TileData); for y: 0 .. 10 { line, file~ := string.bisect(file, #char "\n"); @@ -352,7 +352,7 @@ main :: (args: [] cstr) { for fy: 0 .. 8 { for fx: 0 .. 8 { - res := *index_square_with_orientation(cast(&bool) tile.data.data, tile.orientation, 10, fx + 1, fy + 1); + res := *index_square_with_orientation(cast([&] bool) tile.data.data, tile.orientation, 10, fx + 1, fy + 1); loc := (y * 12 * 8 * 8) + (fy * 12 * 8) + (x * 8) + fx; if res do forest[loc] = #char "#"; else do forest[loc] = #char "."; @@ -362,7 +362,7 @@ main :: (args: [] cstr) { } for ori: .[ TO.N, TO.R90, TO.R180, TO.R270, TO.F, TO.FR90, TO.FR180, TO.FR270 ] { - if scan_for_monsters(cast(&u8) forest, ori, 12 * 8, 12 * 8) do break; + if scan_for_monsters(cast([&] u8) forest, ori, 12 * 8, 12 * 8) do break; } safe_count := 0; diff --git a/tests/aoc-2020/day21.onyx b/tests/aoc-2020/day21.onyx index 33abd5f9..01fdfedf 100644 --- a/tests/aoc-2020/day21.onyx +++ b/tests/aoc-2020/day21.onyx @@ -51,7 +51,7 @@ main :: (args: [] cstr) { array.init(&food.ingredients, 16); array.init(&food.allergens); - while *file.data != #char "(" { + while file[0] != #char "(" { ingredient_name := string.read_alphanum(&file); string.advance(&file, 1); // ' ' @@ -70,9 +70,9 @@ main :: (args: [] cstr) { string.advance(&file, 10); // '(contains ' - while *file.data != #char ")" { + while file[0] != #char ")" { allergen_name := string.read_alphanum(&file); - if *file.data == #char "," do string.advance(&file, 2); // ', ' + if file[0] == #char "," do string.advance(&file, 2); // ', ' array.push(&food.allergens, allergen_name); diff --git a/tests/aoc-2020/day22.onyx b/tests/aoc-2020/day22.onyx index ab98c9de..fdbbf7b3 100644 --- a/tests/aoc-2020/day22.onyx +++ b/tests/aoc-2020/day22.onyx @@ -110,7 +110,7 @@ main :: (args: [] cstr) { defer array.free(&player2); string.advance_line(&file); // 'Player 1:' - while *file.data != #char "\n" { + while file[0] != #char "\n" { card := cast(u32, conv.parse_int(&file)); array.push(&player1, card); diff --git a/tests/aoc-2021/day14.onyx b/tests/aoc-2021/day14.onyx index d43166f4..aa4e3361 100644 --- a/tests/aoc-2021/day14.onyx +++ b/tests/aoc-2021/day14.onyx @@ -30,7 +30,7 @@ main :: (args) => { rules: [..] Rule; while !io.reader_empty(&reader) { r: Rule; - io.read_bytes(&reader, .{cast(&u8) &r.pair, 2}); + io.read_bytes(&reader, .{cast([&] u8) &r.pair, 2}); io.skip_bytes(&reader, 4); r.insert = io.read_byte(&reader); diff --git a/tests/baked_parameters.onyx b/tests/baked_parameters.onyx index cb0e4cdd..eaf0d603 100644 --- a/tests/baked_parameters.onyx +++ b/tests/baked_parameters.onyx @@ -8,7 +8,7 @@ count_to :: ($N: i32) { } alloc_slice :: ($T: type_expr, N: i32) -> [] T { - data := cast(&T) calloc(sizeof T * N); + data := cast([&] T) calloc(sizeof T * N); return .{ data, N }; } -- 2.25.1