harec

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

commit 9886c903b7c4e919d70e324ed730ef143c6d0b67
parent b2341bcd39cf7e04969a6bb1ee1c2887ce28a8e6
Author: Bor Grošelj Simić <bor.groseljsimic@telemach.net>
Date:   Mon, 24 Jan 2022 05:12:56 +0100

implement {i8,i16} -> floating point casts

Signed-off-by: Bor Grošelj Simić <bor.groseljsimic@telemach.net>

Diffstat:
Msrc/gen.c | 20++++++++++++++++++--
Atests/35-floats.ha | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtests/configure | 3++-
3 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1447,6 +1447,8 @@ gen_expr_cast(struct gen_context *ctx, const struct expression *expr) struct qbe_value qvalue = mkqval(ctx, &value); struct gen_value result = mktemp(ctx, expr->result, "cast.%d"); struct qbe_value qresult = mkqval(ctx, &result); + struct gen_value intermediate; + struct qbe_value qintermediate; enum qbe_instr op; bool is_signed = type_is_signed(from); @@ -1509,8 +1511,22 @@ gen_expr_cast(struct gen_context *ctx, const struct expression *expr) } else if (type_is_integer(from)) { if (type_is_signed(from)) { switch (from->size) { - case 4: op = Q_SWTOF; break; - case 8: op = Q_SLTOF; break; + case 1: + case 2: + intermediate = mktemp(ctx, + &builtin_type_i32, "cast.%d"); + qintermediate = mkqval(ctx, &intermediate); + pushi(ctx->current, &qintermediate, + from->size == 1? Q_EXTSB : Q_EXTSH, + &qvalue, NULL); + qvalue = qintermediate; + /* fallthrough */ + case 4: + op = Q_SWTOF; + break; + case 8: + op = Q_SLTOF; + break; default: abort(); // Invariant } } else { diff --git a/tests/35-floats.ha b/tests/35-floats.ha @@ -0,0 +1,58 @@ +fn casts() void = { + let a = 20f64; + let f = a: f32; + assert(f == 20f32); + let i = a: i8; + assert(i == 20); + let i = a: i16; + assert(i == 20); + let i = a: i16; + assert(i == 20); + let i = a: i32; + assert(i == 20); + let i = a: i64; + assert(i == 20); + + let a = 20f32; + let f = a: f64; + assert(f == 20f64); + let i = a: i8; + assert(i == 20); + let i = a: i16; + assert(i == 20); + let i = a: i16; + assert(i == 20); + let i = a: i32; + assert(i == 20); + let i = a: i64; + assert(i == 20); + + let a = 20i8; + let f = a: f32; + assert(f == 20f32); + let f = a: f64; + assert(f == 20f64); + + let a = 20i16; + let f = a: f32; + assert(f == 20f32); + let f = a: f64; + assert(f == 20f64); + + let a = 20i32; + let f = a: f32; + assert(f == 20f32); + let f = a: f64; + assert(f == 20f64); + + let a = 20i64; + let f = a: f32; + assert(f == 20f32); + let f = a: f64; + assert(f == 20f64); +}; + +export fn main() void = { + // TODO: test parsing, compile-time evaluation + casts(); +}; diff --git a/tests/configure b/tests/configure @@ -37,7 +37,8 @@ tests() { 31-postfix \ 32-copy \ 33-yield \ - 34-declarations + 34-declarations \ + 35-floats do cat <<EOF tests/$t: libhart.a tests/$t.ha