harec

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

commit 414c1934ccb43c37e9cb733810d4eac813ac9a89
parent d3406b24cd4d899cd4d587513429e39cb682641f
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon,  1 Feb 2021 14:44:08 -0500

Implement casting slices to array pointers

Diffstat:
Msrc/gen.c | 15+++++++--------
Msrc/types.c | 4+++-
Mtests/08-slices.ha | 8++++++++
3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1042,10 +1042,12 @@ gen_expr_cast(struct gen_context *ctx, 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 + // Special case: str -> *const char; slice -> ptr + if ((to->storage == TYPE_STORAGE_POINTER && to->pointer.referent->storage == TYPE_STORAGE_CHAR - && from->storage == TYPE_STORAGE_STRING) { + && from->storage == TYPE_STORAGE_STRING) + || (to->storage == TYPE_STORAGE_POINTER + && from->storage == TYPE_STORAGE_SLICE)) { alloc_temp(ctx, &in, from, "cast.in.%d"); in.indirect = false; gen_expression(ctx, expr->cast.value, &in); @@ -1123,11 +1125,8 @@ gen_expr_cast(struct gen_context *ctx, case TYPE_STORAGE_F64: assert(0); // TODO case TYPE_STORAGE_ARRAY: - if (from->storage == TYPE_STORAGE_ARRAY) { - pushi(ctx->current, &result, Q_COPY, &in, NULL); - break; - } - assert(0); // TODO: Convert slice to array + assert(from->storage == TYPE_STORAGE_ARRAY); + pushi(ctx->current, &result, Q_COPY, &in, NULL); break; case TYPE_STORAGE_SLICE: if (from->storage == TYPE_STORAGE_SLICE) { diff --git a/src/types.c b/src/types.c @@ -579,7 +579,9 @@ type_is_castable(const struct type *to, const struct type *from) } return from->storage == TYPE_STORAGE_POINTER || from->storage == TYPE_STORAGE_NULL - || from->storage == TYPE_STORAGE_UINTPTR; + || from->storage == TYPE_STORAGE_UINTPTR + || (to->pointer.referent->storage == TYPE_STORAGE_ARRAY + && from->storage == TYPE_STORAGE_SLICE); case TYPE_STORAGE_SLICE: case TYPE_STORAGE_ARRAY: return from->storage == TYPE_STORAGE_SLICE diff --git a/tests/08-slices.ha b/tests/08-slices.ha @@ -29,6 +29,14 @@ fn storage() void = { }; }; +fn casting() void = { + let x: []int = [1, 2, 3, 4, 5]; + let y = x: *[5]int; + for (let i = 0z; i < len(x); i += 1z) { + assert(x[i] == y[i]); + }; +}; + fn measurements() void = { let x: []int = [1, 2, 3, 4, 5]; assert(size([]int) == size(*[*]int) + size(size) * 2z);