Skip to content

Commit e22cf65

Browse files
committed
Add signed integer extend/truncate prims
1 parent 059f971 commit e22cf65

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

fathom/src/core.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,9 @@ def_prims! {
509509
S8Div => "s8_div",
510510
S8Abs => "s8_abs",
511511
S8UAbs => "s8_unsigned_abs",
512+
S8ExtendS16 => "s8_extend_s16",
513+
S8ExtendS32 => "s8_extend_s32",
514+
S8ExtendS64 => "s8_extend_s64",
512515

513516
S16Eq => "s16_eq",
514517
S16Neq => "s16_neq",
@@ -523,6 +526,9 @@ def_prims! {
523526
S16Div => "s16_div",
524527
S16Abs => "s16_abs",
525528
S16UAbs => "s16_unsigned_abs",
529+
S16TruncateS8 => "s16_truncate_s8",
530+
S16ExtendS32 => "s16_extend_s32",
531+
S16ExtendS64 => "s16_extend_s64",
526532

527533
S32Eq => "s32_eq",
528534
S32Neq => "s32_neq",
@@ -537,6 +543,9 @@ def_prims! {
537543
S32Div => "s32_div",
538544
S32Abs => "s32_abs",
539545
S32UAbs => "s32_unsigned_abs",
546+
S32TruncateS8 => "s32_truncate_s8",
547+
S32TruncateS16 => "s32_truncate_s16",
548+
S32ExtendS64 => "s32_extend_s64",
540549

541550
S64Eq => "s64_eq",
542551
S64Neq => "s64_neq",
@@ -551,6 +560,9 @@ def_prims! {
551560
S64Div => "s64_div",
552561
S64Abs => "s64_abs",
553562
S64UAbs => "s64_unsigned_abs",
563+
S64TruncateS8 => "s64_truncate_s8",
564+
S64TruncateS16 => "s64_truncate_s16",
565+
S64TruncateS32 => "s64_truncate_s32",
554566

555567
OptionSome => "some",
556568
OptionNone => "none",

fathom/src/core/prim.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ impl<'arena> Env<'arena> {
265265
env.define_prim_fun(S8Div, [&S8_TYPE, &S8_TYPE], &S8_TYPE);
266266
env.define_prim_fun(S8Abs, [&S8_TYPE], &S8_TYPE);
267267
env.define_prim_fun(S8UAbs, [&S8_TYPE], &U8_TYPE);
268+
env.define_prim_fun(S8ExtendS16, [&S8_TYPE], &S16_TYPE);
269+
env.define_prim_fun(S8ExtendS32, [&S8_TYPE], &S32_TYPE);
270+
env.define_prim_fun(S8ExtendS64, [&S8_TYPE], &S64_TYPE);
268271

269272
env.define_prim_fun(S16Eq, [&S16_TYPE, &S16_TYPE], &BOOL_TYPE);
270273
env.define_prim_fun(S16Neq, [&S16_TYPE, &S16_TYPE], &BOOL_TYPE);
@@ -279,6 +282,9 @@ impl<'arena> Env<'arena> {
279282
env.define_prim_fun(S16Div, [&S16_TYPE, &S16_TYPE], &S16_TYPE);
280283
env.define_prim_fun(S16Abs, [&S16_TYPE], &S16_TYPE);
281284
env.define_prim_fun(S16UAbs, [&S16_TYPE], &U16_TYPE);
285+
env.define_prim_fun(S16TruncateS8, [&S16_TYPE], &S8_TYPE);
286+
env.define_prim_fun(S16ExtendS32, [&S16_TYPE], &S32_TYPE);
287+
env.define_prim_fun(S16ExtendS64, [&S16_TYPE], &S64_TYPE);
282288

283289
env.define_prim_fun(S32Eq, [&S32_TYPE, &S32_TYPE], &BOOL_TYPE);
284290
env.define_prim_fun(S32Neq, [&S32_TYPE, &S32_TYPE], &BOOL_TYPE);
@@ -293,6 +299,9 @@ impl<'arena> Env<'arena> {
293299
env.define_prim_fun(S32Div, [&S32_TYPE, &S32_TYPE], &S32_TYPE);
294300
env.define_prim_fun(S32Abs, [&S32_TYPE], &S32_TYPE);
295301
env.define_prim_fun(S32UAbs, [&S32_TYPE], &U32_TYPE);
302+
env.define_prim_fun(S32TruncateS8, [&S32_TYPE], &S8_TYPE);
303+
env.define_prim_fun(S32TruncateS16, [&S32_TYPE], &S16_TYPE);
304+
env.define_prim_fun(S32ExtendS64, [&S32_TYPE], &S64_TYPE);
296305

297306
env.define_prim_fun(S64Eq, [&S64_TYPE, &S64_TYPE], &BOOL_TYPE);
298307
env.define_prim_fun(S64Neq, [&S64_TYPE, &S64_TYPE], &BOOL_TYPE);
@@ -307,6 +316,9 @@ impl<'arena> Env<'arena> {
307316
env.define_prim_fun(S64Div, [&S64_TYPE, &S64_TYPE], &S64_TYPE);
308317
env.define_prim_fun(S64Abs, [&S64_TYPE], &S64_TYPE);
309318
env.define_prim_fun(S64UAbs, [&S64_TYPE], &U64_TYPE);
319+
env.define_prim_fun(S64TruncateS8, [&S64_TYPE], &S8_TYPE);
320+
env.define_prim_fun(S64TruncateS16, [&S64_TYPE], &S16_TYPE);
321+
env.define_prim_fun(S64TruncateS32, [&S64_TYPE], &S32_TYPE);
310322

311323
env.define_prim(
312324
OptionSome,
@@ -731,6 +743,9 @@ pub fn step(prim: Prim) -> Step {
731743
Prim::S8Div => const_step!([x: S8, y: S8] => Const::S8(i8::checked_div(*x, *y)?)),
732744
Prim::S8Abs => const_step!([x: S8] => Const::S8(i8::abs(*x))),
733745
Prim::S8UAbs => const_step!([x: S8] => Const::U8(i8::unsigned_abs(*x), UIntStyle::Decimal)),
746+
Prim::S8ExtendS16 => const_step!([x: S8] => Const::S16(i16::from(*x))),
747+
Prim::S8ExtendS32 => const_step!([x: S8] => Const::S32(i32::from(*x))),
748+
Prim::S8ExtendS64 => const_step!([x: S8] => Const::S64(i64::from(*x))),
734749

735750
Prim::S16Eq => const_step!([x: S16, y: S16] => Const::Bool(x == y)),
736751
Prim::S16Neq => const_step!([x: S16, y: S16] => Const::Bool(x != y)),
@@ -745,6 +760,9 @@ pub fn step(prim: Prim) -> Step {
745760
Prim::S16Div => const_step!([x: S16, y: S16] => Const::S16(i16::checked_div(*x, *y)?)),
746761
Prim::S16Abs => const_step!([x: S16] => Const::S16(i16::abs(*x))),
747762
Prim::S16UAbs => const_step!([x: S16] => Const::U16(i16::unsigned_abs(*x), UIntStyle::Decimal)),
763+
Prim::S16TruncateS8 => const_step!([x: S16] => Const::S8(*x as i8)),
764+
Prim::S16ExtendS32 => const_step!([x: S16] => Const::S32(i32::from(*x))),
765+
Prim::S16ExtendS64 => const_step!([x: S16] => Const::S64(i64::from(*x))),
748766

749767
Prim::S32Eq => const_step!([x: S32, y: S32] => Const::Bool(x == y)),
750768
Prim::S32Neq => const_step!([x: S32, y: S32] => Const::Bool(x != y)),
@@ -759,6 +777,9 @@ pub fn step(prim: Prim) -> Step {
759777
Prim::S32Div => const_step!([x: S32, y: S32] => Const::S32(i32::checked_div(*x, *y)?)),
760778
Prim::S32Abs => const_step!([x: S32] => Const::S32(i32::abs(*x))),
761779
Prim::S32UAbs => const_step!([x: S32] => Const::U32(i32::unsigned_abs(*x), UIntStyle::Decimal)),
780+
Prim::S32TruncateS8 => const_step!([x: S32] => Const::S8(*x as i8)),
781+
Prim::S32TruncateS16 => const_step!([x: S32] => Const::S16(*x as i16)),
782+
Prim::S32ExtendS64 => const_step!([x: S32] => Const::S64(i64::from(*x))),
762783

763784
Prim::S64Eq => const_step!([x: S64, y: S64] => Const::Bool(x == y)),
764785
Prim::S64Neq => const_step!([x: S64, y: S64] => Const::Bool(x != y)),
@@ -773,6 +794,9 @@ pub fn step(prim: Prim) -> Step {
773794
Prim::S64Div => const_step!([x: S64, y: S64] => Const::S64(i64::checked_div(*x, *y)?)),
774795
Prim::S64Abs => const_step!([x: S64] => Const::S64(i64::abs(*x))),
775796
Prim::S64UAbs => const_step!([x: S64] => Const::U64(i64::unsigned_abs(*x), UIntStyle::Decimal)),
797+
Prim::S64TruncateS8 => const_step!([x: S64] => Const::S8(*x as i8)),
798+
Prim::S64TruncateS16 => const_step!([x: S64] => Const::S16(*x as i16)),
799+
Prim::S64TruncateS32 => const_step!([x: S64] => Const::S32(*x as i32)),
776800

777801
Prim::OptionFold => step!(env, [_, _, on_none, on_some, option] => {
778802
match option.match_prim_spine()? {

tests/succeed/primitives.fathom

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ let _ = s8_mul : S8 -> S8 -> S8;
161161
let _ = s8_div : S8 -> S8 -> S8;
162162
let _ = s8_abs : S8 -> S8;
163163
let _ = s8_unsigned_abs : S8 -> U8;
164+
let _ = s8_extend_s16 : S8 -> S16;
165+
let _ = s8_extend_s32 : S8 -> S32;
166+
let _ = s8_extend_s64 : S8 -> S64;
164167

165168
let _ = s16_eq : S16 -> S16 -> Bool;
166169
let _ = s16_neq : S16 -> S16 -> Bool;
@@ -175,6 +178,9 @@ let _ = s16_mul : S16 -> S16 -> S16;
175178
let _ = s16_div : S16 -> S16 -> S16;
176179
let _ = s16_abs : S16 -> S16;
177180
let _ = s16_unsigned_abs : S16 -> U16;
181+
let _ = s16_truncate_s8 : S16 -> S8;
182+
let _ = s16_extend_s32 : S16 -> S32;
183+
let _ = s16_extend_s64 : S16 -> S64;
178184

179185
let _ = s32_eq : S32 -> S32 -> Bool;
180186
let _ = s32_neq : S32 -> S32 -> Bool;
@@ -189,6 +195,9 @@ let _ = s32_mul : S32 -> S32 -> S32;
189195
let _ = s32_div : S32 -> S32 -> S32;
190196
let _ = s32_abs : S32 -> S32;
191197
let _ = s32_unsigned_abs : S32 -> U32;
198+
let _ = s32_truncate_s8 : S32 -> S8;
199+
let _ = s32_truncate_s16 : S32 -> S16;
200+
let _ = s32_extend_s64 : S32 -> S64;
192201

193202
let _ = s64_eq : S64 -> S64 -> Bool;
194203
let _ = s64_neq : S64 -> S64 -> Bool;
@@ -203,6 +212,9 @@ let _ = s64_mul : S64 -> S64 -> S64;
203212
let _ = s64_div : S64 -> S64 -> S64;
204213
let _ = s64_abs : S64 -> S64;
205214
let _ = s64_unsigned_abs : S64 -> U64;
215+
let _ = s64_truncate_s8 : S64 -> S8;
216+
let _ = s64_truncate_s16 : S64 -> S16;
217+
let _ = s64_truncate_s32 : S64 -> S32;
206218

207219
let _ = some : fun (@A : Type) -> A -> Option A;
208220
let _ = none : fun (@A : Type) -> Option A;

tests/succeed/primitives.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ let _ : S8 -> S8 -> S8 = s8_mul;
151151
let _ : S8 -> S8 -> S8 = s8_div;
152152
let _ : S8 -> S8 = s8_abs;
153153
let _ : S8 -> U8 = s8_unsigned_abs;
154+
let _ : S8 -> S16 = s8_extend_s16;
155+
let _ : S8 -> S32 = s8_extend_s32;
156+
let _ : S8 -> S64 = s8_extend_s64;
154157
let _ : S16 -> S16 -> Bool = s16_eq;
155158
let _ : S16 -> S16 -> Bool = s16_neq;
156159
let _ : S16 -> S16 -> Bool = s16_gt;
@@ -164,6 +167,9 @@ let _ : S16 -> S16 -> S16 = s16_mul;
164167
let _ : S16 -> S16 -> S16 = s16_div;
165168
let _ : S16 -> S16 = s16_abs;
166169
let _ : S16 -> U16 = s16_unsigned_abs;
170+
let _ : S16 -> S8 = s16_truncate_s8;
171+
let _ : S16 -> S32 = s16_extend_s32;
172+
let _ : S16 -> S64 = s16_extend_s64;
167173
let _ : S32 -> S32 -> Bool = s32_eq;
168174
let _ : S32 -> S32 -> Bool = s32_neq;
169175
let _ : S32 -> S32 -> Bool = s32_gt;
@@ -177,6 +183,9 @@ let _ : S32 -> S32 -> S32 = s32_mul;
177183
let _ : S32 -> S32 -> S32 = s32_div;
178184
let _ : S32 -> S32 = s32_abs;
179185
let _ : S32 -> U32 = s32_unsigned_abs;
186+
let _ : S32 -> S8 = s32_truncate_s8;
187+
let _ : S32 -> S16 = s32_truncate_s16;
188+
let _ : S32 -> S64 = s32_extend_s64;
180189
let _ : S64 -> S64 -> Bool = s64_eq;
181190
let _ : S64 -> S64 -> Bool = s64_neq;
182191
let _ : S64 -> S64 -> Bool = s64_gt;
@@ -190,6 +199,9 @@ let _ : S64 -> S64 -> S64 = s64_mul;
190199
let _ : S64 -> S64 -> S64 = s64_div;
191200
let _ : S64 -> S64 = s64_abs;
192201
let _ : S64 -> U64 = s64_unsigned_abs;
202+
let _ : S64 -> S8 = s64_truncate_s8;
203+
let _ : S64 -> S16 = s64_truncate_s16;
204+
let _ : S64 -> S32 = s64_truncate_s32;
193205
let _ : fun (@A : Type) -> A -> Option A = some;
194206
let _ : fun (@A : Type) -> Option A = none;
195207
let _ : fun (@A : Type) (@B : Type) -> B -> (A -> B) -> Option A -> B =

0 commit comments

Comments
 (0)