harec

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

commit e662eea3f936ac70c6dc835ba29a4d7322621dab
parent 5c58caef2eed8e41897e06ce6e264ebffb95ca13
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 23 Nov 2021 09:36:53 +0100

all: remove reflection

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
MMakefile | 1-
Mconfigure | 1-
Minclude/expr.h | 1-
Minclude/type_store.h | 3---
Minclude/types.h | 1-
Mrt/Makefile | 7+++----
Mrt/configure | 2--
Drt/types.ha | 147-------------------------------------------------------------------------------
Drt/types_arch+aarch64.ha | 33---------------------------------
Drt/types_arch+riscv64.ha | 33---------------------------------
Drt/types_arch+x86_64.ha | 33---------------------------------
Msrc/check.c | 24+-----------------------
Msrc/eval.c | 6------
Msrc/gen.c | 672+------------------------------------------------------------------------------
Msrc/lex.c | 1-
Msrc/parse.c | 22----------------------
Msrc/qinstr.c | 2--
Msrc/qtype.c | 3---
Msrc/type_store.c | 16----------------
Msrc/typedef.c | 2--
Msrc/types.c | 12------------
Dtests/34-reflect.ha | 237-------------------------------------------------------------------------------
Mtests/configure | 3+--
Dtypes/Makefile | 15---------------
Dtypes/configure | 2--
Dtypes/reflect.ha | 119-------------------------------------------------------------------------------
26 files changed, 6 insertions(+), 1392 deletions(-)

