Add bit_set type

This commit is contained in:
gingerBill
2018-08-14 17:07:56 +01:00
parent 89f4e7a8db
commit acc010cba5
14 changed files with 509 additions and 45 deletions

View File

@@ -178,6 +178,11 @@ struct TypeStruct {
Scope * scope; \
i64 custom_align; \
}) \
TYPE_KIND(BitSet, struct { \
Type *base_type; \
i64 min; \
i64 max; \
}) \
@@ -376,6 +381,7 @@ gb_global Type *t_type_info_union = nullptr;
gb_global Type *t_type_info_enum = nullptr;
gb_global Type *t_type_info_map = nullptr;
gb_global Type *t_type_info_bit_field = nullptr;
gb_global Type *t_type_info_bit_set = nullptr;
gb_global Type *t_type_info_named_ptr = nullptr;
gb_global Type *t_type_info_integer_ptr = nullptr;
@@ -398,6 +404,7 @@ gb_global Type *t_type_info_union_ptr = nullptr;
gb_global Type *t_type_info_enum_ptr = nullptr;
gb_global Type *t_type_info_map_ptr = nullptr;
gb_global Type *t_type_info_bit_field_ptr = nullptr;
gb_global Type *t_type_info_bit_set_ptr = nullptr;
gb_global Type *t_allocator = nullptr;
gb_global Type *t_allocator_ptr = nullptr;
@@ -607,6 +614,10 @@ Type *alloc_type_bit_field() {
Type *t = alloc_type(Type_BitField);
return t;
}
Type *alloc_type_bit_set() {
Type *t = alloc_type(Type_BitSet);
return t;
}
@@ -903,6 +914,10 @@ bool is_type_bit_field_value(Type *t) {
t = base_type(t);
return (t->kind == Type_BitFieldValue);
}
bool is_type_bit_set(Type *t) {
t = base_type(t);
return (t->kind == Type_BitSet);
}
bool is_type_map(Type *t) {
t = base_type(t);
return t->kind == Type_Map;
@@ -963,6 +978,19 @@ bool is_type_valid_for_keys(Type *t) {
return false;
}
Type *bit_set_to_int(Type *t) {
GB_ASSERT(is_type_bit_set(t));
i64 sz = type_size_of(t);
switch (sz) {
case 1: return t_u8;
case 2: return t_u16;
case 4: return t_u32;
case 8: return t_u64;
}
GB_PANIC("Unknown bit_set size");
return nullptr;
}
bool is_type_indexable(Type *t) {
Type *bt = base_type(t);
@@ -1108,6 +1136,10 @@ bool type_has_nil(Type *t) {
}
return false;
} break;
case Type_Enum:
case Type_BitSet:
case Type_BitField:
return true;
case Type_Slice:
case Type_Proc:
case Type_Pointer:
@@ -1158,6 +1190,9 @@ bool is_type_comparable(Type *t) {
return is_type_comparable(t->Array.elem);
case Type_Proc:
return true;
case Type_BitSet:
return true;
}
return false;
}
@@ -1237,6 +1272,12 @@ bool are_types_identical(Type *x, Type *y) {
}
break;
case Type_BitSet:
if (y->kind == Type_BitSet) {
return are_types_identical(x->BitSet.base_type, y->BitSet.base_type);
}
break;
case Type_Enum:
return x == y; // NOTE(bill): All enums are unique
@@ -2023,6 +2064,16 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
}
return gb_clamp(next_pow2(align), 1, build_context.max_align);
} break;
case Type_BitSet: {
i64 bits = t->BitSet.max - t->BitSet.min + 1;
if (bits == 0) return 0;
if (bits <= 8) return 1;
if (bits <= 16) return 2;
if (bits <= 32) return 4;
if (bits <= 64) return 8;
GB_PANIC("unknown bit_set size");
}
}
// return gb_clamp(next_pow2(type_size_of(t)), 1, build_context.max_align);
@@ -2239,6 +2290,16 @@ i64 type_size_of_internal(Type *t, TypePath *path) {
GB_ASSERT((bits%8) == 0);
return bits/8;
} break;
case Type_BitSet: {
i64 bits = t->BitSet.max - t->BitSet.min + 1;
if (bits == 0) return 0;
if (bits <= 8) return 1;
if (bits <= 16) return 2;
if (bits <= 32) return 4;
if (bits <= 64) return 8;
GB_PANIC("unknown bit_set size");
}
}
// Catch all
@@ -2549,6 +2610,12 @@ gbString write_type_to_string(gbString str, Type *type) {
case Type_BitFieldValue:
str = gb_string_append_fmt(str, "(bit field value with %d bits)", cast(int)type->BitFieldValue.bits);
break;
case Type_BitSet:
str = gb_string_appendc(str, "bit_field[");
str = write_type_to_string(str, type->BitSet.base_type);
str = gb_string_appendc(str, "]");
break;
}
return str;