commit b8ebf6258e998d777f5cd7c72f278786fd6ff420
parent c266689e39f0989b7f7c5f2d969d4ac9f7989490
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 21 Dec 2020 11:16:03 -0500
gen: initial parameter implementation
Diffstat:
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 = ¶m->next;
+ }
+
struct qbe_statement end_label = {0};
struct qbe_value end_label_v = {
.kind = QV_LABEL,