harec

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

commit d85361a88b8ab4ae745bfa49feef1da8220bc3bd
parent 2086dbb6ec0ecf0727d928c28ec383661435f7f7
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri,  2 Jul 2021 11:35:38 -0400

gen: implement bindings

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Minclude/gen.h | 13+++++++++++--
Msrc/gen.c | 33++++++++++++++++++++++++++++-----
2 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/include/gen.h b/include/gen.h @@ -18,6 +18,12 @@ struct gen_temp { const struct type *type; }; +struct gen_binding { + const struct scope_object *object; + struct gen_temp temp; + struct gen_binding *next; +}; + struct gen_arch { const struct qbe_type *ptr; const struct qbe_type *sz; @@ -25,14 +31,17 @@ struct gen_arch { struct gen_context { struct qbe_program *out; + struct gen_arch arch; struct type_store *store; struct identifier *ns; + + uint64_t id; + struct gen_binding *bindings; + struct qbe_func *current; const struct type *functype; const char *end; struct gen_temp *rval; - struct gen_arch arch; - uint64_t id; }; struct unit; diff --git a/src/gen.c b/src/gen.c @@ -41,11 +41,11 @@ gen_qtemp(struct gen_context *ctx, struct qbe_value *out, // Allocates a temporary of the given type on the stack in the current // function's preamble. -static struct gen_temp * -alloc_temp(struct gen_context *ctx, const struct type *type, const char *fmt) +static void +alloc_temp(struct gen_context *ctx, struct gen_temp *temp, + const struct type *type, const char *fmt) { assert(type->size != 0 && type->size != SIZE_UNDEFINED); - struct gen_temp *temp = xcalloc(1, sizeof(struct gen_temp)); temp->type = type; temp->name = gen_name(ctx, fmt); @@ -57,7 +57,6 @@ alloc_temp(struct gen_context *ctx, const struct type *type, const char *fmt) struct qbe_value size; constl(&size, type->size); pushprei(ctx->current, &out, alloc_for_align(type->align), &size, NULL); - return temp; } // Loads a gen temporary into a qbe temporary. For types representable in qbe's @@ -91,6 +90,26 @@ static void gen_expr(struct gen_context *ctx, const struct expression *expr, struct gen_temp *out); static void +gen_expr_binding(struct gen_context *ctx, + const struct expression *expr, + struct gen_temp *out) +{ + for (const struct expression_binding *binding = &expr->binding; + binding; binding = binding->next) { + struct gen_binding *gb = xcalloc(1, sizeof(struct gen_binding)); + alloc_temp(ctx, &gb->temp, binding->object->type, "binding.%d"); + gb->object = binding->object; + pushc(ctx->current, "binding %s => %s", + binding->object->ident.name, + gb->temp.name); + + gen_expr(ctx, binding->initializer, &gb->temp); + gb->next = ctx->bindings; + ctx->bindings = gb; + } +} + +static void gen_expr_constant(struct gen_context *ctx, const struct expression *expr, struct gen_temp *out) @@ -253,7 +272,10 @@ gen_expr(struct gen_context *ctx, case EXPR_ASSERT: case EXPR_ASSIGN: case EXPR_BINARITHM: + assert(0); // TODO case EXPR_BINDING: + gen_expr_binding(ctx, expr, out); + break; case EXPR_BREAK: case EXPR_CONTINUE: case EXPR_CALL: @@ -317,7 +339,8 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) push(&qdef->func.prelude, &start_label); if (type_dealias(fntype->func.result)->storage != STORAGE_VOID) { - ctx->rval = alloc_temp(ctx, fntype->func.result, "rval.%d"); + ctx->rval = xcalloc(1, sizeof(struct gen_temp)); + alloc_temp(ctx, ctx->rval, fntype->func.result, "rval.%d"); qdef->func.returns = qtype_lookup(ctx, fntype->func.result, true); } else { qdef->func.returns = &qbe_void;