harec

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

commit b8ebf6258e998d777f5cd7c72f278786fd6ff420
parent c266689e39f0989b7f7c5f2d969d4ac9f7989490
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 21 Dec 2020 11:16:03 -0500

gen: initial parameter implementation

Diffstat:
Minclude/check.h | 2++
Minclude/qbe.h | 8+++++++-
Msrc/check.c | 4++--
Msrc/emit.c | 16+++++++++++++---
Msrc/gen.c | 15+++++++++++++--
5 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/include/check.h b/include/check.h @@ -5,6 +5,7 @@ #include "types.h" struct expression; +struct scope; enum func_decl_flags { FN_FINI = 1 << 0, @@ -15,6 +16,7 @@ enum func_decl_flags { struct function_decl { const struct type *type; struct expression *body; + struct scope *scope; char *symbol; unsigned int flags; // enum function_flags }; diff --git a/include/qbe.h b/include/qbe.h @@ -164,9 +164,15 @@ struct qbe_statement { }; }; +struct qbe_func_param { + char *name; + const struct qbe_type *type; + struct qbe_func_param *next; +}; + struct qbe_func { const struct qbe_type *returns; - // TODO: Parameters + struct qbe_func_param *params; size_t blen, bsiz; struct qbe_statement *body; }; diff --git a/src/check.c b/src/check.c @@ -199,7 +199,7 @@ check_function(struct context *ctx, identifier_dup(&decl->ident, &afndecl->ident); decl->func.flags = afndecl->flags; - struct scope *scope = scope_push(&ctx->scope, TR_CHECK); + decl->func.scope = scope_push(&ctx->scope, TR_CHECK); struct ast_function_parameters *params = afndecl->prototype.params; while (params) { struct identifier ident = { @@ -207,7 +207,7 @@ check_function(struct context *ctx, }; const struct type *type = type_store_lookup_atype( &ctx->store, params->type); - scope_insert(scope, &ident, type); + scope_insert(decl->func.scope, &ident, type); params = params->next; } diff --git a/src/emit.c b/src/emit.c @@ -13,7 +13,7 @@ emit_qtype(const struct qbe_type *type, FILE *out) case Q_LONG: case Q_SINGLE: case Q_DOUBLE: - fprintf(out, "%c ", (char)type->stype); + fprintf(out, "%c", (char)type->stype); break; case Q__VOID: break; // no-op @@ -78,6 +78,7 @@ emit_stmt(struct qbe_statement *stmt, FILE *out) fprintf(out, " ="); assert(stmt->out->type->stype != Q__AGGREGATE); // TODO emit_qtype(stmt->out->type, out); + fprintf(out, " "); } fprintf(out, "%s%s", qbe_instr[stmt->instr], stmt->args ? " " : ""); @@ -99,10 +100,19 @@ static void emit_func(struct qbe_def *def, FILE *out) { assert(def->type == Q_FUNC); - // TODO: Parameters fprintf(out, "%sfunction ", def->exported ? "export " : ""); emit_qtype(def->func.returns, out); - fprintf(out, "$%s() {\n", def->name); // TODO: Parameters + fprintf(out, " $%s(", def->name); + struct qbe_func_param *param = def->func.params; + while (param) { + emit_qtype(param->type, out); + fprintf(out, " %%%s", param->name); + if (param->next) { + fprintf(out, ", "); + } + param = param->next; + } + fprintf(out, ") {\n"); for (size_t i = 0; i < def->func.blen; ++i) { struct qbe_statement *stmt = &def->func.body[i]; diff --git a/src/gen.c b/src/gen.c @@ -9,6 +9,7 @@ #include "gen.h" #include "identifier.h" #include "qbe.h" +#include "scope.h" #include "trace.h" #include "types.h" @@ -218,10 +219,20 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) qdef->func.returns = qtype_for_type(ctx, fntype->func.result, true); ctx->current = &qdef->func; - assert(fntype->func.params == NULL); // TODO - pushl(&qdef->func, &ctx->id, "start.%d"); + struct qbe_func_param *param, **next = &qdef->func.params; + struct scope_object *obj = decl->func.scope->objects; + while (obj) { + // TODO: Copy params to the stack (for non-aggregate types) + param = *next = calloc(1, sizeof(struct qbe_func_param)); + assert(!obj->ident.ns); // Invariant + param->name = strdup(obj->ident.name); + param->type = qtype_for_type(ctx, obj->type, true); + obj = obj->next; + next = &param->next; + } + struct qbe_statement end_label = {0}; struct qbe_value end_label_v = { .kind = QV_LABEL,