harec

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

commit 86e0a84d07bbdb4fbe47607d5233f51c1a3877e1
parent 689bdd02034adc68233d4e93dd233ead6d508108
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 31 Dec 2020 10:47:23 -0500

Implement str -> *const char cast

Diffstat:
Msrc/gen.c | 28++++++++++++++++++----------
Msrc/type_store.c | 5+++--
2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -556,9 +556,23 @@ gen_expr_cast(struct gen_context *ctx, bool is_signed = type_is_signed(from); struct qbe_value in = {0}, result = {0}; + gen_temp(ctx, &result, qtype_for_type(ctx, to, false), "cast.out.%d"); + + // Special case: str -> *const char + if (to->storage == TYPE_STORAGE_POINTER + && to->pointer.referent->storage == TYPE_STORAGE_CHAR + && from->storage == TYPE_STORAGE_STRING) { + gen_temp(ctx, &in, &qbe_long, "cast.in.%d"); + qval_address(&in); + gen_expression(ctx, expr->cast.value, &in); + qval_deref(&in); + gen_load(ctx, &result, &in, false); + gen_store(ctx, out, &result); + return; + } + gen_temp(ctx, &in, qtype_for_type(ctx, from, false), "cast.in.%d"); gen_expression(ctx, expr->cast.value, &in); - gen_temp(ctx, &result, qtype_for_type(ctx, to, false), "cast.out.%d"); enum qbe_instr op; switch (to->storage) { @@ -608,22 +622,16 @@ gen_expr_cast(struct gen_context *ctx, case TYPE_STORAGE_TAGGED_UNION: case TYPE_STORAGE_ENUM: assert(0); // TODO - case TYPE_STORAGE_STRING: - assert(0); // TODO - case TYPE_STORAGE_POINTER: - if (to->pointer.referent->storage == TYPE_STORAGE_CHAR - && from->storage == TYPE_STORAGE_STRING) { - assert(0); // TODO - } - // Fallthrough // Can be implemented with a copy case TYPE_STORAGE_ARRAY: - case TYPE_STORAGE_SLICE: case TYPE_STORAGE_NULL: + case TYPE_STORAGE_POINTER: + case TYPE_STORAGE_SLICE: pushi(ctx->current, &result, Q_COPY, &in, NULL); break; case TYPE_STORAGE_BOOL: case TYPE_STORAGE_FUNCTION: + case TYPE_STORAGE_STRING: case TYPE_STORAGE_STRUCT: case TYPE_STORAGE_UNION: case TYPE_STORAGE_VOID: diff --git a/src/type_store.c b/src/type_store.c @@ -154,13 +154,14 @@ type_is_castable(const struct type *to, return to->storage == TYPE_STORAGE_POINTER || to->storage == TYPE_STORAGE_NULL || to->storage == TYPE_STORAGE_UINTPTR; - case TYPE_STORAGE_STRING: - return to == &builtin_type_const_ptr_char; case TYPE_STORAGE_SLICE: case TYPE_STORAGE_ARRAY: case TYPE_STORAGE_ALIAS: case TYPE_STORAGE_TAGGED_UNION: assert(0); // TODO + case TYPE_STORAGE_STRING: + return to->pointer.referent->storage == TYPE_STORAGE_CHAR + && to->pointer.referent->flags & TYPE_CONST; case TYPE_STORAGE_RUNE: return to->storage == TYPE_STORAGE_U32; // Cannot be cast: