diff --git a/fathom/src/core.rs b/fathom/src/core.rs index 2843f304f..360277987 100644 --- a/fathom/src/core.rs +++ b/fathom/src/core.rs @@ -509,6 +509,9 @@ def_prims! { S8Div => "s8_div", S8Abs => "s8_abs", S8UAbs => "s8_unsigned_abs", + S8ExtendS16 => "s8_extend_s16", + S8ExtendS32 => "s8_extend_s32", + S8ExtendS64 => "s8_extend_s64", S16Eq => "s16_eq", S16Neq => "s16_neq", @@ -523,6 +526,9 @@ def_prims! { S16Div => "s16_div", S16Abs => "s16_abs", S16UAbs => "s16_unsigned_abs", + S16TruncateS8 => "s16_truncate_s8", + S16ExtendS32 => "s16_extend_s32", + S16ExtendS64 => "s16_extend_s64", S32Eq => "s32_eq", S32Neq => "s32_neq", @@ -537,6 +543,9 @@ def_prims! { S32Div => "s32_div", S32Abs => "s32_abs", S32UAbs => "s32_unsigned_abs", + S32TruncateS8 => "s32_truncate_s8", + S32TruncateS16 => "s32_truncate_s16", + S32ExtendS64 => "s32_extend_s64", S64Eq => "s64_eq", S64Neq => "s64_neq", @@ -551,6 +560,9 @@ def_prims! { S64Div => "s64_div", S64Abs => "s64_abs", S64UAbs => "s64_unsigned_abs", + S64TruncateS8 => "s64_truncate_s8", + S64TruncateS16 => "s64_truncate_s16", + S64TruncateS32 => "s64_truncate_s32", OptionSome => "some", OptionNone => "none", diff --git a/fathom/src/core/prim.rs b/fathom/src/core/prim.rs index 58e2a19a4..94f559aa9 100644 --- a/fathom/src/core/prim.rs +++ b/fathom/src/core/prim.rs @@ -265,6 +265,9 @@ impl<'arena> Env<'arena> { env.define_prim_fun(S8Div, [&S8_TYPE, &S8_TYPE], &S8_TYPE); env.define_prim_fun(S8Abs, [&S8_TYPE], &S8_TYPE); env.define_prim_fun(S8UAbs, [&S8_TYPE], &U8_TYPE); + env.define_prim_fun(S8ExtendS16, [&S8_TYPE], &S16_TYPE); + env.define_prim_fun(S8ExtendS32, [&S8_TYPE], &S32_TYPE); + env.define_prim_fun(S8ExtendS64, [&S8_TYPE], &S64_TYPE); env.define_prim_fun(S16Eq, [&S16_TYPE, &S16_TYPE], &BOOL_TYPE); env.define_prim_fun(S16Neq, [&S16_TYPE, &S16_TYPE], &BOOL_TYPE); @@ -279,6 +282,9 @@ impl<'arena> Env<'arena> { env.define_prim_fun(S16Div, [&S16_TYPE, &S16_TYPE], &S16_TYPE); env.define_prim_fun(S16Abs, [&S16_TYPE], &S16_TYPE); env.define_prim_fun(S16UAbs, [&S16_TYPE], &U16_TYPE); + env.define_prim_fun(S16TruncateS8, [&S16_TYPE], &S8_TYPE); + env.define_prim_fun(S16ExtendS32, [&S16_TYPE], &S32_TYPE); + env.define_prim_fun(S16ExtendS64, [&S16_TYPE], &S64_TYPE); env.define_prim_fun(S32Eq, [&S32_TYPE, &S32_TYPE], &BOOL_TYPE); env.define_prim_fun(S32Neq, [&S32_TYPE, &S32_TYPE], &BOOL_TYPE); @@ -293,6 +299,9 @@ impl<'arena> Env<'arena> { env.define_prim_fun(S32Div, [&S32_TYPE, &S32_TYPE], &S32_TYPE); env.define_prim_fun(S32Abs, [&S32_TYPE], &S32_TYPE); env.define_prim_fun(S32UAbs, [&S32_TYPE], &U32_TYPE); + env.define_prim_fun(S32TruncateS8, [&S32_TYPE], &S8_TYPE); + env.define_prim_fun(S32TruncateS16, [&S32_TYPE], &S16_TYPE); + env.define_prim_fun(S32ExtendS64, [&S32_TYPE], &S64_TYPE); env.define_prim_fun(S64Eq, [&S64_TYPE, &S64_TYPE], &BOOL_TYPE); env.define_prim_fun(S64Neq, [&S64_TYPE, &S64_TYPE], &BOOL_TYPE); @@ -307,6 +316,9 @@ impl<'arena> Env<'arena> { env.define_prim_fun(S64Div, [&S64_TYPE, &S64_TYPE], &S64_TYPE); env.define_prim_fun(S64Abs, [&S64_TYPE], &S64_TYPE); env.define_prim_fun(S64UAbs, [&S64_TYPE], &U64_TYPE); + env.define_prim_fun(S64TruncateS8, [&S64_TYPE], &S8_TYPE); + env.define_prim_fun(S64TruncateS16, [&S64_TYPE], &S16_TYPE); + env.define_prim_fun(S64TruncateS32, [&S64_TYPE], &S32_TYPE); env.define_prim( OptionSome, @@ -731,6 +743,9 @@ pub fn step(prim: Prim) -> Step { Prim::S8Div => const_step!([x: S8, y: S8] => Const::S8(i8::checked_div(*x, *y)?)), Prim::S8Abs => const_step!([x: S8] => Const::S8(i8::abs(*x))), Prim::S8UAbs => const_step!([x: S8] => Const::U8(i8::unsigned_abs(*x), UIntStyle::Decimal)), + Prim::S8ExtendS16 => const_step!([x: S8] => Const::S16(i16::from(*x))), + Prim::S8ExtendS32 => const_step!([x: S8] => Const::S32(i32::from(*x))), + Prim::S8ExtendS64 => const_step!([x: S8] => Const::S64(i64::from(*x))), Prim::S16Eq => const_step!([x: S16, y: S16] => Const::Bool(x == y)), Prim::S16Neq => const_step!([x: S16, y: S16] => Const::Bool(x != y)), @@ -745,6 +760,9 @@ pub fn step(prim: Prim) -> Step { Prim::S16Div => const_step!([x: S16, y: S16] => Const::S16(i16::checked_div(*x, *y)?)), Prim::S16Abs => const_step!([x: S16] => Const::S16(i16::abs(*x))), Prim::S16UAbs => const_step!([x: S16] => Const::U16(i16::unsigned_abs(*x), UIntStyle::Decimal)), + Prim::S16TruncateS8 => const_step!([x: S16] => Const::S8(*x as i8)), + Prim::S16ExtendS32 => const_step!([x: S16] => Const::S32(i32::from(*x))), + Prim::S16ExtendS64 => const_step!([x: S16] => Const::S64(i64::from(*x))), Prim::S32Eq => const_step!([x: S32, y: S32] => Const::Bool(x == y)), Prim::S32Neq => const_step!([x: S32, y: S32] => Const::Bool(x != y)), @@ -759,6 +777,9 @@ pub fn step(prim: Prim) -> Step { Prim::S32Div => const_step!([x: S32, y: S32] => Const::S32(i32::checked_div(*x, *y)?)), Prim::S32Abs => const_step!([x: S32] => Const::S32(i32::abs(*x))), Prim::S32UAbs => const_step!([x: S32] => Const::U32(i32::unsigned_abs(*x), UIntStyle::Decimal)), + Prim::S32TruncateS8 => const_step!([x: S32] => Const::S8(*x as i8)), + Prim::S32TruncateS16 => const_step!([x: S32] => Const::S16(*x as i16)), + Prim::S32ExtendS64 => const_step!([x: S32] => Const::S64(i64::from(*x))), Prim::S64Eq => const_step!([x: S64, y: S64] => Const::Bool(x == y)), Prim::S64Neq => const_step!([x: S64, y: S64] => Const::Bool(x != y)), @@ -773,6 +794,9 @@ pub fn step(prim: Prim) -> Step { Prim::S64Div => const_step!([x: S64, y: S64] => Const::S64(i64::checked_div(*x, *y)?)), Prim::S64Abs => const_step!([x: S64] => Const::S64(i64::abs(*x))), Prim::S64UAbs => const_step!([x: S64] => Const::U64(i64::unsigned_abs(*x), UIntStyle::Decimal)), + Prim::S64TruncateS8 => const_step!([x: S64] => Const::S8(*x as i8)), + Prim::S64TruncateS16 => const_step!([x: S64] => Const::S16(*x as i16)), + Prim::S64TruncateS32 => const_step!([x: S64] => Const::S32(*x as i32)), Prim::OptionFold => step!(env, [_, _, on_none, on_some, option] => { match option.match_prim_spine()? { diff --git a/tests/succeed/primitives.fathom b/tests/succeed/primitives.fathom index 216dc8cbd..21c172e8f 100644 --- a/tests/succeed/primitives.fathom +++ b/tests/succeed/primitives.fathom @@ -161,6 +161,9 @@ let _ = s8_mul : S8 -> S8 -> S8; let _ = s8_div : S8 -> S8 -> S8; let _ = s8_abs : S8 -> S8; let _ = s8_unsigned_abs : S8 -> U8; +let _ = s8_extend_s16 : S8 -> S16; +let _ = s8_extend_s32 : S8 -> S32; +let _ = s8_extend_s64 : S8 -> S64; let _ = s16_eq : S16 -> S16 -> Bool; let _ = s16_neq : S16 -> S16 -> Bool; @@ -175,6 +178,9 @@ let _ = s16_mul : S16 -> S16 -> S16; let _ = s16_div : S16 -> S16 -> S16; let _ = s16_abs : S16 -> S16; let _ = s16_unsigned_abs : S16 -> U16; +let _ = s16_truncate_s8 : S16 -> S8; +let _ = s16_extend_s32 : S16 -> S32; +let _ = s16_extend_s64 : S16 -> S64; let _ = s32_eq : S32 -> S32 -> Bool; let _ = s32_neq : S32 -> S32 -> Bool; @@ -189,6 +195,9 @@ let _ = s32_mul : S32 -> S32 -> S32; let _ = s32_div : S32 -> S32 -> S32; let _ = s32_abs : S32 -> S32; let _ = s32_unsigned_abs : S32 -> U32; +let _ = s32_truncate_s8 : S32 -> S8; +let _ = s32_truncate_s16 : S32 -> S16; +let _ = s32_extend_s64 : S32 -> S64; let _ = s64_eq : S64 -> S64 -> Bool; let _ = s64_neq : S64 -> S64 -> Bool; @@ -203,6 +212,9 @@ let _ = s64_mul : S64 -> S64 -> S64; let _ = s64_div : S64 -> S64 -> S64; let _ = s64_abs : S64 -> S64; let _ = s64_unsigned_abs : S64 -> U64; +let _ = s64_truncate_s8 : S64 -> S8; +let _ = s64_truncate_s16 : S64 -> S16; +let _ = s64_truncate_s32 : S64 -> S32; let _ = some : fun (@A : Type) -> A -> Option A; let _ = none : fun (@A : Type) -> Option A; diff --git a/tests/succeed/primitives.snap b/tests/succeed/primitives.snap index deb8bc0f5..0c9be6fe8 100644 --- a/tests/succeed/primitives.snap +++ b/tests/succeed/primitives.snap @@ -151,6 +151,9 @@ let _ : S8 -> S8 -> S8 = s8_mul; let _ : S8 -> S8 -> S8 = s8_div; let _ : S8 -> S8 = s8_abs; let _ : S8 -> U8 = s8_unsigned_abs; +let _ : S8 -> S16 = s8_extend_s16; +let _ : S8 -> S32 = s8_extend_s32; +let _ : S8 -> S64 = s8_extend_s64; let _ : S16 -> S16 -> Bool = s16_eq; let _ : S16 -> S16 -> Bool = s16_neq; let _ : S16 -> S16 -> Bool = s16_gt; @@ -164,6 +167,9 @@ let _ : S16 -> S16 -> S16 = s16_mul; let _ : S16 -> S16 -> S16 = s16_div; let _ : S16 -> S16 = s16_abs; let _ : S16 -> U16 = s16_unsigned_abs; +let _ : S16 -> S8 = s16_truncate_s8; +let _ : S16 -> S32 = s16_extend_s32; +let _ : S16 -> S64 = s16_extend_s64; let _ : S32 -> S32 -> Bool = s32_eq; let _ : S32 -> S32 -> Bool = s32_neq; let _ : S32 -> S32 -> Bool = s32_gt; @@ -177,6 +183,9 @@ let _ : S32 -> S32 -> S32 = s32_mul; let _ : S32 -> S32 -> S32 = s32_div; let _ : S32 -> S32 = s32_abs; let _ : S32 -> U32 = s32_unsigned_abs; +let _ : S32 -> S8 = s32_truncate_s8; +let _ : S32 -> S16 = s32_truncate_s16; +let _ : S32 -> S64 = s32_extend_s64; let _ : S64 -> S64 -> Bool = s64_eq; let _ : S64 -> S64 -> Bool = s64_neq; let _ : S64 -> S64 -> Bool = s64_gt; @@ -190,6 +199,9 @@ let _ : S64 -> S64 -> S64 = s64_mul; let _ : S64 -> S64 -> S64 = s64_div; let _ : S64 -> S64 = s64_abs; let _ : S64 -> U64 = s64_unsigned_abs; +let _ : S64 -> S8 = s64_truncate_s8; +let _ : S64 -> S16 = s64_truncate_s16; +let _ : S64 -> S32 = s64_truncate_s32; let _ : fun (@A : Type) -> A -> Option A = some; let _ : fun (@A : Type) -> Option A = none; let _ : fun (@A : Type) (@B : Type) -> B -> (A -> B) -> Option A -> B =