aboutsummaryrefslogtreecommitdiff
path: root/src/check_type.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-10-18 16:52:19 +0100
committergingerBill <bill@gingerbill.org>2021-10-18 16:52:19 +0100
commit4c655865e5d9af83a98c137609b01972f4e51beb (patch)
tree2963a8f22c8e2a54dc7f081834b72a6081568842 /src/check_type.cpp
parent7aac8df2f2ddb89ffa8b1d096f41d89e689a2293 (diff)
Begin work on matrix type
Diffstat (limited to 'src/check_type.cpp')
-rw-r--r--src/check_type.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index 0d5c0f977..e752f192d 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2200,6 +2200,63 @@ void check_map_type(CheckerContext *ctx, Type *type, Ast *node) {
// error(node, "'map' types are not yet implemented");
}
+void check_matrix_type(CheckerContext *ctx, Type **type, Ast *node) {
+ ast_node(mt, MatrixType, node);
+
+ Operand row = {};
+ Operand column = {};
+
+ i64 row_count = check_array_count(ctx, &row, mt->row_count);
+ i64 column_count = check_array_count(ctx, &column, mt->column_count);
+
+ Type *elem = check_type_expr(ctx, mt->elem, nullptr);
+
+ Type *generic_row = nullptr;
+ Type *generic_column = nullptr;
+
+ if (row.mode == Addressing_Type && row.type->kind == Type_Generic) {
+ generic_row = row.type;
+ }
+
+ if (column.mode == Addressing_Type && column.type->kind == Type_Generic) {
+ generic_column = column.type;
+ }
+
+ if (row_count < MIN_MATRIX_ELEMENT_COUNT && generic_row == nullptr) {
+ gbString s = expr_to_string(row.expr);
+ error(row.expr, "Invalid matrix row count, expected %d+ rows, got %s", MIN_MATRIX_ELEMENT_COUNT, s);
+ gb_string_free(s);
+ }
+
+ if (column_count < MIN_MATRIX_ELEMENT_COUNT && generic_column == nullptr) {
+ gbString s = expr_to_string(column.expr);
+ error(column.expr, "Invalid matrix column count, expected %d+ rows, got %s", MIN_MATRIX_ELEMENT_COUNT, s);
+ gb_string_free(s);
+ }
+
+ if (row_count*column_count > MAX_MATRIX_ELEMENT_COUNT) {
+ i64 element_count = row_count*column_count;
+ error(column.expr, "Matrix types are limited to a maximum of %d elements, got %lld", MAX_MATRIX_ELEMENT_COUNT, cast(long long)element_count);
+ }
+
+ if (is_type_integer(elem)) {
+ // okay
+ } else if (is_type_float(elem)) {
+ // okay
+ } else if (is_type_complex(elem)) {
+ // okay
+ } else {
+ gbString s = type_to_string(elem);
+ error(column.expr, "Matrix elements types are limited to integers, floats, and complex, got %s", s);
+ gb_string_free(s);
+ }
+
+ *type = alloc_type_matrix(elem, row_count, column_count, generic_row, generic_column);
+
+ return;
+}
+
+
Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *elem_expr, Type *elem, i64 count, Type *generic_type, StructSoaKind soa_kind) {
Type *bt_elem = base_type(elem);
@@ -2785,6 +2842,17 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
return true;
}
case_end;
+
+
+ case_ast_node(mt, MatrixType, e);
+ bool ips = ctx->in_polymorphic_specialization;
+ defer (ctx->in_polymorphic_specialization = ips);
+ ctx->in_polymorphic_specialization = false;
+
+ check_matrix_type(ctx, type, e);
+ set_base_type(named_type, *type);
+ return true;
+ case_end;
}
*type = t_invalid;