harec

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

commit 2a741eda80208625e5b4bd3f348a107c8b2b7bf6
parent eb82b4658a1712fe5fb0eb7f4b677fc1667502bd
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Mon,  3 May 2021 12:04:46 -0400

check: fix multi-global declarations

Diffstat:
Msrc/check.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Mtests/11-globals.ha | 4++--
2 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -2654,18 +2654,18 @@ check_expression(struct context *ctx, static struct declaration * check_const(struct context *ctx, - const struct ast_decl *adecl) + const struct ast_global_decl *adecl) { const struct type *type = type_store_lookup_atype( - ctx->store, adecl->constant.type); + ctx->store, adecl->type); struct declaration *decl = xcalloc(1, sizeof(struct declaration)); const struct scope_object *obj = scope_lookup( - ctx->unit, &adecl->constant.ident); + ctx->unit, &adecl->ident); assert(obj && obj->otype == O_CONST); decl->type = DECL_CONST; decl->constant.type = type; decl->constant.value = obj->value; - mkident(ctx, &decl->ident, &adecl->constant.ident); + mkident(ctx, &decl->ident, &adecl->ident); return decl; } @@ -2757,25 +2757,24 @@ check_function(struct context *ctx, static struct declaration * check_global(struct context *ctx, - const struct ast_decl *adecl) + const struct ast_global_decl *adecl) { - const struct ast_global_decl *agdecl = &adecl->global; - if (!agdecl->init) { + if (!adecl->init) { return NULL; // Forward declaration } const struct type *type = type_store_lookup_atype( - ctx->store, agdecl->type); + ctx->store, adecl->type); // TODO: Free initialier struct expression *initializer = xcalloc(1, sizeof(struct expression)); - struct errors *errors = check_expression(ctx, agdecl->init, initializer, + struct errors *errors = check_expression(ctx, adecl->init, initializer, type, NULL); // TODO: Pass errors up and deal with them at the end of check handle_errors(errors); - expect(&agdecl->init->loc, + expect(&adecl->init->loc, type_is_assignable(type, initializer->result), "Constant type is not assignable from initializer type"); initializer = lower_implicit_cast(type, initializer); @@ -2783,7 +2782,7 @@ check_global(struct context *ctx, struct expression *value = xcalloc(1, sizeof(struct expression)); enum eval_result r = eval_expr(ctx, initializer, value); - expect(&agdecl->init->loc, r == EVAL_OK, + expect(&adecl->init->loc, r == EVAL_OK, "Unable to evaluate global initializer at compile time"); struct declaration *decl = xcalloc(1, sizeof(struct declaration)); @@ -2791,11 +2790,11 @@ check_global(struct context *ctx, decl->global.type = type; decl->global.value = value; - if (agdecl->symbol) { - decl->ident.name = strdup(agdecl->symbol); - decl->symbol = strdup(agdecl->symbol); + if (adecl->symbol) { + decl->ident.name = strdup(adecl->symbol); + decl->symbol = strdup(adecl->symbol); } else { - mkident(ctx, &decl->ident, &agdecl->ident); + mkident(ctx, &decl->ident, &adecl->ident); } return decl; @@ -2824,13 +2823,34 @@ check_declarations(struct context *ctx, const struct ast_decl *adecl = &adecls->decl; switch (adecl->decl_type) { case AST_DECL_CONST: - decl = check_const(ctx, adecl); + for (const struct ast_global_decl *c = &adecl->constant; + c; c = c->next) { + decl = check_const(ctx, c); + struct declarations *decls = *next = + xcalloc(1, sizeof(struct declarations)); + decl->exported = adecl->exported; + decls->decl = decl; + next = &decls->next; + } + decl = NULL; break; case AST_DECL_FUNC: decl = check_function(ctx, adecl); break; case AST_DECL_GLOBAL: - decl = check_global(ctx, adecl); + for (const struct ast_global_decl *g = &adecl->global; + g; g = g->next) { + decl = check_global(ctx, g); + if (decl == NULL) { + continue; + } + struct declarations *decls = *next = + xcalloc(1, sizeof(struct declarations)); + decl->exported = adecl->exported; + decls->decl = decl; + next = &decls->next; + } + decl = NULL; break; case AST_DECL_TYPE: decl = check_type(ctx, adecl); @@ -3231,11 +3251,9 @@ static bool scan_global(struct context *ctx, const struct ast_global_decl *decl) { // TODO: Get rid of this once the type store bubbles up errors - for (const struct ast_global_decl *d = decl; d; d = d->next) { - if (!type_is_specified(ctx, d->type) - || !expr_is_specified(ctx, d->init)) { - return false; - } + if (!type_is_specified(ctx, decl->type) + || !expr_is_specified(ctx, decl->init)) { + return false; } const struct type *type = type_store_lookup_atype( @@ -3334,11 +3352,23 @@ scan_declaration(struct context *ctx, const struct ast_decl *decl) { switch (decl->decl_type) { case AST_DECL_CONST: - return scan_const(ctx, &decl->constant); + for (const struct ast_global_decl *c = &decl->constant; c; + c = c->next) { + if (!scan_const(ctx, c)) { + return false; + } + } + return true; case AST_DECL_FUNC: return scan_function(ctx, &decl->function); case AST_DECL_GLOBAL: - return scan_global(ctx, &decl->global); + for (const struct ast_global_decl *g = &decl->global; g; + g = g->next) { + if (!scan_global(ctx, g)) { + return false; + } + } + return true; case AST_DECL_TYPE: return scan_type(ctx, &decl->type); } diff --git a/tests/11-globals.ha b/tests/11-globals.ha @@ -1,9 +1,9 @@ use rt; -let x: int = 42; +let x: int = 42, y: int = 69; fn write() void = { - assert(x == 42); + assert(x == 42 && y == 69); x = 1337; assert(x == 1337); };