harec

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

commit 08ba275b6cb0ab3047b40f87254ba8a992a2672d
parent 10baff0e69f05d04e6a273216f9baefcfc91ee50
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 12 Jan 2021 17:20:45 -0500

eval: implement basic casts

Diffstat:
Msrc/eval.c | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/gen.c | 6+++++-
2 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/src/eval.c b/src/eval.c @@ -16,13 +16,79 @@ eval_const(struct context *ctx, struct expression *in, struct expression *out) } enum eval_result +eval_cast(struct context *ctx, struct expression *in, struct expression *out) +{ + struct expression val = {0}; + enum eval_result r = eval_expr(ctx, in->cast.value, &val); + if (r != EVAL_OK) { + return r; + } + + const struct type *to = type_dealias(in->result), + *from = type_dealias(val.result); + if (to->storage == from->storage) { + *out = val; + return EVAL_OK; + } + + // XXX: We should also be able to handle expressions which use + // symbols/identifiers + out->type = EXPR_CONSTANT; + out->result = to; + + switch (to->storage) { + case TYPE_STORAGE_POINTER: + if (from->storage == TYPE_STORAGE_NULL) { + out->constant.uval = 0; + return EVAL_OK; + } + assert(0); // TODO + case TYPE_STORAGE_CHAR: + case TYPE_STORAGE_ENUM: + case TYPE_STORAGE_F32: + case TYPE_STORAGE_F64: + case TYPE_STORAGE_I16: + case TYPE_STORAGE_I32: + case TYPE_STORAGE_I64: + case TYPE_STORAGE_I8: + case TYPE_STORAGE_INT: + case TYPE_STORAGE_NULL: + case TYPE_STORAGE_RUNE: + case TYPE_STORAGE_SIZE: + case TYPE_STORAGE_U16: + case TYPE_STORAGE_U32: + case TYPE_STORAGE_U64: + case TYPE_STORAGE_U8: + case TYPE_STORAGE_UINT: + case TYPE_STORAGE_UINTPTR: + case TYPE_STORAGE_ARRAY: + case TYPE_STORAGE_SLICE: + case TYPE_STORAGE_TAGGED_UNION: + assert(0); // TODO + case TYPE_STORAGE_ALIAS: + assert(0); // Handled above + case TYPE_STORAGE_BOOL: + case TYPE_STORAGE_FUNCTION: + case TYPE_STORAGE_STRING: + case TYPE_STORAGE_STRUCT: + case TYPE_STORAGE_UNION: + assert(0); // Invariant + case TYPE_STORAGE_VOID: + break; // no-op + } + + assert(0); // Unreachable +} + +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_CAST: + return eval_cast(ctx, in, out); case EXPR_CONSTANT: return eval_const(ctx, in, out); case EXPR_CONTINUE: diff --git a/src/gen.c b/src/gen.c @@ -1367,9 +1367,13 @@ gen_global_decl(struct gen_context *ctx, const struct declaration *decl) assert(0); // TODO case TYPE_STORAGE_UINTPTR: assert(0); // TODO: What are the semantics for this? + case TYPE_STORAGE_POINTER: + assert(global->value->type == EXPR_CONSTANT); // TODO? + item->type = QD_VALUE; + constl(&item->value, (uint64_t)constant->uval); // XXX: ARCH + break; case TYPE_STORAGE_ARRAY: case TYPE_STORAGE_ENUM: - case TYPE_STORAGE_POINTER: case TYPE_STORAGE_SLICE: case TYPE_STORAGE_STRING: case TYPE_STORAGE_STRUCT: