harec

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

commit 6898b25658d89498ea7c88a15d8b6bfc9658945c
parent bdd2d174e1593e01b449aebfde85cbf1026112c3
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri,  3 Sep 2021 13:19:23 +0200

gen: implement type() for builtins

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

Diffstat:
Minclude/gen.h | 1+
Mrt/Makefile | 2+-
Msrc/check.c | 6+++++-
Msrc/gen.c | 54+++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/genutil.c | 12++++++++++++
Msrc/types.c | 4++--
6 files changed, 74 insertions(+), 5 deletions(-)

diff --git a/include/gen.h b/include/gen.h @@ -91,6 +91,7 @@ struct qbe_value mkcopy(struct gen_context *ctx, struct qbe_value mkqtmp(struct gen_context *ctx, const struct qbe_type *qtype, const char *fmt); struct qbe_value mkrtfunc(struct gen_context *ctx, const char *name); +char *mkrttype(enum type_storage storage); struct qbe_value mklabel(struct gen_context *ctx, struct qbe_statement *stmt, const char *fmt); void branch_copyresult(struct gen_context *ctx, struct gen_value result, diff --git a/rt/Makefile b/rt/Makefile @@ -16,7 +16,7 @@ libhart.a: harec $(libhart_srcs) $(libhart_objs) $(rtstart) @mkdir -p $(HARECACHE)/rt @./harec -Nrt -t$(HARECACHE)/rt/rt.td -o $@.ssa $(libhart_srcs) @$(QBE) -o $@.s $@.ssa - @$(AS) -o $@.o $@.s + @$(AS) -g -o $@.o $@.s @$(AR) -csr $@ $@.o $(libhart_objs) @rm $@.o $@.s $@.ssa diff --git a/src/check.c b/src/check.c @@ -3452,7 +3452,11 @@ scan_type(struct context *ctx, const struct ast_type_decl *decl, bool exported) type_store_lookup_atype(ctx->store, decl->type); struct identifier ident = {0}; - mkident(ctx, &ident, &decl->ident); + if (!decl->ident.ns) { + mkident(ctx, &ident, &decl->ident); + } else { + ident = decl->ident; + } const struct type *alias = type_store_lookup_alias(ctx->store, &ident, type, exported); diff --git a/src/gen.c b/src/gen.c @@ -2504,6 +2504,58 @@ gen_expr_tuple_at(struct gen_context *ctx, } static struct gen_value +gen_expr_type(struct gen_context *ctx, + const struct expression *expr) +{ + const struct type *type = expr->_type.type; + switch (type->storage) { + case STORAGE_BOOL: + case STORAGE_CHAR: + case STORAGE_ENUM: + 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_TYPE: // TODO: Add me to builtins & audit + 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 = expr->result, + .name = mkrttype(type->storage), + }; + case STORAGE_FCONST: + case STORAGE_ICONST: + abort(); // Invariant + case STORAGE_ALIAS: + assert(0); // TODO: Emit typeinfo (in gen_decl_type) + case STORAGE_ARRAY: + case STORAGE_FUNCTION: + case STORAGE_POINTER: + case STORAGE_SLICE: + case STORAGE_STRING: + case STORAGE_STRUCT: + case STORAGE_TAGGED: + case STORAGE_TUPLE: + case STORAGE_UNION: + assert(0); // TODO: Emit typeinfo (here) + } + abort(); // Unreachable +} + +static struct gen_value gen_expr_unarithm(struct gen_context *ctx, const struct expression *expr) { @@ -2610,7 +2662,7 @@ gen_expr(struct gen_context *ctx, const struct expression *expr) case EXPR_SWITCH: return gen_expr_switch_with(ctx, expr, NULL); case EXPR_TYPE: - assert(0); // TODO + return gen_expr_type(ctx, expr); case EXPR_UNARITHM: return gen_expr_unarithm(ctx, expr); case EXPR_SLICE: diff --git a/src/genutil.c b/src/genutil.c @@ -3,6 +3,7 @@ #include <string.h> #include "gen.h" #include "qbe.h" +#include "types.h" #include "util.h" char * @@ -84,6 +85,17 @@ mkrtfunc(struct gen_context *ctx, const char *name) }; } +char * +mkrttype(enum type_storage storage) +{ + int n = snprintf(NULL, 0, "rt.builtin_%s", + type_storage_unparse(storage)); + char *str = xcalloc(1, n + 1); + snprintf(str, n + 1, "rt.builtin_%s", + type_storage_unparse(storage)); + return str; +} + struct qbe_value mklabel(struct gen_context *ctx, struct qbe_statement *stmt, const char *fmt) { diff --git a/src/types.c b/src/types.c @@ -723,8 +723,6 @@ type_is_castable(const struct type *to, const struct type *from) switch (from->storage) { case STORAGE_FCONST: case STORAGE_ICONST: - case STORAGE_TYPE: - assert(0); // TODO case STORAGE_I8: case STORAGE_I16: case STORAGE_I32: @@ -771,6 +769,8 @@ 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: