Parametric polymorphic union type

This commit is contained in:
gingerBill
2018-09-08 12:02:25 +01:00
parent 26cfc0257d
commit 3cd6ae311d
9 changed files with 317 additions and 58 deletions

View File

@@ -99,6 +99,20 @@ struct TypeStruct {
Entity * names;
};
struct TypeUnion {
Array<Type *> variants;
Ast * node;
Scope * scope;
i64 variant_block_size;
i64 custom_align;
i64 tag_size;
bool is_polymorphic;
bool is_poly_specialized;
Type * polymorphic_params; // Type_Tuple
Type * polymorphic_parent;
};
#define TYPE_KINDS \
TYPE_KIND(Basic, BasicType) \
TYPE_KIND(Named, struct { \
@@ -129,6 +143,7 @@ struct TypeStruct {
Type *lookup_result_type; \
}) \
TYPE_KIND(Struct, TypeStruct) \
TYPE_KIND(Union, TypeUnion) \
TYPE_KIND(Enum, struct { \
Array<Entity *> fields; \
Ast *node; \
@@ -136,14 +151,6 @@ struct TypeStruct {
Entity * names; \
Type * base_type; \
}) \
TYPE_KIND(Union, struct { \
Array<Type *> variants; \
Ast *node; \
Scope * scope; \
i64 variant_block_size; \
i64 custom_align; \
i64 tag_size; \
}) \
TYPE_KIND(Tuple, struct { \
Array<Entity *> variables; /* Entity_Variable */ \
Array<i64> offsets; \
@@ -1026,30 +1033,53 @@ bool is_type_indexable(Type *t) {
return false;
}
bool is_type_polymorphic_struct(Type *t) {
bool is_type_polymorphic_record(Type *t) {
t = base_type(t);
if (t->kind == Type_Struct) {
return t->Struct.is_polymorphic;
} else if (t->kind == Type_Union) {
return t->Union.is_polymorphic;
}
return false;
}
bool is_type_polymorphic_struct_specialized(Type *t) {
bool is_type_polymorphic_record_specialized(Type *t) {
t = base_type(t);
if (t->kind == Type_Struct) {
return t->Struct.is_polymorphic && t->Struct.is_poly_specialized;
} else if (t->kind == Type_Union) {
return t->Union.is_polymorphic && t->Union.is_poly_specialized;
}
return false;
}
bool is_type_polymorphic_struct_unspecialized(Type *t) {
bool is_type_polymorphic_record_unspecialized(Type *t) {
t = base_type(t);
if (t->kind == Type_Struct) {
return t->Struct.is_polymorphic && !t->Struct.is_poly_specialized;
} else if (t->kind == Type_Struct) {
return t->Struct.is_polymorphic && !t->Struct.is_poly_specialized;
}
return false;
}
TypeTuple *get_record_polymorphic_params(Type *t) {
t = base_type(t);
switch (t->kind) {
case Type_Struct:
if (t->Struct.polymorphic_params) {
return &t->Struct.polymorphic_params->Tuple;
}
break;
case Type_Union:
if (t->Union.polymorphic_params) {
return &t->Union.polymorphic_params->Tuple;
}
break;
}
return nullptr;
}
bool is_type_polymorphic(Type *t) {
switch (t->kind) {
@@ -1057,7 +1087,7 @@ bool is_type_polymorphic(Type *t) {
return true;
case Type_Named:
return is_type_polymorphic_struct(t->Named.base);
return is_type_polymorphic_record(t->Named.base);
case Type_Pointer:
return is_type_polymorphic(t->Pointer.elem);