From f32d71eca05983520fb5e39cd9c7802200353adb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 19 Jul 2023 20:44:37 +0100 Subject: [PATCH] Mock out `any` type `switch` statement --- src/tilde_backend.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++ src/tilde_expr.cpp | 5 --- src/tilde_stmt.cpp | 13 +++---- 3 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/tilde_backend.cpp b/src/tilde_backend.cpp index 9ac2d2f12..e76912895 100644 --- a/src/tilde_backend.cpp +++ b/src/tilde_backend.cpp @@ -186,6 +186,86 @@ gb_internal isize cg_type_info_index(CheckerInfo *info, Type *type, bool err_on_ return -1; } + +gb_internal u64 cg_typeid_as_u64(cgModule *m, Type *type) { + GB_ASSERT(!build_context.no_rtti); + + type = default_type(type); + + u64 id = cast(u64)cg_type_info_index(m->info, type); + GB_ASSERT(id >= 0); + + u64 kind = Typeid_Invalid; + u64 named = is_type_named(type) && type->kind != Type_Basic; + u64 special = 0; + u64 reserved = 0; + + Type *bt = base_type(type); + TypeKind tk = bt->kind; + switch (tk) { + case Type_Basic: { + u32 flags = bt->Basic.flags; + if (flags & BasicFlag_Boolean) kind = Typeid_Boolean; + if (flags & BasicFlag_Integer) kind = Typeid_Integer; + if (flags & BasicFlag_Unsigned) kind = Typeid_Integer; + if (flags & BasicFlag_Float) kind = Typeid_Float; + if (flags & BasicFlag_Complex) kind = Typeid_Complex; + if (flags & BasicFlag_Pointer) kind = Typeid_Pointer; + if (flags & BasicFlag_String) kind = Typeid_String; + if (flags & BasicFlag_Rune) kind = Typeid_Rune; + } break; + case Type_Pointer: kind = Typeid_Pointer; break; + case Type_MultiPointer: kind = Typeid_Multi_Pointer; break; + case Type_Array: kind = Typeid_Array; break; + case Type_Matrix: kind = Typeid_Matrix; break; + case Type_EnumeratedArray: kind = Typeid_Enumerated_Array; break; + case Type_Slice: kind = Typeid_Slice; break; + case Type_DynamicArray: kind = Typeid_Dynamic_Array; break; + case Type_Map: kind = Typeid_Map; break; + case Type_Struct: kind = Typeid_Struct; break; + case Type_Enum: kind = Typeid_Enum; break; + case Type_Union: kind = Typeid_Union; break; + case Type_Tuple: kind = Typeid_Tuple; break; + case Type_Proc: kind = Typeid_Procedure; break; + case Type_BitSet: kind = Typeid_Bit_Set; break; + case Type_SimdVector: kind = Typeid_Simd_Vector; break; + case Type_RelativePointer: kind = Typeid_Relative_Pointer; break; + case Type_RelativeSlice: kind = Typeid_Relative_Slice; break; + case Type_SoaPointer: kind = Typeid_SoaPointer; break; + } + + if (is_type_cstring(type)) { + special = 1; + } else if (is_type_integer(type) && !is_type_unsigned(type)) { + special = 1; + } + + u64 data = 0; + if (build_context.ptr_size == 4) { + GB_ASSERT(id <= (1u<<24u)); + data |= (id &~ (1u<<24)) << 0u; // index + data |= (kind &~ (1u<<5)) << 24u; // kind + data |= (named &~ (1u<<1)) << 29u; // named + data |= (special &~ (1u<<1)) << 30u; // special + data |= (reserved &~ (1u<<1)) << 31u; // reserved + } else { + GB_ASSERT(build_context.ptr_size == 8); + GB_ASSERT(id <= (1ull<<56u)); + data |= (id &~ (1ull<<56)) << 0ul; // index + data |= (kind &~ (1ull<<5)) << 56ull; // kind + data |= (named &~ (1ull<<1)) << 61ull; // named + data |= (special &~ (1ull<<1)) << 62ull; // special + data |= (reserved &~ (1ull<<1)) << 63ull; // reserved + } + return data; +} + +gb_internal cgValue cg_typeid(cgProcedure *p, Type *t) { + u64 x = cg_typeid_as_u64(p->module, t); + return cg_value(tb_inst_uint(p->func, cg_data_type(t_typeid), x), t_typeid); +} + + struct cgGlobalVariable { cgValue var; cgValue init; diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index f3801682d..2d4b11336 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -120,11 +120,6 @@ gb_internal cgAddr cg_build_addr_from_entity(cgProcedure *p, Entity *e, Ast *exp return cg_addr(v); } -gb_internal cgValue cg_typeid(cgProcedure *p, Type *t) { - GB_ASSERT("TODO(bill): cg_typeid"); - return {}; -} - gb_internal cgValue cg_emit_union_tag_ptr(cgProcedure *p, cgValue const &parent_ptr) { Type *t = parent_ptr.type; Type *ut = base_type(type_deref(t)); diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index a2dfa0257..c5aaa9161 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -1323,7 +1323,6 @@ gb_internal void cg_build_type_switch_stmt(cgProcedure *p, Ast *node) { tag = cg_emit_load(p, tag_ptr); } } else if (switch_kind == TypeSwitch_Any) { - GB_PANIC("TODO(bill): type switch any"); tag = cg_emit_load(p, cg_emit_struct_ep(p, parent_ptr, 1)); } else { GB_PANIC("Unknown switch kind"); @@ -1406,13 +1405,11 @@ gb_internal void cg_build_type_switch_stmt(cgProcedure *p, Ast *node) { key = union_variant_index(ut, case_type); } } else if (switch_kind == TypeSwitch_Any) { - GB_PANIC("TODO(bill): any"); - // if (is_type_untyped_nil(case_type)) { - // saw_nil = true; - // on_val = lb_const_nil(m, t_typeid); - // } else { - // on_val = lb_typeid(m, case_type); - // } + if (is_type_untyped_nil(case_type)) { + key = 0; + } else { + key = cast(i64)cg_typeid_as_u64(p->module, case_type); + } } GB_ASSERT(key >= 0);