diff --git a/Makefile b/Makefile @@ -8,7 +8,6 @@ harec: $(harec_objects) @printf 'CCLD\t$@\n' @$(CC) $(LDFLAGS) -o $@ $(harec_objects) $(LIBS) -include types/Makefile include rt/Makefile include tests/Makefile diff --git a/configure b/configure @@ -28,7 +28,6 @@ harec() { all="harec" -subdir types subdir rt subdir tests diff --git a/include/expr.h b/include/expr.h @@ -36,7 +36,6 @@ enum expr_type { EXPR_STRUCT, EXPR_SWITCH, EXPR_TUPLE, - EXPR_TYPE, EXPR_UNARITHM, EXPR_YIELD, }; diff --git a/include/type_store.h b/include/type_store.h @@ -55,7 +55,4 @@ const struct type *type_store_tagged_to_union( const struct type *type_store_lookup_tuple(struct type_store *store, struct type_tuple *values); -// Returns the 'type' type. -const struct type *type_store_type(struct type_store *store); - #endif diff --git a/include/types.h b/include/types.h @@ -27,7 +27,6 @@ enum type_storage { STORAGE_UINT, STORAGE_UINTPTR, STORAGE_VOID, - STORAGE_TYPE, // Handled separately // Other types STORAGE_ALIAS, STORAGE_ARRAY, diff --git a/rt/Makefile b/rt/Makefile @@ -8,16 +8,15 @@ libhart_srcs+=\ rt/memmove.ha \ rt/memset.ha \ rt/rtmain.ha \ - rt/strcmp.ha \ - rt/types.ha + rt/strcmp.ha -libhart.a: harec $(libhart_srcs) $(libhart_objs) $(rtstart) types/types.o +libhart.a: harec $(libhart_srcs) $(libhart_objs) $(rtstart) @printf 'HAREC\t$@\n' @mkdir -p $(HARECACHE)/rt @./harec -Nrt -t$(HARECACHE)/rt/rt.td -o $@.ssa $(libhart_srcs) @$(QBE) -o $@.s $@.ssa @$(AS) -g -o $@.o $@.s - @$(AR) -csr $@ $@.o $(libhart_objs) types/types.o + @$(AR) -csr $@ $@.o $(libhart_objs) @rm $@.o $@.s $@.ssa clean-rt: diff --git a/rt/configure b/rt/configure @@ -14,7 +14,6 @@ rt() { rt/+linux/segmalloc.ha \ rt/+linux/syscallno+$arch.ha \ rt/+linux/syscalls.ha \ - rt/types_arch+$arch.ha libhart_objs=\ rt/+linux/syscall+$arch.o @@ -42,7 +41,6 @@ rt() { rt/+freebsd/segmalloc.ha \ rt/+freebsd/syscallno.ha \ rt/+freebsd/syscalls.ha \ - rt/types_arch+$arch.ha libhart_objs=\ rt/+freebsd/syscall+$arch.o diff --git a/rt/types.ha b/rt/types.ha @@ -1,147 +0,0 @@ -// This defines a subset of types/reflect.ha so we can declare static typeinfo -// structures for builtins. -type types::typeinfo = struct { - id: uint, - sz: size, - al: size, - flags: types::flags, - repr: types::repr, -}; - -type types::flags = enum uint { - NONE = 0, - CONST = 1 << 0, - ERROR = 1 << 1, -}; - -type types::repr = (types::alias | types::array | types::builtin - | types::enum_ | types::func | types::pointer | types::slice_repr - | types::struct_union | types::tagged | types::tuple); - -type types::alias = struct { - ident: []str, - secondary: type, -}; - -type types::array = struct { - length: size, - members: type, -}; - -type types::builtin = enum uint { - BOOL, CHAR, F32, F64, I16, I32, I64, I8, INT, NULL, RUNE, SIZE, STR, - U16, U32, U64, U8, UINT, UINTPTR, VOID, TYPE, -}; - -type types::enum_ = struct { - storage: types::builtin, - values: [](str, u64), -}; - -type types::variadism = enum { - NONE, - C, - HARE, -}; - -type types::func_flags = enum uint { - NORETURN = 1 << 0, -}; - -type types::func = struct { - result: type, - variadism: types::variadism, - flags: types::func_flags, - params: []type, -}; - -type types::pointer_flags = enum uint { - NONE = 0, - NULLABLE = 1 << 0, -}; - -type types::pointer = struct { - referent: type, - flags: types::pointer_flags, -}; - -type types::slice_repr = type; - -type types::struct_kind = enum { - STRUCT, - UNION, -}; - -type types::struct_union = struct { - kind: types::struct_kind, - fields: []types::struct_field, -}; - -type types::struct_field = struct { - name: str, - offs: size, - type_: type, -}; - -type types::tagged = []type; - -type types::tuple = []types::tuple_value; - -type types::tuple_value = struct { - offs: size, - type_: type, -}; - -export const @hidden builtin_char: types::typeinfo = types::typeinfo { - id = 3950255460, - sz = 1, al = 1, flags = 0, - repr = types::builtin::CHAR, -}, @hidden builtin_f32: types::typeinfo = types::typeinfo { - id = 1568378015, - sz = 4, al = 4, flags = 0, - repr = types::builtin::F32, -}, @hidden builtin_f64: types::typeinfo = types::typeinfo { - id = 930681398, - sz = 8, al = 8, flags = 0, - repr = types::builtin::F64, -}, @hidden builtin_i8: types::typeinfo = types::typeinfo { - id = 2674862226, - sz = 1, al = 1, flags = 0, - repr = types::builtin::I8, -}, @hidden builtin_i16: types::typeinfo = types::typeinfo { - id = 2037165609, - sz = 2, al = 2, flags = 0, - repr = types::builtin::I16, -}, @hidden builtin_i32: types::typeinfo = types::typeinfo { - id = 1399468992, - sz = 4, al = 4, flags = 0, - repr = types::builtin::I32, -}, @hidden builtin_i64: types::typeinfo = types::typeinfo { - id = 3312558843, - sz = 8, al = 8, flags = 0, - repr = types::builtin::I64, -}, @hidden builtin_rune: types::typeinfo = types::typeinfo { - id = 2374983655, - sz = 4, al = 4, flags = 0, - repr = types::builtin::RUNE, -}, @hidden builtin_u8: types::typeinfo = types::typeinfo { - id = 1906196061, - sz = 1, al = 1, flags = 0, - repr = types::builtin::U8, -}, @hidden builtin_u16: types::typeinfo = types::typeinfo { - id = 2206074632, - sz = 2, al = 2, flags = 0, - repr = types::builtin::U16, -}, @hidden builtin_u32: types::typeinfo = types::typeinfo { - id = 4119164483, - sz = 4, al = 4, flags = 0, - repr = types::builtin::U32, -}, @hidden builtin_u64: types::typeinfo = types::typeinfo { - id = 3481467866, - sz = 8, al = 8, flags = 0, - repr = types::builtin::U64, -}, @hidden builtin_void: types::typeinfo = types::typeinfo { - id = 2543892678, - sz = 0, al = 0, flags = 0, - repr = types::builtin::VOID, -}; diff --git a/rt/types_arch+aarch64.ha b/rt/types_arch+aarch64.ha @@ -1,33 +0,0 @@ -export const @hidden builtin_int: types::typeinfo = types::typeinfo { - id = 1099590421, - sz = 4, al = 4, flags = 0, - repr = types::builtin::INT, -}, @hidden builtin_uint: types::typeinfo = types::typeinfo { - id = 1268499444, - sz = 4, al = 4, flags = 0, - repr = types::builtin::UINT, -}, @hidden builtin_bool: types::typeinfo = types::typeinfo { - id = 292984781, - sz = 4, al = 4, flags = 0, - repr = types::builtin::BOOL, -}, @hidden builtin_size: types::typeinfo = types::typeinfo { - id = 1737287038, - sz = 8, al = 8, flags = 0, - repr = types::builtin::SIZE, -}, @hidden builtin_uintptr: types::typeinfo = types::typeinfo { - id = 3181589295, - sz = 8, al = 8, flags = 0, - repr = types::builtin::UINTPTR, -}, @hidden builtin_str: types::typeinfo = types::typeinfo { - id = 2843771249, - sz = 24, al = 8, flags = 0, - repr = types::builtin::STR, -}, @hidden builtin_null: types::typeinfo = types::typeinfo { - id = 461893804, - sz = 8, al = 8, flags = 0, - repr = types::builtin::NULL, -}, @hidden builtin_type: types::typeinfo = types::typeinfo { - id = 3650376889, - sz = 8, al = 8, flags = 0, - repr = types::builtin::TYPE, -}; diff --git a/rt/types_arch+riscv64.ha b/rt/types_arch+riscv64.ha @@ -1,33 +0,0 @@ -export const @hidden builtin_int: types::typeinfo = types::typeinfo { - id = 1099590421, - sz = 4, al = 4, flags = 0, - repr = types::builtin::INT, -}, @hidden builtin_uint: types::typeinfo = types::typeinfo { - id = 1268499444, - sz = 4, al = 4, flags = 0, - repr = types::builtin::UINT, -}, @hidden builtin_bool: types::typeinfo = types::typeinfo { - id = 292984781, - sz = 4, al = 4, flags = 0, - repr = types::builtin::BOOL, -}, @hidden builtin_size: types::typeinfo = types::typeinfo { - id = 1737287038, - sz = 8, al = 8, flags = 0, - repr = types::builtin::SIZE, -}, @hidden builtin_uintptr: types::typeinfo = types::typeinfo { - id = 3181589295, - sz = 8, al = 8, flags = 0, - repr = types::builtin::UINTPTR, -}, @hidden builtin_str: types::typeinfo = types::typeinfo { - id = 2843771249, - sz = 24, al = 8, flags = 0, - repr = types::builtin::STR, -}, @hidden builtin_null: types::typeinfo = types::typeinfo { - id = 461893804, - sz = 8, al = 8, flags = 0, - repr = types::builtin::NULL, -}, @hidden builtin_type: types::typeinfo = types::typeinfo { - id = 3650376889, - sz = 8, al = 8, flags = 0, - repr = types::builtin::TYPE, -}; diff --git a/rt/types_arch+x86_64.ha b/rt/types_arch+x86_64.ha @@ -1,33 +0,0 @@ -export const @hidden builtin_int: types::typeinfo = types::typeinfo { - id = 1099590421, - sz = 4, al = 4, flags = 0, - repr = types::builtin::INT, -}, @hidden builtin_uint: types::typeinfo = types::typeinfo { - id = 1268499444, - sz = 4, al = 4, flags = 0, - repr = types::builtin::UINT, -}, @hidden builtin_bool: types::typeinfo = types::typeinfo { - id = 292984781, - sz = 4, al = 4, flags = 0, - repr = types::builtin::BOOL, -}, @hidden builtin_size: types::typeinfo = types::typeinfo { - id = 1737287038, - sz = 8, al = 8, flags = 0, - repr = types::builtin::SIZE, -}, @hidden builtin_uintptr: types::typeinfo = types::typeinfo { - id = 3181589295, - sz = 8, al = 8, flags = 0, - repr = types::builtin::UINTPTR, -}, @hidden builtin_str: types::typeinfo = types::typeinfo { - id = 2843771249, - sz = 24, al = 8, flags = 0, - repr = types::builtin::STR, -}, @hidden builtin_null: types::typeinfo = types::typeinfo { - id = 461893804, - sz = 8, al = 8, flags = 0, - repr = types::builtin::NULL, -}, @hidden builtin_type: types::typeinfo = types::typeinfo { - id = 3650376889, - sz = 8, al = 8, flags = 0, - repr = types::builtin::TYPE, -}; diff --git a/src/check.c b/src/check.c @@ -661,7 +661,6 @@ type_promote(struct type_store *store, case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UINTPTR: case STORAGE_UNION: case STORAGE_VOID: @@ -820,8 +819,7 @@ check_expr_binarithm(struct context *ctx, if (!type_is_numeric(p) && type_dealias(p)->storage != STORAGE_POINTER && type_dealias(p)->storage != STORAGE_STRING && type_dealias(p)->storage != STORAGE_BOOL - && type_dealias(p)->storage != STORAGE_RUNE - && type_dealias(p)->storage != STORAGE_TYPE) { + && type_dealias(p)->storage != STORAGE_RUNE) { error(ctx, aexpr->loc, expr, "Cannot perform equality test on %s type", type_storage_unparse(type_dealias(p)->storage)); @@ -1480,7 +1478,6 @@ check_expr_constant(struct context *ctx, case STORAGE_SLICE: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_STRUCT: case STORAGE_UNION: assert(0); // Invariant @@ -2677,18 +2674,6 @@ check_expr_tuple(struct context *ctx, } static void -check_expr_type(struct context *ctx, - const struct ast_expression *aexpr, - struct expression *expr, - const struct type *hint) -{ - expr->type = EXPR_TYPE; - expr->_type.type = type_store_lookup_atype( - ctx->store, aexpr->_type.type); - expr->result = type_store_type(ctx->store); -} - -static void check_expr_unarithm(struct context *ctx, const struct ast_expression *aexpr, struct expression *expr, @@ -2847,9 +2832,6 @@ check_expression(struct context *ctx, case EXPR_TUPLE: check_expr_tuple(ctx, aexpr, expr, hint); break; - case EXPR_TYPE: - check_expr_type(ctx, aexpr, expr, hint); - break; case EXPR_UNARITHM: check_expr_unarithm(ctx, aexpr, expr, hint); break; @@ -3125,7 +3107,6 @@ type_is_specified(const struct type *type, bool is_static) { case STORAGE_RUNE: case STORAGE_SIZE: case STORAGE_STRING: - case STORAGE_TYPE: case STORAGE_U16: case STORAGE_U32: case STORAGE_U64: @@ -3213,7 +3194,6 @@ atype_is_specified(struct context *ctx, case STORAGE_RUNE: case STORAGE_SIZE: case STORAGE_STRING: - case STORAGE_TYPE: case STORAGE_U16: case STORAGE_U32: case STORAGE_U64: @@ -3474,8 +3454,6 @@ expr_is_specified(struct context *ctx, } } return true; - case EXPR_TYPE: - return atype_is_specified(ctx, aexpr->_type.type, is_static); case EXPR_UNARITHM: return expr_is_specified(ctx, aexpr->unarithm.operand, is_static); case EXPR_YIELD: diff --git a/src/eval.c b/src/eval.c @@ -89,7 +89,6 @@ itrunc(const struct type *type, uintmax_t val) case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UNION: case STORAGE_VOID: assert(0); @@ -347,7 +346,6 @@ eval_const(struct context *ctx, struct expression *in, struct expression *out) case STORAGE_POINTER: case STORAGE_RUNE: case STORAGE_SIZE: - case STORAGE_TYPE: case STORAGE_U16: case STORAGE_U32: case STORAGE_U64: @@ -458,8 +456,6 @@ eval_cast(struct context *ctx, struct expression *in, struct expression *out) case STORAGE_TUPLE: case STORAGE_UNION: assert(0); // Invariant - case STORAGE_TYPE: - assert(0); // TODO case STORAGE_VOID: break; // no-op } @@ -548,7 +544,6 @@ constant_default(struct context *ctx, struct expression *v) assert(0); // TODO case STORAGE_ALIAS: case STORAGE_FUNCTION: - case STORAGE_TYPE: assert(0); // Invariant case STORAGE_VOID: break; // no-op @@ -744,7 +739,6 @@ eval_expr(struct context *ctx, struct expression *in, struct expression *out) case EXPR_PROPAGATE: case EXPR_RETURN: case EXPR_SWITCH: - case EXPR_TYPE: // XXX: Should this work? case EXPR_YIELD: // Excluded from translation-compatible subset return EVAL_INVALID; diff --git a/src/gen.c b/src/gen.c @@ -818,7 +818,6 @@ gen_expr_binarithm(struct gen_context *ctx, const struct expression *expr) } assert((ltype->storage == STORAGE_STRING) == (rtype->storage == STORAGE_STRING)); - assert((ltype->storage == STORAGE_TYPE) == (rtype->storage == STORAGE_TYPE)); if (ltype->storage == STORAGE_STRING) { struct qbe_value rtfunc = mkrtfunc(ctx, "rt.strcmp"); pushi(ctx->current, &qresult, Q_CALL, @@ -830,12 +829,6 @@ gen_expr_binarithm(struct gen_context *ctx, const struct expression *expr) assert(expr->binarithm.op == BIN_LEQUAL); } return result; - } else if (ltype->storage == STORAGE_TYPE) { - struct qbe_value qltmp = mkqtmp(ctx, ctx->arch.ptr, ".%d"); - struct qbe_value qrtmp = mkqtmp(ctx, ctx->arch.ptr, ".%d"); - pushi(ctx->current, &qltmp, Q_LOADL, &qlval, NULL); - pushi(ctx->current, &qrtmp, Q_LOADL, &qrval, NULL); - qlval = qltmp, qrval = qrtmp; } enum qbe_instr instr = binarithm_for_op(ctx, expr->binarithm.op, expr->binarithm.lvalue->result); @@ -1342,8 +1335,6 @@ gen_expr_cast(struct gen_context *ctx, const struct expression *expr) assert(from->storage == STORAGE_SLICE); pushi(ctx->current, &qresult, Q_COPY, &qvalue, NULL); break; - case STORAGE_TYPE: - assert(0); // TODO case STORAGE_ALIAS: case STORAGE_BOOL: case STORAGE_FCONST: @@ -2523,89 +2514,6 @@ gen_expr_tuple_at(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 -mktyperef(struct gen_context *ctx, const struct type *type) -{ - size_t n; - char *name; - struct qbe_def *qdef; - switch (type->storage) { - case STORAGE_FCONST: - case STORAGE_ICONST: - abort(); // Invariant - case STORAGE_BOOL: - case STORAGE_CHAR: - case STORAGE_F32: - case STORAGE_F64: - case STORAGE_I16: - case STORAGE_I32: - case STORAGE_I64: - case STORAGE_I8: - case STORAGE_INT: - case STORAGE_NULL: - case STORAGE_RUNE: - case STORAGE_SIZE: - case STORAGE_STRING: - case STORAGE_TYPE: - case STORAGE_U16: - case STORAGE_U32: - case STORAGE_U64: - case STORAGE_U8: - case STORAGE_UINT: - case STORAGE_UINTPTR: - case STORAGE_VOID: - // Built-ins - return (struct gen_value){ - .kind = GV_GLOBAL, - .type = type_store_type(ctx->store), - .name = mkrttype(type->storage), - }; - case STORAGE_ALIAS: - n = snprintf(NULL, 0, "type.%u", type->id); - name = xcalloc(1, n + 1); - snprintf(name, n + 1, "type.%u", type->id); - return (struct gen_value){ - .kind = GV_GLOBAL, - .type = type_store_type(ctx->store), - .name = name, - }; - case STORAGE_ARRAY: - case STORAGE_ENUM: - case STORAGE_FUNCTION: - case STORAGE_POINTER: - case STORAGE_SLICE: - case STORAGE_STRUCT: - case STORAGE_TAGGED: - case STORAGE_TUPLE: - case STORAGE_UNION: - qdef = xcalloc(1, sizeof(struct qbe_def)); - qdef->name = gen_name(ctx, "typeinfo.%d"); - qdef->kind = Q_DATA; - - struct qbe_data_item *subitem = &qdef->data.items; - gen_type_info(ctx, type, subitem); - qbe_append_def(ctx->out, qdef); - - return (struct gen_value){ - .kind = GV_GLOBAL, - .type = type_store_type(ctx->store), - .name = strdup(qdef->name), - }; - } - abort(); // Unreachable -} - -static struct gen_value -gen_expr_type(struct gen_context *ctx, - const struct expression *expr) -{ - const struct type *type = expr->_type.type; - return mktyperef(ctx, type); -} - static struct gen_value gen_expr_unarithm(struct gen_context *ctx, const struct expression *expr) @@ -2712,8 +2620,6 @@ gen_expr(struct gen_context *ctx, const struct expression *expr) return gen_expr_return(ctx, expr); case EXPR_SWITCH: return gen_expr_switch_with(ctx, expr, NULL); - case EXPR_TYPE: - return gen_expr_type(ctx, expr); case EXPR_UNARITHM: return gen_expr_unarithm(ctx, expr); case EXPR_SLICE: @@ -3236,8 +3142,6 @@ gen_data_item(struct gen_context *ctx, struct expression *expr, } break; case STORAGE_UNION: - case STORAGE_TYPE: - assert(0); // TODO case STORAGE_ALIAS: case STORAGE_FCONST: case STORAGE_FUNCTION: @@ -3264,578 +3168,6 @@ gen_global_decl(struct gen_context *ctx, const struct declaration *decl) qbe_append_def(ctx->out, qdef); } -static struct qbe_data_item * -gen_ident_data(struct gen_context *ctx, - const struct identifier *ident, - struct qbe_data_item *item, - size_t *n) -{ - if (ident->ns != NULL) { - item = gen_ident_data(ctx, ident->ns, item, n); - item->next = xcalloc(1, sizeof(struct qbe_data_item)); - item = item->next; - } - - size_t l = strlen(ident->name); - struct qbe_def *def = xcalloc(1, sizeof(struct qbe_def)); - def->name = gen_name(ctx, "strdata.%d"); - def->kind = Q_DATA; - def->data.items.type = QD_STRING; - def->data.items.str = xcalloc(1, l); - def->data.items.sz = l; - memcpy(def->data.items.str, ident->name, l); - qbe_append_def(ctx->out, def); - - 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(l); - item->next = xcalloc(1, sizeof(struct qbe_data_item)); - item = item->next; - item->type = QD_VALUE; - item->value = constl(l); - *n = *n + 1; - return item; -} - -static struct qbe_data_item * -gen_type_info(struct gen_context *ctx, - const struct type *type, - struct qbe_data_item *item) -{ - assert(builtin_type_uint.size == 4); // XXX: Is this ever not true? - item->type = QD_VALUE; - item->value = constw(type->id); - 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->size); - item->next = xcalloc(1, sizeof(struct qbe_data_item)); - item = item->next; - - item->type = QD_VALUE; - item->value = constl(type->align); - item->next = xcalloc(1, sizeof(struct qbe_data_item)); - item = item->next; - - item->type = QD_VALUE; - item->value = constw(type->flags); - 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; - - struct identifier ns = { .name = "types" }; - struct type repr = { - .storage = STORAGE_ALIAS, - .alias = { - .ident = { - .ns = &ns, - }, - }, - }; - char **repr_name = &repr.alias.ident.name; - item->type = QD_VALUE; - - 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: - case STORAGE_BOOL: - case STORAGE_CHAR: - case STORAGE_F32: - case STORAGE_F64: - case STORAGE_I16: - case STORAGE_I32: - case STORAGE_I64: - case STORAGE_I8: - case STORAGE_INT: - case STORAGE_NULL: - case STORAGE_RUNE: - case STORAGE_SIZE: - case STORAGE_STRING: - case STORAGE_TYPE: - case STORAGE_U16: - case STORAGE_U32: - case STORAGE_U64: - case STORAGE_U8: - case STORAGE_UINT: - case STORAGE_UINTPTR: - case STORAGE_VOID: - abort(); // Invariant - case STORAGE_ALIAS: - *repr_name = "alias"; - 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; - - def = xcalloc(1, sizeof(struct qbe_def)); - def->name = gen_name(ctx, "sldata.%d"); - def->kind = Q_DATA; - - subitem = &def->data.items; - gen_ident_data(ctx, &type->alias.ident, subitem, &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); - - item->next = xcalloc(1, sizeof(struct qbe_data_item)); - item = item->next; - - ref = mktyperef(ctx, type->alias.type); - item->type = QD_VALUE; - item->value.kind = QV_GLOBAL; - item->value.type = &qbe_long; - item->value.name = ref.name; - break; - case STORAGE_ENUM: - *repr_name = "enumerated"; - 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 = constw(type->_enum.storage); - 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; - - 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_enum_value *ev = type->_enum.values; - ev; ev = ev->next) { - size_t l = strlen(ev->name); - struct qbe_def *sdef = xcalloc(1, sizeof(struct qbe_def)); - sdef->name = gen_name(ctx, "strdata.%d"); - sdef->kind = Q_DATA; - sdef->data.items.type = QD_STRING; - sdef->data.items.str = xcalloc(1, l); - sdef->data.items.sz = l; - memcpy(sdef->data.items.str, ev->name, l); - qbe_append_def(ctx->out, sdef); - - subitem->value.kind = QV_GLOBAL; - subitem->value.type = &qbe_long; - subitem->value.name = strdup(sdef->name); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - subitem->type = QD_VALUE; - subitem->value = constl(l); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - subitem->type = QD_VALUE; - subitem->value = constl(l); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - - subitem->type = QD_VALUE; - subitem->value = constl(ev->uval); - if (ev->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_ARRAY: - *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: - *repr_name = "slice"; - 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; - - if (type->func.params) { - 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); - } else { - item->type = QD_VALUE; - item->value = constl(0); - } - - 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_UNION: - *repr_name = "struct_union"; - 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 = constw(type->storage == STORAGE_STRUCT ? 0 : 1); - 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; - - def = xcalloc(1, sizeof(struct qbe_def)); - def->name = gen_name(ctx, "sldata.%d"); - def->kind = Q_DATA; - subitem = &def->data.items; - for (struct struct_field *field = type->struct_union.fields; - field; field = field->next) { - if (field->name) { - size_t l = strlen(field->name); - struct qbe_def *sdef = xcalloc(1, sizeof(struct qbe_def)); - sdef->name = gen_name(ctx, "strdata.%d"); - sdef->kind = Q_DATA; - sdef->data.items.type = QD_STRING; - sdef->data.items.str = xcalloc(1, l); - sdef->data.items.sz = l; - memcpy(sdef->data.items.str, field->name, l); - qbe_append_def(ctx->out, sdef); - - subitem->type = QD_VALUE; - subitem->value.kind = QV_GLOBAL; - subitem->value.type = &qbe_long; - subitem->value.name = strdup(sdef->name); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - subitem->type = QD_VALUE; - subitem->value = constl(l); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - subitem->type = QD_VALUE; - subitem->value = constl(l); - } else { - subitem->type = QD_VALUE; - subitem->value = constl(0); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - subitem->type = QD_VALUE; - subitem->value = constl(0); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - subitem->type = QD_VALUE; - subitem->value = constl(0); - } - - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - - subitem->type = QD_VALUE; - subitem->value = constl(field->offset); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - - ref = mktyperef(ctx, field->type); - subitem->type = QD_VALUE; - subitem->value.kind = QV_GLOBAL; - subitem->value.type = &qbe_long; - subitem->value.name = ref.name; - if (field->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_TAGGED: - *repr_name = "tagged"; - 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; - - def = xcalloc(1, sizeof(struct qbe_def)); - def->name = gen_name(ctx, "sldata.%d"); - def->kind = Q_DATA; - subitem = &def->data.items; - for (const struct type_tagged_union *tu = &type->tagged; - tu; tu = tu->next) { - ref = mktyperef(ctx, tu->type); - subitem->type = QD_VALUE; - subitem->value.kind = QV_GLOBAL; - subitem->value.type = &qbe_long; - subitem->value.name = ref.name; - if (tu->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_TUPLE: - *repr_name = "tuple"; - 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; - - def = xcalloc(1, sizeof(struct qbe_def)); - def->name = gen_name(ctx, "sldata.%d"); - def->kind = Q_DATA; - subitem = &def->data.items; - for (const struct type_tuple *field = &type->tuple; - field; field = field->next) { - subitem->type = QD_VALUE; - subitem->value = constl(field->offset); - subitem->next = xcalloc(1, sizeof(struct qbe_data_item)); - subitem = subitem->next; - - ref = mktyperef(ctx, field->type); - subitem->type = QD_VALUE; - subitem->value.kind = QV_GLOBAL; - subitem->value.type = &qbe_long; - subitem->value.name = ref.name; - if (field->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; - } - return item; -} - -static void -gen_type_decl(struct gen_context *ctx, const struct declaration *decl) -{ - const struct type *type = decl->_type; - struct qbe_def *qdef = xcalloc(1, sizeof(struct qbe_def)); - qdef->kind = Q_DATA; - qdef->exported = decl->exported; - - size_t n = snprintf(NULL, 0, "type.%u", type->id); - qdef->name = xcalloc(1, n + 1); - snprintf(qdef->name, n + 1, "type.%u", type->id); - - gen_type_info(ctx, type, &qdef->data.items); - qbe_append_def(ctx->out, qdef); -} - static void gen_decl(struct gen_context *ctx, const struct declaration *decl) { @@ -3847,10 +3179,8 @@ gen_decl(struct gen_context *ctx, const struct declaration *decl) gen_global_decl(ctx, decl); break; case DECL_TYPE: - gen_type_decl(ctx, decl); - break; case DECL_CONST: - break; // Nothing to do + break; // no-op } } diff --git a/src/lex.c b/src/lex.c @@ -1141,7 +1141,6 @@ token_str(const struct token *tok) case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UNION: case STORAGE_VOID: assert(0); diff --git a/src/parse.c b/src/parse.c @@ -369,9 +369,6 @@ parse_primitive_type(struct lexer *lexer) case T_STR: type->storage = STORAGE_STRING; break; - case T_TYPE: - type->storage = STORAGE_TYPE; - break; case T_F32: type->storage = STORAGE_F32; break; @@ -628,7 +625,6 @@ parse_type(struct lexer *lexer) case T_RUNE: case T_SIZE: case T_STR: - case T_TYPE: case T_U16: case T_U32: case T_U64: @@ -820,7 +816,6 @@ parse_constant(struct lexer *lexer) case STORAGE_TAGGED: case STORAGE_TUPLE: case STORAGE_UNION: - case STORAGE_TYPE: assert(0); // Handled in a different nonterminal } return exp; @@ -1136,20 +1131,6 @@ parse_measurement_expression(struct lexer *lexer) } static struct ast_expression * -parse_type_expression(struct lexer *lexer) -{ - struct ast_expression *exp = mkexpr(&lexer->loc); - exp->type = EXPR_TYPE; - struct token tok; - lex(lexer, &tok); - - want(lexer, T_LPAREN, NULL); - exp->_type.type = parse_type(lexer); - want(lexer, T_RPAREN, NULL); - return exp; -} - -static struct ast_expression * parse_call_expression(struct lexer *lexer, struct ast_expression *lvalue) { struct token tok; @@ -1483,9 +1464,6 @@ parse_builtin_expression(struct lexer *lexer) case T_OFFSET: unlex(lexer, &tok); return parse_measurement_expression(lexer); - case T_TYPE: - unlex(lexer, &tok); - return parse_type_expression(lexer); default: unlex(lexer, &tok); break; diff --git a/src/qinstr.c b/src/qinstr.c @@ -57,7 +57,6 @@ store_for_type(struct gen_context *ctx, const struct type *type) break; case STORAGE_POINTER: case STORAGE_UINTPTR: - case STORAGE_TYPE: switch (ctx->arch.ptr->stype) { case Q_LONG: return Q_STOREL; @@ -125,7 +124,6 @@ load_for_type(struct gen_context *ctx, const struct type *type) break; case STORAGE_POINTER: case STORAGE_UINTPTR: - case STORAGE_TYPE: switch (ctx->arch.ptr->stype) { case Q_LONG: return Q_LOADL; diff --git a/src/qtype.c b/src/qtype.c @@ -175,7 +175,6 @@ aggregate_lookup(struct gen_context *ctx, const struct type *type) case STORAGE_SIZE: case STORAGE_UINTPTR: case STORAGE_POINTER: - case STORAGE_TYPE: case STORAGE_NULL: case STORAGE_F32: case STORAGE_F64: @@ -216,7 +215,6 @@ qtype_lookup(struct gen_context *ctx, case STORAGE_UINTPTR: case STORAGE_POINTER: case STORAGE_NULL: - case STORAGE_TYPE: return ctx->arch.ptr; case STORAGE_F32: return &qbe_single; @@ -261,7 +259,6 @@ type_is_aggregate(const struct type *type) case STORAGE_I8: case STORAGE_INT: case STORAGE_POINTER: - case STORAGE_TYPE: case STORAGE_NULL: case STORAGE_RUNE: case STORAGE_SIZE: diff --git a/src/type_store.c b/src/type_store.c @@ -115,7 +115,6 @@ builtin_type_for_storage(enum type_storage storage, bool is_const) return &builtin_type_null; // const null and null are the same type case STORAGE_STRING: return is_const ? &builtin_type_const_str : &builtin_type_str; - case STORAGE_TYPE: case STORAGE_ALIAS: case STORAGE_ARRAY: case STORAGE_FUNCTION: @@ -710,10 +709,6 @@ type_init_from_atype(struct type_store *store, type->pointer.referent = type_store_lookup_atype( store, atype->pointer.referent); break; - case STORAGE_TYPE: - type->size = 8; // XXX: ARCH - type->align = 8; - break; case STORAGE_SLICE: type->size = 24; // XXX: ARCH type->align = 8; @@ -990,17 +985,6 @@ type_store_lookup_tuple(struct type_store *store, struct type_tuple *values) return type_store_lookup_type(store, &type); } -const struct type * -type_store_type(struct type_store *store) -{ - struct type type = { - .storage = STORAGE_TYPE, - .size = 8, // XXX: ARCH - .align = 8, - }; - return type_store_lookup_type(store, &type); -} - // Algorithm: // - Deduplicate and collect nested unions // - Merge *type with nullable *type diff --git a/src/typedef.c b/src/typedef.c @@ -143,7 +143,6 @@ emit_const(const struct expression *expr, FILE *out) case STORAGE_FUNCTION: case STORAGE_POINTER: case STORAGE_TAGGED: - case STORAGE_TYPE: assert(0); // Invariant } } @@ -218,7 +217,6 @@ emit_type(const struct type *type, FILE *out) case STORAGE_RUNE: case STORAGE_SIZE: case STORAGE_STRING: - case STORAGE_TYPE: case STORAGE_U16: case STORAGE_U32: case STORAGE_U64: diff --git a/src/types.c b/src/types.c @@ -150,8 +150,6 @@ type_storage_unparse(enum type_storage storage) return "tagged union"; case STORAGE_TUPLE: return "tuple"; - case STORAGE_TYPE: - return "type"; case STORAGE_U16: return "u16"; case STORAGE_U32: @@ -185,7 +183,6 @@ type_is_integer(const struct type *type) case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UNION: case STORAGE_BOOL: case STORAGE_NULL: @@ -229,7 +226,6 @@ type_is_numeric(const struct type *type) case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UNION: case STORAGE_BOOL: case STORAGE_CHAR: @@ -282,7 +278,6 @@ type_storage_is_signed(enum type_storage storage) case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UNION: case STORAGE_BOOL: case STORAGE_CHAR: @@ -345,7 +340,6 @@ bool storage_is_flexible(enum type_storage storage) case STORAGE_STRUCT: case STORAGE_TAGGED: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_U16: case STORAGE_U32: case STORAGE_U64: @@ -453,9 +447,6 @@ type_hash(const struct type *type) hash = fnv1a_u32(hash, type_hash(tuple->type)); } break; - case STORAGE_TYPE: - // Does not require any additional information - break; } return hash; } @@ -675,7 +666,6 @@ type_is_assignable(const struct type *to, const struct type *from) case STORAGE_RUNE: case STORAGE_STRUCT: case STORAGE_TUPLE: - case STORAGE_TYPE: case STORAGE_UINTPTR: case STORAGE_UNION: return false; @@ -774,8 +764,6 @@ type_is_castable(const struct type *to, const struct type *from) || (to->storage == STORAGE_POINTER && to->pointer.referent->storage == STORAGE_ARRAY && from->storage == STORAGE_SLICE); - case STORAGE_TYPE: - return to->storage == STORAGE_POINTER; // Cannot be cast: case STORAGE_STRING: case STORAGE_BOOL: diff --git a/tests/34-reflect.ha b/tests/34-reflect.ha @@ -1,237 +0,0 @@ -use types; -use types::{builtin}; - -fn unwrap(in: type) *types::typeinfo = { - const info = types::reflect(in); - match (info.repr) { - case a: types::alias => - return unwrap(a.secondary); - case => - return info; - }; -}; - -fn builtins() void = { - const cases: [_](type, size, size, builtin) = [ - (type(u8), 1, 1, builtin::U8), - (type(u16), 2, 2, builtin::U16), - (type(u32), 4, 4, builtin::U32), - (type(u64), 8, 8, builtin::U64), - (type(i8), 1, 1, builtin::I8), - (type(i16), 2, 2, builtin::I16), - (type(i32), 4, 4, builtin::I32), - (type(i64), 8, 8, builtin::I64), - (type(f32), 4, 4, builtin::F32), - (type(f64), 8, 8, builtin::F64), - (type(rune), 4, 4, builtin::RUNE), - (type(char), 1, 1, builtin::CHAR), - (type(void), 0, 0, builtin::VOID), - (type(str), size(str), size(uintptr), builtin::STR), - (type(bool), size(uint), size(uint), builtin::BOOL), - (type(int), size(int), size(int), builtin::INT), - (type(uint), size(uint), size(uint), builtin::UINT), - (type(size), size(size), size(size), builtin::SIZE), - (type(uintptr), size(uintptr), size(uintptr), builtin::UINTPTR), - (type(type), size(type), size(type), builtin::TYPE), // so meta - ]; - for (let i = 0z; i < len(cases); i += 1) { - const item = cases[i]; - let t = types::reflect(item.0); - assert(t.sz == item.1); - assert(t.al == item.2); - let b = t.repr as builtin; - assert(b == item.3); - }; -}; - -type alias = i32; - -fn aliases() void = { - let t = types::reflect(type(alias)); - assert(t.sz == 4); - assert(t.al == 4); - let a = t.repr as types::alias; - assert(a.secondary == type(i32)); - assert(len(a.ident) == 1); - assert(a.ident[0] == "alias"); -}; - -type watchmen = enum { - VIMES, - CARROT, - ANGUA, - COLON, - NOBBY = -1, -}; - -fn enums() void = { - let ty = unwrap(type(watchmen)); - let em = ty.repr as types::enumerated; - assert(em.storage == builtin::INT); - - const cases: [_](str, u64) = [ - ("VIMES", 0), - ("CARROT", 1), - ("ANGUA", 2), - ("COLON", 3), - ("NOBBY", -1: u64), - ]; - for (let i = 0z; i < len(em.values); i += 1) { - const val = em.values[i]; - const expect = cases[i]; - assert(val.0 == expect.0 && val.1.u == expect.1); - }; -}; - -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; - 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); -}; - -fn struct_union() void = { - let ty = types::reflect(type(struct { - x: int, - y: int, - })); - assert(ty.sz == size(int) * 2); - assert(ty.al == size(int)); - let su = ty.repr as types::struct_union; - assert(su.kind == types::struct_kind::STRUCT); - assert(len(su.fields) == 2); - assert(su.fields[0].name == "x"); - assert(su.fields[0].offs == 0); - assert(su.fields[0].type_ == type(int)); - assert(su.fields[1].name == "y"); - assert(su.fields[1].offs == 4); - assert(su.fields[1].type_ == type(int)); - - let ty = types::reflect(type(union { - x: int, - y: int, - })); - let su = ty.repr as types::struct_union; - assert(su.kind == types::struct_kind::UNION); - assert(len(su.fields) == 2); - assert(su.fields[0].name == "x"); - assert(su.fields[0].offs == 0); - assert(su.fields[1].name == "y"); - assert(su.fields[1].offs == 0); - - let ty = types::reflect(type(struct { - x: int, - y: int, - struct { - z: int, - }, - })); - let su = ty.repr as types::struct_union; - assert(len(su.fields) == 3); - assert(su.fields[2].name == ""); - assert(su.fields[2].offs == 8); -}; - -fn tagged() void = { - let ty = types::reflect(type((int | uint | void))); - assert(ty.sz == size(uint) * 2); - assert(ty.al == size(uint)); - let ta = ty.repr as types::tagged; - assert(len(ta) == 3); - // The order of fields in a tagged union type is not consistent with - // their AST ordering, so we don't expect specific types at specific - // indicies. It is consistently ordered (based on type ID), but the type - // IDs change whenever the ABI changes and I don't feel like updating - // this every time. - let _i = false, _u = false, _v = false; - for (let i = 0z; i < len(ta); i += 1) { - if (ta[i] == type(int)) { - _i = true; - }; - if (ta[i] == type(uint)) { - _u = true; - }; - if (ta[i] == type(void)) { - _v = true; - }; - }; - assert(_i && _u && _v); -}; - -fn tuples() void = { - let ty = types::reflect(type((int, int, int))); - assert(ty.sz == size(int) * 3); - assert(ty.al == size(int)); - let tu = ty.repr as types::tuple; - assert(len(tu) == 3); - assert(tu[0].offs == 0); - assert(tu[0].type_ == type(int)); - assert(tu[1].offs == 4); - assert(tu[1].type_ == type(int)); - assert(tu[2].offs == 8); - assert(tu[2].type_ == type(int)); -}; - -fn comparisons() void = { - // Tests that comparisons between non-static typeinfos work (since the - // pointer address will differ) - assert(type(struct { x: int, y: int}) == type(struct { x: int, y: int})); -}; - -export fn main() void = { - builtins(); - aliases(); - enums(); - arrays(); - slices(); - pointers(); - functions(); - struct_union(); - tagged(); - tuples(); - comparisons(); -}; diff --git a/tests/configure b/tests/configure @@ -36,8 +36,7 @@ tests() { 29-unarithm \ 31-postfix \ 32-copy \ - 33-yield \ - 34-reflect + 33-yield do cat <<EOF tests/$t: libhart.a tests/$t.ha diff --git a/types/Makefile b/types/Makefile @@ -1,15 +0,0 @@ -types_srcs+=\ - types/reflect.ha - -types/types.o: harec $(types_srcs) - @printf 'HAREC\t$@\n' - @mkdir -p $(HARECACHE)/types - @./harec -Ntypes -t$(HARECACHE)/types/types.td -o $@.ssa $(types_srcs) - @$(QBE) -o $@.s $@.ssa - @$(AS) -g -o $@ $@.s - @rm $@.s $@.ssa - -clean-types: - @rm -f types/types.o - -.PHONY: types clean-types diff --git a/types/configure b/types/configure @@ -1,2 +0,0 @@ -#!/bin/sh -# no-op diff --git a/types/reflect.ha b/types/reflect.ha @@ -1,119 +0,0 @@ -// The sz field of [[typeinfo]] is set to this value to indicate that the size -// of the type is undefined. -export def SIZE_UNDEFINED: size = -1: size; - -// Structure detailing information about a specific type. -export type typeinfo = struct { - id: uint, - sz: size, - al: size, - flags: flags, - repr: repr, -}; - -// Returns [[typeinfo]] for the provided type. -export fn reflect(in: type) const *typeinfo = in: *typeinfo; - -// Type flags. -export type flags = enum uint { - NONE = 0, - CONST = 1 << 0, - ERROR = 1 << 1, -}; - -// Details of the type representation. -export type repr = (alias | array | builtin - | enumerated | func | pointer | slice - | struct_union | tagged | tuple); - -// A type alias. -export type alias = struct { - ident: []str, - secondary: type, -}; - -// An array type. -export type array = struct { - length: size, - members: type, -}; - -// A built-in type. -export type builtin = enum uint { - BOOL, CHAR, F32, F64, I16, I32, I64, I8, INT, NULL, RUNE, SIZE, STR, - U16, U32, U64, U8, UINT, UINTPTR, VOID, TYPE, -}; - -// An enum type. -export type enumerated = struct { - storage: builtin, - values: [](str, union { u: u64, i: i64 }), -}; - -// Indicates the variadism of a [[func]]. -export type variadism = enum uint { - NONE, - C, - HARE, -}; - -// Indicats if a [[func]] has the @noreturn attribute. -export type func_flags = enum uint { - NONE = 0, - NORETURN = 1 << 0, -}; - -// A function type, e.g. fn(x: int, y: int) int. -export type func = struct { - result: type, - variadism: variadism, - flags: func_flags, - params: []type, -}; - -// Flags which apply to a pointer type. -export type pointer_flags = enum uint { - NONE = 0, - NULLABLE = 1 << 0, -}; - -// *int -export type pointer = struct { - secondary: type, - flags: pointer_flags, -}; - -// Type information for slice members. -export type slice = type; - -// Indicates if a [[_struct]] was declared as a struct or union type. -export type struct_kind = enum uint { - STRUCT, - UNION, -}; - -// struct { ... } or union { ... } -export type struct_union = struct { - kind: struct_kind, - fields: []struct_field, -}; - -// A single struct field. -export type struct_field = struct { - // "" for an anonymous field - name: str, - offs: size, - type_: type, -}; - -// A tagged union type, e.g. (int | uint | void). -export type tagged = []type; - -// A tuple type, e.g. (a, b, c) -export type tuple = []tuple_value; - -// A single value of a tuple type. -export type tuple_value = struct { - offs: size, - type_: type, -};