harec

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

commit 89f77d6f4fa5ad5af97ceee51491ae1448ae5e8c
parent f35adac4f375b7151ac10cf34f6dbaeacf12a958
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Wed,  3 Feb 2021 18:40:38 -0500

check: implement append

Diffstat:
Msrc/check.c | 41++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/check.c b/src/check.c @@ -200,7 +200,46 @@ check_expr_append(struct context *ctx, assert(aexpr->type == EXPR_APPEND); trace(TR_CHECK, "append"); expr->type = EXPR_APPEND; - assert(0); // TODO + expr->result = &builtin_type_void; + expr->append.expr = xcalloc(sizeof(struct expression), 1); + check_expression(ctx, aexpr->append.expr, expr->append.expr, NULL); + expect(&aexpr->append.expr->loc, + expr->append.expr->result->storage == TYPE_STORAGE_SLICE, + "append must operate on a slice"); + expect(&aexpr->append.expr->loc, + !(expr->append.expr->result->flags & TYPE_CONST), + "append must operate on a mutable slice"); + expect(&aexpr->append.expr->loc, + expr->append.expr->type == EXPR_ACCESS + || (expr->append.expr->type == EXPR_UNARITHM + && expr->append.expr->unarithm.op == UN_DEREF), + "append must operate on a slice object"); + const struct type *memb = expr->append.expr->result->array.members; + struct append_values **next = &expr->append.values; + for (struct ast_append_values *avalue = aexpr->append.values; avalue; + avalue = avalue->next) { + struct append_values *value = *next = + xcalloc(sizeof(struct append_values), 1); + value->expr = + xcalloc(sizeof(struct expression), 1); + check_expression(ctx, avalue->expr, value->expr, memb); + expect(&avalue->expr->loc, + type_is_assignable(memb, value->expr->result), + "appended value must be assignable to member type"); + value->expr = lower_implicit_cast(memb, value->expr); + next = &value->next; + } + if (aexpr->append.variadic != NULL) { + const struct type *type = expr->append.expr->result; + expr->append.variadic = xcalloc(sizeof(struct expression), 1); + check_expression(ctx, aexpr->append.variadic, + expr->append.variadic, type); + expect(&aexpr->append.variadic->loc, + type_is_assignable(type, expr->append.variadic->result), + "appended slice must be assignable to slice type"); + expr->append.variadic = + lower_implicit_cast(type, expr->append.variadic); + } } static void