harec

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

commit 9e727edfbe7d08d197500fd5a4cd29f24c5156f5
parent 4db3a7129372f4a13421fb70c50fa244b3a1813e
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 26 Dec 2020 11:10:28 -0500

type store: rig up array types

Diffstat:
Minclude/expr.h | 9++++++++-
Minclude/types.h | 13++++++++++---
Msrc/eval.c | 11+++++++++++
Msrc/type_store.c | 43++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/include/expr.h b/include/expr.h @@ -92,6 +92,12 @@ struct expression_call { struct call_argument *args; }; +struct array_constant { + struct expression *expr; + struct array_constant *next; + bool expand; +}; + union expression_constant { struct { char *sval; @@ -102,7 +108,8 @@ union expression_constant { intmax_t ival; uintmax_t uval; uint32_t rune; - // TODO: Array, slice, struct constants + struct array_constant *array; + // TODO: Struct constants }; struct expressions { diff --git a/include/types.h b/include/types.h @@ -40,6 +40,15 @@ enum type_storage { struct type; +#define SIZE_UNDEFINED ((size_t)-1) +#define ALIGN_UNDEFINED ((size_t)-1) + +struct type_array { + size_t length; // SIZE_UNDEFINED for [*] or slices + const struct type *members; + bool extensible; +}; + enum variadism { VARIADISM_NONE, VARIADISM_C, @@ -75,14 +84,12 @@ enum type_flags { TYPE_CONST = 1 << 0, }; -#define SIZE_UNDEFINED ((size_t)-1) -#define ALIGN_UNDEFINED ((size_t)-1) - struct type { enum type_storage storage; unsigned int flags; size_t size, align; union { + struct type_array array; struct type_func func; struct type_pointer pointer; }; diff --git a/src/eval.c b/src/eval.c @@ -7,13 +7,24 @@ #include "types.h" enum eval_result +eval_const(struct context *ctx, struct expression *in, struct expression *out) +{ + out->type = EXPR_CONSTANT; + out->result = in->result; + out->constant = in->constant; + return EVAL_OK; +} + +enum eval_result eval_expr(struct context *ctx, struct expression *in, struct expression *out) { switch (in->type) { case EXPR_ACCESS: case EXPR_BINARITHM: case EXPR_CAST: + assert(0); // TODO case EXPR_CONSTANT: + return eval_const(ctx, in, out); case EXPR_CONTINUE: case EXPR_FOR: case EXPR_MEASURE: diff --git a/src/type_store.c b/src/type_store.c @@ -1,9 +1,29 @@ #include <assert.h> #include <stdlib.h> #include "check.h" +#include "eval.h" #include "type_store.h" #include "util.h" +static size_t +ast_array_len(struct type_store *store, const struct ast_type *atype) +{ + // TODO: Maybe we should cache these + struct expression in, out; + if (atype->array.length == NULL) { + return SIZE_UNDEFINED; + } + check_expression(store->check_context, atype->array.length, &in); + enum eval_result r = eval_expr(store->check_context, &in, &out); + // TODO: Bubble up these errors: + assert(r == EVAL_OK); + assert(type_is_integer(out.result)); + if (type_is_signed(out.result)) { + assert(out.constant.ival > 0); + } + return (size_t)out.constant.uval; +} + bool type_is_assignable(struct type_store *store, const struct type *to, @@ -154,6 +174,7 @@ atype_hash(struct type_store *store, const struct ast_type *type) unsigned long hash = DJB2_INIT; hash = djb2(hash, type->storage); hash = djb2(hash, type->flags); + switch (type->storage) { case TYPE_STORAGE_BOOL: case TYPE_STORAGE_CHAR: @@ -176,8 +197,11 @@ atype_hash(struct type_store *store, const struct ast_type *type) case TYPE_STORAGE_VOID: break; // built-ins case TYPE_STORAGE_ALIAS: - case TYPE_STORAGE_ARRAY: assert(0); // TODO + case TYPE_STORAGE_ARRAY: + hash = djb2(hash, atype_hash(store, type->array.members)); + hash = djb2(hash, ast_array_len(store, type)); + break; case TYPE_STORAGE_FUNCTION: hash = djb2(hash, atype_hash(store, type->func.result)); hash = djb2(hash, type->func.variadism); @@ -303,7 +327,10 @@ type_eq_atype(struct type_store *store, case TYPE_STORAGE_VOID: return true; case TYPE_STORAGE_ALIAS: + assert(0); // TODO case TYPE_STORAGE_ARRAY: + return type->array.length == ast_array_len(store, atype) + && type_eq_atype(store, type->array.members, atype->array.members); case TYPE_STORAGE_ENUM: assert(0); // TODO case TYPE_STORAGE_FUNCTION: @@ -433,7 +460,21 @@ type_init_from_atype(struct type_store *store, case TYPE_STORAGE_VOID: assert(0); // Invariant case TYPE_STORAGE_ALIAS: + assert(0); // TODO case TYPE_STORAGE_ARRAY: + type->array.length = ast_array_len(store, atype); + type->array.members = type_store_lookup_atype( + store, atype->array.members); + // TODO: Bubble this up: + assert(type->array.members->size != SIZE_UNDEFINED); + + type->align = type->array.members->align; + if (type->array.length == SIZE_UNDEFINED) { + type->size = SIZE_UNDEFINED; + } else { + type->size = type->array.members->size * type->array.length; + } + break; case TYPE_STORAGE_ENUM: assert(0); // TODO case TYPE_STORAGE_FUNCTION: