Improve casts (WIP)

This commit is contained in:
MrLetsplay 2024-03-19 08:00:49 +01:00
parent a7ec08b379
commit fc8e2acb71
Signed by: mr
SSH Key Fingerprint: SHA256:0zWNiRisbQ4dq/CCQAaMLoF3UfkF5wKPXO7DcjfFBEU

View File

@ -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 {
fromFloat := isFloatingPoint(from)
toFloat := isFloatingPoint(to)
if fromFloat && toFloat {
if to == Primitive_F32 {
return "f32.demote_f64\n", nil
} else {
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")
if toFloat {
suffix := ""
if isUnsignedInt(to) {
suffix = "u"
} else {
suffix = "s"
}
wat := ""
return getPrimitiveWATType(to) + ".convert_" + getPrimitiveWATType(from) + "_" + suffix + "\n", nil
}
if getBits(from) == 64 && getBits(to) < 64 {
wat += "i32.wrap_i64\n"
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 {
if to == Primitive_I64 {
wat += "i64.extend_i32_s\n"
suffix := ""
if isUnsignedInt(from) {
suffix = "u"
} else {
wat += "i64.extend_i32_u\n"
}
suffix = "s"
}
switch to {
case Primitive_I8, Primitive_I16, Primitive_I32, Primitive_U8, Primitive_U16, Primitive_U32:
wat += getTypeCast(to)
return "i64.extend_i32_" + suffix + "\n", nil
}
return wat, nil
// TODO: cast down from 64 to 32
return "", nil
}
func compileExpressionWAT(expr Expression, block Block) (string, error) {