From fc8e2acb715b73ba859f11e5a3763e80ec409ecd Mon Sep 17 00:00:00 2001 From: MrLetsplay Date: Tue, 19 Mar 2024 08:00:49 +0100 Subject: [PATCH] Improve casts (WIP) --- backend_wat.go | 95 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 34 deletions(-) diff --git a/backend_wat.go b/backend_wat.go index 6770516..00cc31c 100644 --- a/backend_wat.go +++ b/backend_wat.go @@ -5,14 +5,7 @@ import ( "strconv" ) -func getWATType(t Type) string { - // TODO: tuples? - - if t.Type != Type_Primitive { - panic("not implemented") // TODO: non-primitive types - } - - primitive := t.Value.(PrimitiveType) +func getPrimitiveWATType(primitive PrimitiveType) string { switch primitive { case Primitive_I8, Primitive_I16, Primitive_I32, Primitive_U8, Primitive_U16, Primitive_U32: return "i32" @@ -29,6 +22,17 @@ func getWATType(t Type) string { panic("unhandled type") } +func getWATType(t Type) string { + // TODO: tuples? + + if t.Type != Type_Primitive { + panic("not implemented") // TODO: non-primitive types + } + + primitive := t.Value.(PrimitiveType) + return getPrimitiveWATType(primitive) +} + func getTypeCast(primitive PrimitiveType) string { switch primitive { case Primitive_I8: @@ -76,38 +80,61 @@ func upcastTypeWAT(from PrimitiveType, to PrimitiveType) (string, error) { return "", errors.New("cannot upcast from or to bool") } - if from == Primitive_F32 && to == Primitive_F64 { - return "f64.promote_f32\n", nil - } - - if from == Primitive_F64 && to == Primitive_F32 { - return "f32.demote_f64\n", nil - } - - if isFloatingPoint(from) || isFloatingPoint(to) { - return "", errors.New("cannot upcast int from/to float") - } - - wat := "" - - if getBits(from) == 64 && getBits(to) < 64 { - wat += "i32.wrap_i64\n" - } - - if getBits(from) < 64 && getBits(to) == 64 { - if to == Primitive_I64 { - wat += "i64.extend_i32_s\n" + fromFloat := isFloatingPoint(from) + toFloat := isFloatingPoint(to) + if fromFloat && toFloat { + if to == Primitive_F32 { + return "f32.demote_f64\n", nil } else { - wat += "i64.extend_i32_u\n" + return "f64.promote_f32\n", nil } } - switch to { - case Primitive_I8, Primitive_I16, Primitive_I32, Primitive_U8, Primitive_U16, Primitive_U32: - wat += getTypeCast(to) + if toFloat { + suffix := "" + if isUnsignedInt(to) { + suffix = "u" + } else { + suffix = "s" + } + + return getPrimitiveWATType(to) + ".convert_" + getPrimitiveWATType(from) + "_" + suffix + "\n", nil } - return wat, nil + if fromFloat { + suffix := "" + + if isUnsignedInt(to) { + suffix = "u" + } else { + suffix = "s" + } + + return getPrimitiveWATType(to) + ".trunc_" + getPrimitiveWATType(from) + "_" + suffix + "\n", nil + } + + if getBits(from) == getBits(to) { + return "", nil + } + + if getPrimitiveWATType(from) == getPrimitiveWATType(to) { + // TODO: cast if to is smaller than from + } + + if getBits(from) < 64 && getBits(to) == 64 { + suffix := "" + if isUnsignedInt(from) { + suffix = "u" + } else { + suffix = "s" + } + + return "i64.extend_i32_" + suffix + "\n", nil + } + + // TODO: cast down from 64 to 32 + + return "", nil } func compileExpressionWAT(expr Expression, block Block) (string, error) {