harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Minclude/type_store.h | 3+++
Msrc/check.c | 15++++++++++++++-
Msrc/type_store.c | 20+++++++++++++++++++-
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) {