harec

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

commit 2afdcd49101ac94d37c0ea9cf924a05610e54899
parent f45f75b96ab4fc6efc559440b16763eacd4ebca2
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 12 Jan 2021 14:48:56 -0500

gen: implement globals

Diffstat:
Msrc/emit.c | 18+++++++++---------
Msrc/gen.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Atests/11-globals.ha | 21+++++++++++++++++++++
Mtests/configure | 3++-
4 files changed, 99 insertions(+), 12 deletions(-)

diff --git a/src/emit.c b/src/emit.c @@ -213,9 +213,9 @@ emit_data_string(const char *str, size_t sz, FILE *out) } } if (q) { - fprintf(out, "\", b 0, "); + fprintf(out, "\", b 0"); } else { - fprintf(out, "b 0, "); + fprintf(out, "b 0"); } } @@ -223,7 +223,7 @@ static void emit_data(struct qbe_def *def, FILE *out) { assert(def->kind == Q_DATA); - fprintf(out, "%sdata $%s = {", + fprintf(out, "%sdata $%s = { ", def->exported ? "export " : "", def->name); @@ -231,7 +231,10 @@ emit_data(struct qbe_def *def, FILE *out) while (item) { switch (item->type) { case QD_VALUE: - assert(0); // TODO + emit_qtype(item->value.type, true, out); + fprintf(out, " "); + emit_value(&item->value, out); + break; case QD_ZEROED: assert(0); // TODO case QD_STRING: @@ -239,14 +242,11 @@ emit_data(struct qbe_def *def, FILE *out) break; } - if (item->next) { - fprintf(out, ","); - } - + fprintf(out, item->next ? ", " : " "); item = item->next; } - fprintf(out, " }\n\n"); + fprintf(out, "}\n\n"); } static void diff --git a/src/gen.c b/src/gen.c @@ -107,7 +107,7 @@ qval_for_object(struct gen_context *ctx, break; case O_DECL: val->kind = QV_GLOBAL; - val->indirect = false; + val->indirect = true; val->name = ident_to_sym(&obj->ident); break; case O_CONST: @@ -1289,7 +1289,72 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) static void gen_global_decl(struct gen_context *ctx, const struct declaration *decl) { - assert(0); // TODO + assert(decl->type == DECL_GLOBAL); + const struct global_decl *global = &decl->global; + + struct qbe_def *qdef = xcalloc(1, sizeof(struct qbe_def)); + qdef->kind = Q_DATA; + qdef->exported = decl->exported; + qdef->name = ident_to_sym(&decl->ident); + + const union expression_constant *constant = &global->value->constant; + struct qbe_data_item *item = &qdef->data.items; + + const struct type *type = type_dealias(global->type); + switch (type->storage) { + case TYPE_STORAGE_I8: + case TYPE_STORAGE_U8: + item->type = QD_VALUE; + constw(&item->value, (uint8_t)constant->uval); + item->value.type = &qbe_byte; + break; + case TYPE_STORAGE_I16: + case TYPE_STORAGE_U16: + item->type = QD_VALUE; + constw(&item->value, (uint16_t)constant->uval); + item->value.type = &qbe_half; + break; + case TYPE_STORAGE_BOOL: + item->type = QD_VALUE; + constw(&item->value, constant->bval ? 1 : 0); + break; + case TYPE_STORAGE_I32: + case TYPE_STORAGE_U32: + case TYPE_STORAGE_INT: + case TYPE_STORAGE_UINT: + case TYPE_STORAGE_RUNE: + item->type = QD_VALUE; + constw(&item->value, (uint32_t)constant->uval); + break; + case TYPE_STORAGE_U64: + case TYPE_STORAGE_I64: + case TYPE_STORAGE_SIZE: + item->type = QD_VALUE; + constw(&item->value, (uint32_t)constant->uval); + break; + case TYPE_STORAGE_F32: + case TYPE_STORAGE_F64: + assert(0); // TODO + case TYPE_STORAGE_UINTPTR: + assert(0); // TODO: What are the semantics for this? + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_ENUM: + case TYPE_STORAGE_POINTER: + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_TAGGED_UNION: + case TYPE_STORAGE_UNION: + assert(0); // TODO + case TYPE_STORAGE_ALIAS: + case TYPE_STORAGE_CHAR: + case TYPE_STORAGE_FUNCTION: + case TYPE_STORAGE_NULL: + case TYPE_STORAGE_VOID: + assert(0); // Invariant + } + + qbe_append_def(ctx->out, qdef); } static void diff --git a/tests/11-globals.ha b/tests/11-globals.ha @@ -0,0 +1,21 @@ +fn rt::compile(src: str) int; + +let x: int = 42; + +fn write() void = { + assert(x == 42); + x = 1337; + assert(x == 1337); +}; + +fn invariants() void = { + assert(rt::compile("fn test() int; let x: int = test();") != 0); +}; + +export fn main() void = { + // TODO: Expand this test: + // - Declare & validate globals of more types + // - Globals which are pointers to other globals + write(); + invariants(); +}; diff --git a/tests/configure b/tests/configure @@ -13,7 +13,8 @@ tests() { 07-aliases \ 08-slices \ 09-funcs \ - 10-binarithms + 10-binarithms \ + 11-globals do cat <<EOF tests/$t: libhart.a tests/$t.ha