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:
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: