harec

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

commit 6a318a2529db284b56aeaad5beb5643fa23c7acf
parent 8a0d1c0409c7cff4ec9713bca05df7788db59745
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 24 Dec 2020 09:49:55 -0500

gen: implement unary pointer dereference

Diffstat:
Msrc/check.c | 5++++-
Msrc/gen.c | 29++++++++++++++++++++++++-----
Msrc/type_store.c | 42+++++++++++++++++++++++++++++++++++++++++-
3 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -321,7 +321,10 @@ check_expr_unarithm(struct context *ctx, &ctx->store, operand->result, 0); break; case UN_DEREF: - assert(0); // TODO + expect(operand->result->storage == TYPE_STORAGE_POINTER, + "Cannot de-reference non-pointer type"); + expr->result = operand->result->pointer.referent; + break; } trleave(TR_CHECK, NULL); diff --git a/src/gen.c b/src/gen.c @@ -98,6 +98,25 @@ qval_for_object(struct gen_context *ctx, val->name = binding ? strdup(binding->name) : ident_to_sym(&obj->ident); } +// Given a pointer temporary, convert it to a dereferenced pointer for the given +// secondary type +static void +qval_deref(struct gen_context *ctx, + struct qbe_value *val, const struct type *type) +{ + assert(val->type == &qbe_long); // Invariant // XXX: ARCH + val->indirect = true; + val->type = qtype_for_type(ctx, type, false); +} + +// Given a non-pointer temporary, convert it to a pointer +static void +qval_address(struct qbe_value *val) +{ + val->type = &qbe_long; // XXX: ARCH + val->indirect = false; +} + // Given value src of type A, and value dest of type pointer to A, store src in // dest. static void @@ -178,9 +197,7 @@ gen_assign(struct gen_context *ctx, struct qbe_value dest = {0}; gen_temp(ctx, &dest, &qbe_long, "indirect.%d"); // XXX: ARCH gen_expression(ctx, object, &dest); - // TODO: We might want a helper to dereference a qval - dest.indirect = true; - dest.type = qtype_for_type(ctx, value->result, false); + qval_deref(ctx, &dest, value->result); gen_expression(ctx, value, &dest); } else { assert(object->type == EXPR_ACCESS); // Invariant @@ -321,7 +338,7 @@ gen_expr_unarithm(struct gen_context *ctx, struct qbe_value src = {0}; qval_for_object(ctx, &src, obj); - src.type = &qbe_long; // XXX: ARCH + qval_address(&src); gen_store(ctx, out, &src); return; } @@ -353,7 +370,9 @@ gen_expr_unarithm(struct gen_context *ctx, result = operand; break; case UN_DEREF: - assert(0); // TODO + qval_deref(ctx, &operand, expr->result); + gen_load(ctx, &result, &operand, type_is_signed(expr->result)); + break; case UN_ADDRESS: assert(0); // Invariant } diff --git a/src/type_store.c b/src/type_store.c @@ -250,7 +250,47 @@ static bool type_eq_type(struct type_store *store, const struct type *a, const struct type *b) { - assert(0); // TODO + if (a->storage != b->storage || a->flags != b->flags) { + return false; + } + + switch (a->storage) { + case TYPE_STORAGE_BOOL: + case TYPE_STORAGE_CHAR: + case TYPE_STORAGE_F32: + case TYPE_STORAGE_F64: + case TYPE_STORAGE_I8: + case TYPE_STORAGE_I16: + case TYPE_STORAGE_I32: + case TYPE_STORAGE_I64: + case TYPE_STORAGE_INT: + case TYPE_STORAGE_RUNE: + case TYPE_STORAGE_SIZE: + case TYPE_STORAGE_U8: + case TYPE_STORAGE_U16: + case TYPE_STORAGE_U32: + case TYPE_STORAGE_U64: + case TYPE_STORAGE_UINT: + case TYPE_STORAGE_UINTPTR: + case TYPE_STORAGE_VOID: + return true; + case TYPE_STORAGE_ALIAS: + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_ENUM: + case TYPE_STORAGE_FUNCTION: + assert(0); // TODO + case TYPE_STORAGE_POINTER: + return a->pointer.flags == b->pointer.flags && + type_eq_type(store, a->pointer.referent, b->pointer.referent); + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_TAGGED_UNION: + case TYPE_STORAGE_UNION: + assert(0); // TODO + } + + assert(0); // Unreachable } static void