aboutsummaryrefslogtreecommitdiff
path: root/src/types.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-06-03 22:27:23 +0100
committerGinger Bill <bill@gingerbill.org>2017-06-03 22:27:23 +0100
commit2c0e59ae064b273899a56cb8d3c53b6967466fa2 (patch)
tree0e1a9dc2ac94b7dfc408166f1cc1e0b921a5aba3 /src/types.c
parent9d1a4c304a27c0b762809bc3c1d6c70fdb5137be (diff)
`bit_field`; Lexical sugar operators ≠ ≤ ≥
Example below: // See: https://en.wikipedia.org/wiki/Bit_field BoxProps :: bit_field { opaque : 1, fill_colour : 3, _ : 4, show_border : 1, border_colour : 3, border_style : 2, _ : 2, width : 4, height : 4, _ : 8, }
Diffstat (limited to 'src/types.c')
-rw-r--r--src/types.c141
1 files changed, 134 insertions, 7 deletions
diff --git a/src/types.c b/src/types.c
index cbb0bd0d9..91d8dc4eb 100644
--- a/src/types.c
+++ b/src/types.c
@@ -14,9 +14,11 @@ typedef enum BasicKind {
Basic_i128,
Basic_u128,
+ // Basic_f16,
Basic_f32,
Basic_f64,
+ // Basic_complex32,
Basic_complex64,
Basic_complex128,
@@ -149,6 +151,15 @@ typedef struct TypeRecord {
Type *generated_struct_type; \
Type *lookup_result_type; \
}) \
+ TYPE_KIND(BitFieldValue, struct { u32 bits; }) \
+ TYPE_KIND(BitField, struct { \
+ Scope * scope; \
+ Entity **fields; \
+ i32 field_count; \
+ u32 * offsets; \
+ u32 * sizes; \
+ i64 custom_align; \
+ }) \
@@ -225,9 +236,11 @@ gb_global Type basic_types[] = {
{Type_Basic, {Basic_u128, BasicFlag_Integer | BasicFlag_Unsigned, 16, STR_LIT("u128")}},
+ // {Type_Basic, {Basic_f16, BasicFlag_Float, 2, STR_LIT("f16")}},
{Type_Basic, {Basic_f32, BasicFlag_Float, 4, STR_LIT("f32")}},
{Type_Basic, {Basic_f64, BasicFlag_Float, 8, STR_LIT("f64")}},
+ // {Type_Basic, {Basic_complex32, BasicFlag_Complex, 4, STR_LIT("complex32")}},
{Type_Basic, {Basic_complex64, BasicFlag_Complex, 8, STR_LIT("complex64")}},
{Type_Basic, {Basic_complex128, BasicFlag_Complex, 16, STR_LIT("complex128")}},
@@ -265,9 +278,11 @@ gb_global Type *t_u64 = &basic_types[Basic_u64];
gb_global Type *t_i128 = &basic_types[Basic_i128];
gb_global Type *t_u128 = &basic_types[Basic_u128];
+// gb_global Type *t_f16 = &basic_types[Basic_f16];
gb_global Type *t_f32 = &basic_types[Basic_f32];
gb_global Type *t_f64 = &basic_types[Basic_f64];
+// gb_global Type *t_complex32 = &basic_types[Basic_complex32];
gb_global Type *t_complex64 = &basic_types[Basic_complex64];
gb_global Type *t_complex128 = &basic_types[Basic_complex128];
@@ -325,6 +340,7 @@ gb_global Type *t_type_info_raw_union = NULL;
gb_global Type *t_type_info_union = NULL;
gb_global Type *t_type_info_enum = NULL;
gb_global Type *t_type_info_map = NULL;
+gb_global Type *t_type_info_bit_field = NULL;
gb_global Type *t_type_info_named_ptr = NULL;
gb_global Type *t_type_info_integer_ptr = NULL;
@@ -347,6 +363,7 @@ gb_global Type *t_type_info_raw_union_ptr = NULL;
gb_global Type *t_type_info_union_ptr = NULL;
gb_global Type *t_type_info_enum_ptr = NULL;
gb_global Type *t_type_info_map_ptr = NULL;
+gb_global Type *t_type_info_bit_field_ptr = NULL;
gb_global Type *t_allocator = NULL;
gb_global Type *t_allocator_ptr = NULL;
@@ -560,8 +577,21 @@ Type *make_type_map(gbAllocator a, i64 count, Type *key, Type *value) {
return t;
}
+Type *make_type_bit_field_value(gbAllocator a, u32 bits) {
+ Type *t = alloc_type(a, Type_BitFieldValue);
+ t->BitFieldValue.bits = bits;
+ return t;
+}
+
+Type *make_type_bit_field(gbAllocator a) {
+ Type *t = alloc_type(a, Type_BitField);
+ return t;
+}
+
+////////////////////////////////////////////////////////////////
+
Type *type_deref(Type *t) {
if (t != NULL) {
@@ -777,6 +807,7 @@ Type *base_complex_elem_type(Type *t) {
t = core_type(t);
if (is_type_complex(t)) {
switch (t->Basic.kind) {
+ // case Basic_complex32: return t_f16;
case Basic_complex64: return t_f32;
case Basic_complex128: return t_f64;
case Basic_UntypedComplex: return t_untyped_float;
@@ -802,7 +833,14 @@ bool is_type_enum(Type *t) {
t = base_type(t);
return (t->kind == Type_Record && t->Record.kind == TypeRecord_Enum);
}
-
+bool is_type_bit_field(Type *t) {
+ t = base_type(t);
+ return (t->kind == Type_BitField);
+}
+bool is_type_bit_field_value(Type *t) {
+ t = base_type(t);
+ return (t->kind == Type_BitFieldValue);
+}
bool is_type_map(Type *t) {
t = base_type(t);
return t->kind == Type_Map;
@@ -1067,6 +1105,26 @@ Type *default_type(Type *type) {
return type;
}
+Type *default_bit_field_value_type(Type *type) {
+ if (type == NULL) {
+ return t_invalid;
+ }
+ Type *t = base_type(type);
+ if (t->kind == Type_BitFieldValue) {
+ i32 bits = t->BitFieldValue.bits;
+ i32 size = 8*next_pow2((bits+7)/8);
+ switch (size) {
+ case 8: return t_u8;
+ case 16: return t_u16;
+ case 32: return t_u32;
+ case 64: return t_u64;
+ case 128: return t_u128;
+ default: GB_PANIC("Too big of a bit size!"); break;
+ }
+ }
+ return type;
+}
+
// NOTE(bill): Valid Compile time execution #run type
bool is_type_cte_safe(Type *type) {
type = default_type(base_type(type));
@@ -1211,8 +1269,9 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
i64 max_count = 0;
switch (type->kind) {
- case Type_Record: max_count = type->Record.field_count; break;
- case Type_Tuple: max_count = type->Tuple.variable_count; break;
+ case Type_Record: max_count = type->Record.field_count; break;
+ case Type_Tuple: max_count = type->Tuple.variable_count; break;
+ case Type_BitField: max_count = type->BitField.field_count; break;
}
if (index >= max_count) {
@@ -1244,6 +1303,14 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
}
}
break;
+
+ case Type_BitField: {
+ Array_i32 sel_array = {0};
+ array_init_count(&sel_array, a, 1);
+ sel_array.e[0] = cast(i32)index;
+ return make_selection(type->BitField.fields[index], sel_array, false);
+ } break;
+
}
GB_PANIC("Illegal index");
@@ -1407,6 +1474,21 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
return sel;
}
}
+ } else if (type->kind == Type_BitField) {
+ for (isize i = 0; i < type->BitField.field_count; i++) {
+ Entity *f = type->BitField.fields[i];
+ if (f->kind != Entity_Variable ||
+ (f->flags & EntityFlag_BitFieldValue) == 0) {
+ continue;
+ }
+
+ String str = f->token.string;
+ if (str_eq(field_name, str)) {
+ selection_add_index(&sel, i); // HACK(bill): Leaky memory
+ sel.entity = f;
+ return sel;
+ }
+ }
}
return sel;
@@ -1641,7 +1723,7 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
return max;
} break;
case TypeRecord_RawUnion: {
- i64 max = build_context.word_size;
+ i64 max = 1;
for (isize i = 0; i < t->Record.field_count; i++) {
Type *field_type = t->Record.fields[i]->type;
type_path_push(path, field_type);
@@ -1658,6 +1740,14 @@ i64 type_align_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
} break;
}
} break;
+
+ case Type_BitField: {
+ i64 align = 1;
+ if (t->BitField.custom_align > 0) {
+ align = t->BitField.custom_align;
+ }
+ return gb_clamp(next_pow2(align), 1, build_context.max_align);
+ } break;
}
// return gb_clamp(next_pow2(type_size_of(allocator, t)), 1, build_context.max_align);
@@ -1913,6 +2003,18 @@ i64 type_size_of_internal(gbAllocator allocator, Type *t, TypePath *path) {
} break;
}
} break;
+
+ case Type_BitField: {
+ i64 align = 8*type_align_of_internal(allocator, t, path);
+ i64 end = 0;
+ if (t->BitField.field_count > 0) {
+ i64 last = t->BitField.field_count-1;
+ end = t->BitField.offsets[last] + t->BitField.sizes[last];
+ }
+ i64 bits = align_formula(end, align);
+ GB_ASSERT((bits%8) == 0);
+ return bits/8;
+ } break;
}
// Catch all
@@ -2009,8 +2111,6 @@ i64 type_offset_of_from_selection(gbAllocator allocator, Type *type, Selection s
return offset;
}
-
-
gbString write_type_to_string(gbString str, Type *type) {
if (type == NULL) {
return gb_string_appendc(str, "<no type>");
@@ -2191,8 +2291,9 @@ gbString write_type_to_string(gbString str, Type *type) {
case Type_Proc:
str = gb_string_appendc(str, "proc(");
- if (type->Proc.params)
+ if (type->Proc.params) {
str = write_type_to_string(str, type->Proc.params);
+ }
str = gb_string_appendc(str, ")");
if (type->Proc.results) {
str = gb_string_appendc(str, " -> ");
@@ -2213,6 +2314,32 @@ gbString write_type_to_string(gbString str, Type *type) {
break;
}
break;
+
+ case Type_BitField:
+ str = gb_string_appendc(str, "bit_field ");
+ if (type->BitField.custom_align != 0) {
+ str = gb_string_appendc(str, gb_bprintf("#align %d ", cast(int)type->BitField.custom_align));
+ }
+ str = gb_string_appendc(str, "{");
+
+ for (isize i = 0; i < type->BitField.field_count; i++) {
+ Entity *f = type->BitField.fields[i];
+ GB_ASSERT(f->kind == Entity_Variable);
+ GB_ASSERT(f->type != NULL && f->type->kind == Type_BitFieldValue);
+ str = gb_string_appendc(str, "{");
+ if (i > 0) {
+ str = gb_string_appendc(str, ", ");
+ }
+ str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
+ str = gb_string_appendc(str, " : ");
+ str = gb_string_appendc(str, gb_bprintf("%lld", cast(long long)f->type->BitFieldValue.bits));
+ }
+ str = gb_string_appendc(str, "}");
+ break;
+
+ case Type_BitFieldValue:
+ str = gb_string_appendc(str, gb_bprintf("(bit field value with %lld bits)", cast(int)type->BitFieldValue.bits));
+ break;
}
return str;