aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-07-19 20:44:37 +0100
committergingerBill <bill@gingerbill.org>2023-07-19 20:44:37 +0100
commitf32d71eca05983520fb5e39cd9c7802200353adb (patch)
tree2e1f43b3ead3e0c5c04a38bae3ade64a38abe86c /src
parent5fb98609cd9d5d7efea6d54a722181ff46413333 (diff)
Mock out `any` type `switch` statement
Diffstat (limited to 'src')
-rw-r--r--src/tilde_backend.cpp80
-rw-r--r--src/tilde_expr.cpp5
-rw-r--r--src/tilde_stmt.cpp13
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);