harec

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

commit 1bf83d7925fd22fb45c9012b80873e5f8ea57c8c
parent 411297c121980d3df1d85596358014158aae6a66
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 24 Dec 2020 09:22:48 -0500

check, gen: implement unary address

Diffstat:
Minclude/type_store.h | 3+++
Msrc/check.c | 3+++
Msrc/gen.c | 19++++++++++++++++---
Msrc/type_store.c | 69++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/include/type_store.h b/include/type_store.h @@ -26,4 +26,7 @@ const struct type *builtin_type_for_storage( const struct type *type_store_lookup_with_flags(struct type_store *store, const struct type *type, unsigned int flags); +const struct type *type_store_lookup_pointer(struct type_store *store, + const struct type *referent, unsigned int ptrflags); + #endif diff --git a/src/check.c b/src/check.c @@ -312,6 +312,9 @@ check_expr_unarithm(struct context *ctx, expr->result = operand->result; break; case UN_ADDRESS: + expr->result = type_store_lookup_pointer( + &ctx->store, operand->result, 0); + break; case UN_DEREF: assert(0); // TODO } diff --git a/src/gen.c b/src/gen.c @@ -93,6 +93,7 @@ qval_for_object(struct gen_context *ctx, { const struct gen_binding *binding = binding_lookup(ctx, obj); val->kind = QV_TEMPORARY; // XXX: Is this always the case? + val->indirect = true; // XXX: Is this always the case? val->type = qtype_for_type(ctx, obj->type, false); val->name = binding ? strdup(binding->name) : ident_to_sym(&obj->ident); } @@ -109,7 +110,6 @@ gen_store(struct gen_context *ctx, assert(qtype->stype != Q__AGGREGATE); // TODO if (dest->indirect) { - assert(!src->indirect); // XXX: Correct? pushi(ctx->current, NULL, store_for_type(qtype->stype), src, dest, NULL); } else { pushi(ctx->current, dest, Q_COPY, src, NULL); @@ -154,6 +154,7 @@ gen_access(struct gen_context *ctx, return; } + assert(expr->access.type == ACCESS_IDENTIFIER); // TODO const struct scope_object *obj = expr->access.object; struct qbe_value src; qval_for_object(ctx, &src, obj); @@ -303,6 +304,18 @@ gen_expr_unarithm(struct gen_context *ctx, const struct qbe_type *otype = qtype_for_type(ctx, expr->unarithm.operand->result, false); const struct qbe_type *rtype = qtype_for_type(ctx, expr->result, false); + if (expr->unarithm.op == UN_ADDRESS) { // Special case + const struct expression *operand = expr->unarithm.operand; + assert(operand->type == EXPR_ACCESS); // Invariant + assert(operand->access.type == ACCESS_IDENTIFIER); // TODO + const struct scope_object *obj = operand->access.object; + + struct qbe_value src = {0}; + qval_for_object(ctx, &src, obj); + src.type = &qbe_long; // XXX: ARCH + gen_store(ctx, out, &src); + return; + } struct qbe_value operand = {0}, result = {0}; gen_temp(ctx, &operand, otype, "operand.%d"); @@ -330,9 +343,10 @@ gen_expr_unarithm(struct gen_context *ctx, // no-op result = operand; break; - case UN_ADDRESS: case UN_DEREF: assert(0); // TODO + case UN_ADDRESS: + assert(0); // Invariant } gen_store(ctx, out, &result); @@ -444,7 +458,6 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) // TODO: Update for void type struct qbe_value rval; alloc_temp(ctx, &rval, fntype->func.result, "ret.%d"); - rval.indirect = true; ctx->return_value = &rval; pushl(&qdef->func, &ctx->id, "body.%d"); diff --git a/src/type_store.c b/src/type_store.c @@ -98,7 +98,11 @@ atype_hash(struct type_store *store, const struct ast_type *type) } break; case TYPE_STORAGE_ENUM: + assert(0); // TODO case TYPE_STORAGE_POINTER: + hash = djb2(hash, type->pointer.flags); + hash = atype_hash(store, type->pointer.referent); + break; case TYPE_STORAGE_SLICE: case TYPE_STORAGE_STRING: case TYPE_STORAGE_STRUCT: @@ -147,7 +151,11 @@ type_hash(struct type_store *store, const struct type *type) } break; case TYPE_STORAGE_ENUM: + assert(0); // TODO case TYPE_STORAGE_POINTER: + hash = djb2(hash, type->pointer.flags); + hash = type_hash(store, type->pointer.referent); + break; case TYPE_STORAGE_SLICE: case TYPE_STORAGE_STRING: case TYPE_STORAGE_STRUCT: @@ -298,12 +306,53 @@ type_init_from_atype(struct type_store *store, } } +static const struct type *type_store_lookup_type( + struct type_store *store, const struct type *type); + static void type_init_from_type(struct type_store *store, - struct type *type, - const struct type *atype) + struct type *new, const struct type *old) { - assert(0); // TODO + new->storage = old->storage; + new->flags = old->flags; + + switch (old->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: + assert(0); // Invariant + case TYPE_STORAGE_ALIAS: + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_ENUM: + case TYPE_STORAGE_FUNCTION: + assert(0); // TODO + case TYPE_STORAGE_POINTER: + new->pointer.flags = old->pointer.flags; + new->pointer.referent = type_store_lookup_type( + store, old->pointer.referent); + break; + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_TAGGED_UNION: + case TYPE_STORAGE_UNION: + assert(0); // TODO + } } const struct type * @@ -368,3 +417,17 @@ type_store_lookup_with_flags(struct type_store *store, new.flags |= flags; return type_store_lookup_type(store, &new); } + +const struct type * +type_store_lookup_pointer(struct type_store *store, + const struct type *referent, unsigned int ptrflags) +{ + struct type ptr = { + .storage = TYPE_STORAGE_POINTER, + .pointer = { + .referent = referent, + .flags = ptrflags, + }, + }; + return type_store_lookup_type(store, &ptr); +}