From 3868a9a0f00185b6f8f587f67a62cbd12a215336 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Mon, 10 Jul 2017 23:15:41 +0100 Subject: [PATCH] Clean up _preload.odin types --- core/_preload.odin | 55 ++++++++++++++++++++++------------------------ core/fmt.odin | 45 +++---------------------------------- core/mem.odin | 8 +++---- src/check_expr.cpp | 4 ++-- src/ir.cpp | 10 +++++---- src/parser.cpp | 25 ++++++++++++++------- src/types.cpp | 31 ++++++++++---------------- 7 files changed, 70 insertions(+), 108 deletions(-) diff --git a/core/_preload.odin b/core/_preload.odin index 4201823f2..0d6d0b74c 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -17,12 +17,14 @@ import ( // Local Variables: snake_case // Constant Variables: SCREAMING_SNAKE_CASE + + + // IMPORTANT NOTE(bill): `type_info` cannot be used within a // #shared_global_scope due to the internals of the compiler. // This could change at a later date if the all these data structures are // implemented within the compiler rather than in this "preload" file - // NOTE(bill): This must match the compiler's CallingConvention :: enum { Invalid = 0, @@ -81,13 +83,7 @@ TypeInfo :: struct #ordered { Struct :: Record; RawUnion :: Record; Union :: struct #ordered { - common_fields: struct #ordered { - types: []^TypeInfo; - names: []string; - offsets: []int; // offsets may not be used in tuples - }; - variant_names: []string; - variant_types: []^TypeInfo; + variants: []^TypeInfo; }; Enum :: struct #ordered { base: ^TypeInfo; @@ -145,17 +141,19 @@ __argv__: ^^u8; __argc__: i32; // IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it) -AllocatorMode :: enum u8 { - Alloc, - Free, - FreeAll, - Resize, -} -AllocatorProc :: proc(allocator_data: rawptr, mode: AllocatorMode, - size, alignment: int, - old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr; + Allocator :: struct #ordered { - procedure: AllocatorProc; + Mode :: enum u8 { + Alloc, + Free, + FreeAll, + Resize, + } + Proc :: proc(allocator_data: rawptr, mode: Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64 = 0) -> rawptr; + + procedure: Proc; data: rawptr; } @@ -283,26 +281,26 @@ __check_context :: proc() { alloc :: proc(size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline { a := context.allocator; - return a.procedure(a.data, AllocatorMode.Alloc, size, alignment, nil, 0, 0); + return a.procedure(a.data, Allocator.Mode.Alloc, size, alignment, nil, 0, 0); } free_ptr_with_allocator :: proc(a: Allocator, ptr: rawptr) #inline { if ptr == nil do return; if a.procedure == nil do return; - a.procedure(a.data, AllocatorMode.Free, 0, 0, ptr, 0, 0); + a.procedure(a.data, Allocator.Mode.Free, 0, 0, ptr, 0, 0); } free_ptr :: proc(ptr: rawptr) #inline do free_ptr_with_allocator(context.allocator, ptr); free_all :: proc() #inline { a := context.allocator; - a.procedure(a.data, AllocatorMode.FreeAll, 0, 0, nil, 0, 0); + a.procedure(a.data, Allocator.Mode.FreeAll, 0, 0, nil, 0, 0); } resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_ALIGNMENT) -> rawptr #inline { a := context.allocator; - return a.procedure(a.data, AllocatorMode.Resize, new_size, alignment, ptr, old_size, 0); + return a.procedure(a.data, Allocator.Mode.Resize, new_size, alignment, ptr, old_size, 0); } @@ -403,7 +401,7 @@ reserve :: proc(array: ^[dynamic]$T, capacity: int) -> bool { new_size := capacity * size_of(T); allocator := a.allocator; - new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, align_of(T), a.data, old_size, 0); + new_data := allocator.procedure(allocator.data, Allocator.Mode.Resize, new_size, align_of(T), a.data, old_size, 0); if new_data == nil do return false; a.data = new_data; @@ -503,10 +501,10 @@ default_resize_align :: proc(old_memory: rawptr, old_size, new_size, alignment: } -default_allocator_proc :: proc(allocator_data: rawptr, mode: AllocatorMode, +default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator.Mode, size, alignment: int, old_memory: rawptr, old_size: int, flags: u64) -> rawptr { - using AllocatorMode; + using Allocator.Mode; match mode { case Alloc: @@ -715,7 +713,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: new_size := cap * elem_size; allocator := array.allocator; - new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, elem_align, array.data, old_size, 0); + new_data := allocator.procedure(allocator.data, Allocator.Mode.Resize, new_size, elem_align, array.data, old_size, 0); if new_data == nil do return false; array.data = new_data; @@ -736,9 +734,8 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int, items: rawptr, item_count: int) -> int { array := ^raw.DynamicArray(array_); - if item_count <= 0 || items == nil { - return array.len; - } + if items == nil do return 0; + if item_count <= 0 do return 0; ok := true; diff --git a/core/fmt.odin b/core/fmt.odin index 8b44587fa..ce57abd06 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -295,32 +295,9 @@ write_type :: proc(buf: ^StringBuffer, ti: ^TypeInfo) { case Union: write_string(buf, "union {"); - cf := info.common_fields; - total_count := 0; - for name, i in cf.names { + for variant, i in info.variants { if i > 0 do write_string(buf, ", "); - write_string(buf, name); - write_string(buf, ": "); - write_type(buf, cf.types[i]); - total_count++; - } - for name, i in info.variant_names { - if total_count > 0 || i > 0 do write_string(buf, ", "); - write_string(buf, name); - write_byte(buf, '{'); - defer write_byte(buf, '}'); - - variant_type := type_info_base(info.variant_types[i]).variant; - variant := (&variant_type).(Struct); - - vc := len(variant.names)-len(cf.names); - for j in 0..vc { - if j > 0 do write_string(buf, ", "); - index := j + len(cf.names); - write_string(buf, variant.names[index]); - write_string(buf, ": "); - write_type(buf, variant.types[index]); - } + write_type(buf, variant); } write_string(buf, "}"); @@ -897,23 +874,7 @@ fmt_value :: proc(fi: ^FmtInfo, v: any, verb: rune) { } case Union: - write_byte(fi.buf, '{'); - defer write_byte(fi.buf, '}'); - - cf := info.common_fields; - for _, i in cf.names { - if i > 0 do write_string(fi.buf, ", "); - - write_string(fi.buf, cf.names[i]); - write_string(fi.buf, " = "); - - if t := cf.types[i]; types.is_any(t) { - write_string(fi.buf, "any{}"); - } else { - data := ^u8(v.data) + cf.offsets[i]; - fmt_arg(fi, any{rawptr(data), t}, 'v'); - } - } + write_string(fi.buf, "(union)"); case RawUnion: write_string(fi.buf, "(raw_union)"); diff --git a/core/mem.odin b/core/mem.odin index 94d1f2cc2..6c0d95e98 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -137,10 +137,10 @@ arena_allocator :: proc(arena: ^Arena) -> Allocator { }; } -arena_allocator_proc :: proc(allocator_data: rawptr, mode: AllocatorMode, - size, alignment: int, - old_memory: rawptr, old_size: int, flags: u64) -> rawptr { - using AllocatorMode; +arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator.Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, flags: u64) -> rawptr { + using Allocator.Mode; arena := ^Arena(allocator_data); match mode { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d135cf3dd..fab388d9f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6837,14 +6837,14 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t o->type = t; o->mode = Addressing_OptionalOk; - } else if (is_type_any(o->type)) { + } else if (is_type_any(src)) { o->type = t; o->mode = Addressing_OptionalOk; add_type_info_type(c, o->type); add_type_info_type(c, t); } else { - error(o->expr, "Type assertions can only operate on unions"); + error(o->expr, "Type assertions can only operate on unions and `any`"); o->mode = Addressing_Invalid; o->expr = node; return kind; diff --git a/src/ir.cpp b/src/ir.cpp index 4ff15ca32..980788f3e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3339,6 +3339,11 @@ irValue *ir_emit_union_cast(irProcedure *proc, irValue *value, Type *type, Token irAddr ir_emit_any_cast_addr(irProcedure *proc, irValue *value, Type *type, TokenPos pos) { gbAllocator a = proc->module->allocator; Type *src_type = ir_type(value); + + if (is_type_pointer(src_type)) { + value = ir_emit_load(proc, value); + } + bool is_tuple = true; Type *tuple = type; if (type->kind != Type_Tuple) { @@ -8049,11 +8054,9 @@ void ir_gen_tree(irGen *s) { tag = ir_emit_conv(proc, variant_ptr, t_type_info_union_ptr); { - irValue *variant_names = ir_emit_struct_ep(proc, tag, 1); - irValue *variant_types = ir_emit_struct_ep(proc, tag, 2); + irValue *variant_types = ir_emit_struct_ep(proc, tag, 0); isize variant_count = gb_max(0, t->Union.variant_count-1); - irValue *memory_names = ir_type_info_member_names_offset(proc, variant_count); irValue *memory_types = ir_type_info_member_types_offset(proc, variant_count); // NOTE(bill): Zeroth is nil so ignore it @@ -8067,7 +8070,6 @@ void ir_gen_tree(irGen *s) { } irValue *count = ir_const_int(a, variant_count); - ir_fill_slice(proc, variant_names, memory_names, count, count); ir_fill_slice(proc, variant_types, memory_types, count, count); } diff --git a/src/parser.cpp b/src/parser.cpp index ef4c9809b..8a55a31ea 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4134,20 +4134,29 @@ AstNode *parse_match_stmt(AstFile *f) { if (f->curr_token.kind != Token_OpenBrace) { isize prev_level = f->expr_level; f->expr_level = -1; + defer (f->expr_level = prev_level); - tag = parse_simple_stmt(f, StmtAllowFlag_In); - if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) { + if (allow_token(f, Token_in)) { + Array lhs = {}; + Array rhs = make_ast_node_array(f, 1); + array_add(&rhs, parse_expr(f, false)); + + tag = ast_assign_stmt(f, token, lhs, rhs); is_type_match = true; } else { - if (allow_token(f, Token_Semicolon)) { - init = tag; - tag = nullptr; - if (f->curr_token.kind != Token_OpenBrace) { - tag = parse_simple_stmt(f, StmtAllowFlag_None); + tag = parse_simple_stmt(f, StmtAllowFlag_In); + if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) { + is_type_match = true; + } else { + if (allow_token(f, Token_Semicolon)) { + init = tag; + tag = nullptr; + if (f->curr_token.kind != Token_OpenBrace) { + tag = parse_simple_stmt(f, StmtAllowFlag_None); + } } } } - f->expr_level = prev_level; } open = expect_token(f, Token_OpenBrace); diff --git a/src/types.cpp b/src/types.cpp index 52a14e352..786c4b13a 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -84,23 +84,13 @@ struct TypeRecord { // All record types // Theses are arrays - // Entity_Variable - struct/raw_union/union (for common fields) - // Entity_Constant - enum + // Entity_Variable - struct/raw_union (for common fields) Entity **fields; i32 field_count; // == struct_offsets count Entity **fields_in_src_order; // Entity_Variable AstNode *node; Scope * scope; - // Entity_TypeName - union - // Type ** variants; - // i32 variant_count; - // Entity * union__tag; - // i64 variant_block_size; // NOTE(bill): Internal use only - - // Type * variant_parent; - // i32 variant_index; - i64 * offsets; bool are_offsets_set; bool are_offsets_being_processed; @@ -109,11 +99,6 @@ struct TypeRecord { i64 custom_align; // NOTE(bill): Only used in structs at the moment Entity * names; - - // Type * enum_base_type; - // Entity * enum_count; - // Entity * enum_min_value; - // Entity * enum_max_value; }; #define TYPE_KINDS \ @@ -144,8 +129,6 @@ struct TypeRecord { Scope * scope; \ Entity * union__tag; \ i64 variant_block_size; \ - Type * variant_parent; \ - i32 variant_index; \ i64 custom_align; \ }) \ TYPE_KIND(Named, struct { \ @@ -1559,14 +1542,24 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } if (is_type) { - if (type->kind == Type_Record) { + switch (type->kind) { + case Type_Record: if (type->Record.names != nullptr && field_name == "names") { sel.entity = type->Record.names; return sel; } + break; + case Type_Enum: + if (type->Enum.names != nullptr && + field_name == "names") { + sel.entity = type->Enum.names; + return sel; + } + break; } + if (is_type_enum(type)) { // NOTE(bill): These may not have been added yet, so check in case if (type->Enum.count != nullptr) {