commit 2afdcd49101ac94d37c0ea9cf924a05610e54899
parent f45f75b96ab4fc6efc559440b16763eacd4ebca2
Author: Drew DeVault <sir@cmpwn.com>
Date: Tue, 12 Jan 2021 14:48:56 -0500
gen: implement globals
Diffstat:
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