Browse Source

Mock out `any` type `switch` statement

gingerBill 2 years ago
parent
commit
f32d71eca0
3 changed files with 85 additions and 13 deletions
  1. 80 0
      src/tilde_backend.cpp
  2. 0 5
      src/tilde_expr.cpp
  3. 5 8
      src/tilde_stmt.cpp

+ 80 - 0
src/tilde_backend.cpp

@@ -186,6 +186,86 @@ gb_internal isize cg_type_info_index(CheckerInfo *info, Type *type, bool err_on_
 	return -1;
 	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 {
 struct cgGlobalVariable {
 	cgValue var;
 	cgValue var;
 	cgValue init;
 	cgValue init;

+ 0 - 5
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);
 	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) {
 gb_internal cgValue cg_emit_union_tag_ptr(cgProcedure *p, cgValue const &parent_ptr) {
 	Type *t = parent_ptr.type;
 	Type *t = parent_ptr.type;
 	Type *ut = base_type(type_deref(t));
 	Type *ut = base_type(type_deref(t));

+ 5 - 8
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);
 			tag = cg_emit_load(p, tag_ptr);
 		}
 		}
 	} else if (switch_kind == TypeSwitch_Any) {
 	} 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));
 		tag = cg_emit_load(p, cg_emit_struct_ep(p, parent_ptr, 1));
 	} else {
 	} else {
 		GB_PANIC("Unknown switch kind");
 		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);
 					key = union_variant_index(ut, case_type);
 				}
 				}
 			} else if (switch_kind == TypeSwitch_Any) {
 			} 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);
 			GB_ASSERT(key >= 0);