aboutsummaryrefslogtreecommitdiff
path: root/src/types.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-01-29 20:15:16 +0000
committerGinger Bill <bill@gingerbill.org>2017-01-29 20:15:16 +0000
commit984e36a15147cb4ed681174fb1f97f4e1735411d (patch)
tree042890f3eb8a56add6091646279a599204635d18 /src/types.c
parentec9c8fb8a49cb6f9fe8f6df806dfb5a6fcb2e148 (diff)
Dynamic arrays
Diffstat (limited to 'src/types.c')
-rw-r--r--src/types.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/src/types.c b/src/types.c
index 7bb849fff..2612ee72c 100644
--- a/src/types.c
+++ b/src/types.c
@@ -97,6 +97,7 @@ typedef struct TypeRecord {
TYPE_KIND(Basic, BasicType) \
TYPE_KIND(Pointer, struct { Type *elem; }) \
TYPE_KIND(Array, struct { Type *elem; i64 count; }) \
+ TYPE_KIND(DynamicArray, struct { Type *elem; }) \
TYPE_KIND(Vector, struct { Type *elem; i64 count; }) \
TYPE_KIND(Slice, struct { Type *elem; }) \
TYPE_KIND(Maybe, struct { Type *elem; }) \
@@ -385,6 +386,12 @@ Type *make_type_array(gbAllocator a, Type *elem, i64 count) {
return t;
}
+Type *make_type_dynamic_array(gbAllocator a, Type *elem) {
+ Type *t = alloc_type(a, Type_DynamicArray);
+ t->DynamicArray.elem = elem;
+ return t;
+}
+
Type *make_type_vector(gbAllocator a, Type *elem, i64 count) {
Type *t = alloc_type(a, Type_Vector);
t->Vector.elem = elem;
@@ -616,6 +623,10 @@ bool is_type_array(Type *t) {
t = base_type(t);
return t->kind == Type_Array;
}
+bool is_type_dynamic_array(Type *t) {
+ t = base_type(t);
+ return t->kind == Type_DynamicArray;
+}
bool is_type_slice(Type *t) {
t = base_type(t);
return t->kind == Type_Slice;
@@ -690,6 +701,7 @@ bool type_has_nil(Type *t) {
return false;
} break;
case Type_Slice:
+ case Type_DynamicArray:
case Type_Proc:
case Type_Pointer:
case Type_Maybe:
@@ -750,6 +762,12 @@ bool are_types_identical(Type *x, Type *y) {
}
break;
+ case Type_DynamicArray:
+ if (y->kind == Type_DynamicArray) {
+ return are_types_identical(x->DynamicArray.elem, y->DynamicArray.elem);
+ }
+ break;
+
case Type_Vector:
if (y->kind == Type_Vector) {
return (x->Vector.count == y->Vector.count) && are_types_identical(x->Vector.elem, y->Vector.elem);
@@ -973,7 +991,10 @@ gb_global Entity *entity__any_data = NULL;
gb_global Entity *entity__string_data = NULL;
gb_global Entity *entity__string_count = NULL;
gb_global Entity *entity__slice_count = NULL;
-gb_global Entity *entity__slice_capacity = NULL;
+
+gb_global Entity *entity__dynamic_array_count = NULL;
+gb_global Entity *entity__dynamic_array_capacity = NULL;
+gb_global Entity *entity__dynamic_array_allocator = NULL;
Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel);
@@ -1142,6 +1163,39 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__slice_count;
return sel;
}
+ } else if (type->kind == Type_DynamicArray) {
+ String data_str = str_lit("data");
+ String count_str = str_lit("count");
+ String capacity_str = str_lit("capacity");
+ String allocator_str = str_lit("allocator");
+
+ if (str_eq(field_name, data_str)) {
+ selection_add_index(&sel, 0);
+ // HACK(bill): Memory leak
+ sel.entity = make_entity_field(a, NULL, make_token_ident(data_str), make_type_pointer(a, type->DynamicArray.elem), false, 0);
+ return sel;
+ } else if (str_eq(field_name, count_str)) {
+ selection_add_index(&sel, 1);
+ if (entity__dynamic_array_count == NULL) {
+ entity__dynamic_array_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 1);
+ }
+ sel.entity = entity__dynamic_array_count;
+ return sel;
+ } else if (str_eq(field_name, capacity_str)) {
+ selection_add_index(&sel, 2);
+ if (entity__dynamic_array_capacity == NULL) {
+ entity__dynamic_array_capacity = make_entity_field(a, NULL, make_token_ident(capacity_str), t_int, false, 2);
+ }
+ sel.entity = entity__dynamic_array_capacity;
+ return sel;
+ } else if (str_eq(field_name, allocator_str)) {
+ selection_add_index(&sel, 3);
+ if (entity__dynamic_array_allocator == NULL) {
+ entity__dynamic_array_allocator = make_entity_field(a, NULL, make_token_ident(allocator_str), t_allocator, false, 3);
+ }
+ sel.entity = entity__dynamic_array_allocator;
+ return sel;
+ }
}
if (type->kind != Type_Record) {
@@ -1351,6 +1405,14 @@ i64 type_align_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, Type
type_path_pop(path);
return align;
}
+
+ case Type_DynamicArray:
+ // data, count, capacity, allocator
+ return s.word_size;
+
+ case Type_Slice:
+ return s.word_size;
+
case Type_Vector: {
Type *elem = t->Vector.elem;
type_path_push(path, elem);
@@ -1537,6 +1599,9 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP
return alignment*(count-1) + size;
} break;
+ case Type_DynamicArray:
+ return 3*s.word_size + type_size_of(s, allocator, t_allocator);
+
case Type_Vector: {
i64 count, bit_size, total_size_in_bits, total_size;
count = t->Vector.count;
@@ -1736,6 +1801,11 @@ gbString write_type_to_string(gbString str, Type *type) {
str = write_type_to_string(str, type->Array.elem);
break;
+ case Type_DynamicArray:
+ str = gb_string_appendc(str, "[dynamic]");
+ str = write_type_to_string(str, type->DynamicArray.elem);
+ break;
+
case Type_Record: {
switch (type->Record.kind) {
case TypeRecord_Struct: