commit 010ade7aa39f93cbc89fa4c08dbdc458e9f3ce55
parent 555bd4914dcf770a15733efdd20dd39149a8a89c
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 3 Sep 2021 11:00:48 +0200
check: check type expressions
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
3 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/include/type_store.h b/include/type_store.h
@@ -55,4 +55,7 @@ const struct type *type_store_tagged_to_union(
const struct type *type_store_lookup_tuple(struct type_store *store,
struct type_tuple *values);
+// Returns the 'type' type.
+const struct type *type_store_type(struct type_store *store);
+
#endif
diff --git a/src/check.c b/src/check.c
@@ -2623,6 +2623,18 @@ check_expr_tuple(struct context *ctx,
}
static void
+check_expr_type(struct context *ctx,
+ const struct ast_expression *aexpr,
+ struct expression *expr,
+ const struct type *hint)
+{
+ expr->type = EXPR_TYPE;
+ expr->_type.type = type_store_lookup_atype(
+ ctx->store, aexpr->_type.type);
+ expr->result = type_store_type(ctx->store);
+}
+
+static void
check_expr_unarithm(struct context *ctx,
const struct ast_expression *aexpr,
struct expression *expr,
@@ -2782,7 +2794,8 @@ check_expression(struct context *ctx,
check_expr_tuple(ctx, aexpr, expr, hint);
break;
case EXPR_TYPE:
- assert(0); // TODO
+ check_expr_type(ctx, aexpr, expr, hint);
+ break;
case EXPR_UNARITHM:
check_expr_unarithm(ctx, aexpr, expr, hint);
break;
diff --git a/src/type_store.c b/src/type_store.c
@@ -115,6 +115,7 @@ builtin_type_for_storage(enum type_storage storage, bool is_const)
return &builtin_type_null; // const null and null are the same type
case STORAGE_STRING:
return is_const ? &builtin_type_const_str : &builtin_type_str;
+ case STORAGE_TYPE:
case STORAGE_ALIAS:
case STORAGE_ARRAY:
case STORAGE_FUNCTION:
@@ -123,7 +124,6 @@ builtin_type_for_storage(enum type_storage storage, bool is_const)
case STORAGE_STRUCT:
case STORAGE_TAGGED:
case STORAGE_TUPLE:
- case STORAGE_TYPE:
case STORAGE_UNION:
case STORAGE_ENUM:
return NULL;
@@ -984,6 +984,24 @@ type_store_lookup_tuple(struct type_store *store, struct type_tuple *values)
}
const struct type *
+type_store_type(struct type_store *store)
+{
+ struct type type = {
+ .storage = STORAGE_TYPE,
+ };
+ return type_store_lookup_type(store, &type);
+}
+
+// Algorithm:
+// - Deduplicate and collect nested unions
+// - Merge *type with nullable *type
+// - If one of the types is null:
+// - If there's more than one pointer type, error out
+// - If there's one pointer type, make it nullable and drop the null
+// - If there are no pointer types, keep the null
+// - If the resulting union only has one type, return that type
+// - Otherwise, return a tagged union of all the selected types
+const struct type *
type_store_reduce_result(struct type_store *store, struct type_tagged_union *in)
{
if (!in) {