harec

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

commit 4d40b91c5b4fee2b07fe95b666392f3d03667011
parent 3ded0a2d4dee1d9715a4a85a6836be71b3bdb04e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sun, 26 Sep 2021 09:46:23 +0200

gen: rig up more typeinfo structures

Diffstat:
Mrt/Makefile | 2+-
Msrc/gen.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mtests/34-reflect.ha | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtypes/reflect.ha | 4++--
4 files changed, 191 insertions(+), 10 deletions(-)

diff --git a/rt/Makefile b/rt/Makefile @@ -18,7 +18,7 @@ libhart.a: harec $(libhart_srcs) $(libhart_objs) $(rtstart) types/types.o @$(QBE) -o $@.s $@.ssa @$(AS) -g -o $@.o $@.s @$(AR) -csr $@ $@.o $(libhart_objs) types/types.o - #@rm $@.o $@.s $@.ssa + @rm $@.o $@.s $@.ssa clean-rt: @rm -f libhart.a $(libhart_objs) $(rtstart) diff --git a/src/gen.c b/src/gen.c @@ -2503,7 +2503,7 @@ gen_expr_tuple_at(struct gen_context *ctx, } } -static void gen_type_info(struct gen_context *ctx, +static struct qbe_data_item *gen_type_info(struct gen_context *ctx, const struct type *type, struct qbe_data_item *item); static struct gen_value @@ -3281,7 +3281,7 @@ gen_ident_data(struct gen_context *ctx, return item; } -static void +static struct qbe_data_item * gen_type_info(struct gen_context *ctx, const struct type *type, struct qbe_data_item *item) @@ -3333,6 +3333,7 @@ gen_type_info(struct gen_context *ctx, size_t len = 0; struct qbe_def *def; struct qbe_data_item *subitem; + struct gen_value ref; switch (type->storage) { case STORAGE_FCONST: case STORAGE_ICONST: @@ -3348,6 +3349,8 @@ gen_type_info(struct gen_context *ctx, case STORAGE_NULL: case STORAGE_RUNE: case STORAGE_SIZE: + case STORAGE_STRING: + case STORAGE_TYPE: case STORAGE_U16: case STORAGE_U32: case STORAGE_U64: @@ -3391,7 +3394,7 @@ gen_type_info(struct gen_context *ctx, item->next = xcalloc(1, sizeof(struct qbe_data_item)); item = item->next; - struct gen_value ref = mktyperef(ctx, type->alias.type); + ref = mktyperef(ctx, type->alias.type); item->type = QD_VALUE; item->value.kind = QV_GLOBAL; item->value.type = &qbe_long; @@ -3474,20 +3477,143 @@ gen_type_info(struct gen_context *ctx, item->value = constl(len); break; case STORAGE_ARRAY: - case STORAGE_FUNCTION: - case STORAGE_POINTER: + *repr_name = "array"; + item->value = constw(type_hash(&repr)); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_ZEROED; + item->zeroed = 4; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_VALUE; + item->value = constl(type->array.length); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + ref = mktyperef(ctx, type->array.members); + item->type = QD_VALUE; + item->value.kind = QV_GLOBAL; + item->value.type = &qbe_long; + item->value.name = ref.name; + break; case STORAGE_SLICE: - case STORAGE_STRING: + *repr_name = "slice_repr"; + item->value = constw(type_hash(&repr)); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_ZEROED; + item->zeroed = 4; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + ref = mktyperef(ctx, type->array.members); + item->type = QD_VALUE; + item->value.kind = QV_GLOBAL; + item->value.type = &qbe_long; + item->value.name = ref.name; + break; + case STORAGE_POINTER: + *repr_name = "pointer"; + item->value = constw(type_hash(&repr)); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_ZEROED; + item->zeroed = 4; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + ref = mktyperef(ctx, type->pointer.referent); + item->type = QD_VALUE; + item->value.kind = QV_GLOBAL; + item->value.type = &qbe_long; + item->value.name = ref.name; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_VALUE; + item->value = constw(type->pointer.flags); + item->value.type = &qbe_word; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_ZEROED; + item->zeroed = 7; + break; + case STORAGE_FUNCTION: + *repr_name = "func"; + item->value = constw(type_hash(&repr)); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_ZEROED; + item->zeroed = 4; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + ref = mktyperef(ctx, type->func.result); + item->type = QD_VALUE; + item->value.kind = QV_GLOBAL; + item->value.type = &qbe_long; + item->value.name = ref.name; + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_VALUE; + item->value = constw(type->func.variadism); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + item->type = QD_VALUE; + item->value = constw(type->func.flags); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + + def = xcalloc(1, sizeof(struct qbe_def)); + def->name = gen_name(ctx, "sldata.%d"); + def->kind = Q_DATA; + subitem = &def->data.items; + for (struct type_func_param *param = type->func.params; + param; param = param->next) { + ref = mktyperef(ctx, param->type); + subitem->type = QD_VALUE; + subitem->value.kind = QV_GLOBAL; + subitem->value.type = &qbe_long; + subitem->value.name = ref.name; + if (param->next) { + subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); + subitem = subitem->next; + } + ++len; + } + qbe_append_def(ctx->out, def); + + item->type = QD_VALUE; + item->value.kind = QV_GLOBAL; + item->value.type = &qbe_long; + item->value.name = strdup(def->name); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + item->type = QD_VALUE; + item->value = constl(len); + item->next = xcalloc(1, sizeof(struct qbe_data_item)); + item = item->next; + item->type = QD_VALUE; + item->value = constl(len); + break; case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: case STORAGE_UNION: - case STORAGE_TYPE: // XXX: Temporary code to make sure code in the wild builds // while we flesh out these types item->value = constw(0); break; } + return item; } static void diff --git a/tests/34-reflect.ha b/tests/34-reflect.ha @@ -73,8 +73,63 @@ fn enums() void = { }; }; +fn arrays() void = { + let ty = types::reflect(type([42]int)); + assert(ty.sz == 42 * size(int)); + assert(ty.al == size(int)); + let ar = ty.repr as types::array; + assert(ar.length == 42); + assert(ar.members == type(int)); +}; + +fn slices() void = { + let ty = types::reflect(type([]int)); + assert(ty.sz == size(*int) + size(size) + size(size)); + assert(ty.al == size(*int)); + let sl = ty.repr as types::slice_repr; + assert(sl == type(int)); +}; + +fn pointers() void = { + let ty = types::reflect(type(*int)); + assert(ty.sz == size(*int)); + assert(ty.al == size(*int)); + let pt = ty.repr as types::pointer; + assert(pt.secondary == type(int)); + assert(pt.flags == 0); + + let ty = types::reflect(type(nullable *int)); + assert(ty.sz == size(*int)); + assert(ty.al == size(*int)); + let pt = ty.repr as types::pointer; + assert(pt.secondary == type(int)); + assert(pt.flags == types::pointer_flags::NULLABLE); +}; + +fn functions() void = { + let ty = types::reflect(type(fn(x: int, y: int) int)); + assert(ty.sz == types::SIZE_UNDEFINED); + assert(ty.al == types::SIZE_UNDEFINED); + let func = ty.repr as types::func; + assert(func.result == type(int)); + assert(func.variadism == types::variadism::NONE); + assert(func.flags == 0); + assert(len(func.params) == 2); + assert(func.params[0] == type(int)); + assert(func.params[1] == type(int)); + + let ty = types::reflect(type(@noreturn fn(x: int, y: int, z: int...) int)); + let func = ty.repr as types::func; + assert(func.variadism == types::variadism::HARE); + assert(func.flags == types::func_flags::NORETURN); +}; + export fn main() void = { builtins(); aliases(); enums(); + arrays(); + slices(); + pointers(); + functions(); }; diff --git a/types/reflect.ha b/types/reflect.ha @@ -63,7 +63,7 @@ export type enumerated = struct { }; // Indicates the variadism of a [[func]]. -export type variadism = enum { +export type variadism = enum uint { NONE, C, HARE, @@ -90,7 +90,7 @@ export type pointer_flags = enum u8 { // *int export type pointer = struct { - referent: type, + secondary: type, flags: pointer_flags, };