aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-10-20 01:06:58 +0100
committergingerBill <bill@gingerbill.org>2021-10-20 01:06:58 +0100
commit445696d660804650c7dbaf1fb3f344b59d93fdf4 (patch)
tree32e905be1281590f1b9f9e7ce3242d6ef240aa0d /src
parentf454ac3150905d640af396b7c7c7582fd2288482 (diff)
Support parapoly matrices
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index eb6040320..d98430aec 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1165,6 +1165,67 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source,
return key || value;
}
return false;
+
+ case Type_Matrix:
+ if (source->kind == Type_Matrix) {
+ if (poly->Matrix.generic_row_count != nullptr) {
+ Type *gt = poly->Matrix.generic_row_count;
+ GB_ASSERT(gt->kind == Type_Generic);
+ Entity *e = scope_lookup(gt->Generic.scope, gt->Generic.name);
+ GB_ASSERT(e != nullptr);
+ if (e->kind == Entity_TypeName) {
+ poly->Matrix.generic_row_count = nullptr;
+ poly->Matrix.row_count = source->Matrix.row_count;
+
+ e->kind = Entity_Constant;
+ e->Constant.value = exact_value_i64(source->Matrix.row_count);
+ e->type = t_untyped_integer;
+ } else if (e->kind == Entity_Constant) {
+ poly->Matrix.generic_row_count = nullptr;
+ if (e->Constant.value.kind != ExactValue_Integer) {
+ return false;
+ }
+ i64 count = big_int_to_i64(&e->Constant.value.value_integer);
+ if (count != source->Matrix.row_count) {
+ return false;
+ }
+ poly->Matrix.row_count = source->Matrix.row_count;
+ } else {
+ return false;
+ }
+ }
+ if (poly->Matrix.generic_column_count != nullptr) {
+ Type *gt = poly->Matrix.generic_column_count;
+ GB_ASSERT(gt->kind == Type_Generic);
+ Entity *e = scope_lookup(gt->Generic.scope, gt->Generic.name);
+ GB_ASSERT(e != nullptr);
+ if (e->kind == Entity_TypeName) {
+ poly->Matrix.generic_column_count = nullptr;
+ poly->Matrix.column_count = source->Matrix.column_count;
+
+ e->kind = Entity_Constant;
+ e->Constant.value = exact_value_i64(source->Matrix.column_count);
+ e->type = t_untyped_integer;
+ } else if (e->kind == Entity_Constant) {
+ poly->Matrix.generic_column_count = nullptr;
+ if (e->Constant.value.kind != ExactValue_Integer) {
+ return false;
+ }
+ i64 count = big_int_to_i64(&e->Constant.value.value_integer);
+ if (count != source->Matrix.column_count) {
+ return false;
+ }
+ poly->Matrix.column_count = source->Matrix.column_count;
+ } else {
+ return false;
+ }
+ }
+ if (poly->Matrix.row_count == source->Matrix.row_count &&
+ poly->Matrix.column_count == source->Matrix.column_count) {
+ return is_polymorphic_type_assignable(c, poly->Matrix.elem, source->Matrix.elem, true, modify_type);
+ }
+ }
+ return false;
}
return false;
}