diff --git a/crates/compiler/builtins/bitcode/src/dec.zig b/crates/compiler/builtins/bitcode/src/dec.zig index 6ac774f78e..5473bbdae8 100644 --- a/crates/compiler/builtins/bitcode/src/dec.zig +++ b/crates/compiler/builtins/bitcode/src/dec.zig @@ -226,6 +226,10 @@ pub const RocDec = extern struct { return self.num; } + pub fn fromI128(num: i128) RocDec { + return .{ .num = num }; + } + pub fn eq(self: RocDec, other: RocDec) bool { return self.num == other.num; } @@ -1475,6 +1479,10 @@ pub fn toI128(arg: RocDec) callconv(.C) i128 { return @call(.always_inline, RocDec.toI128, .{arg}); } +pub fn fromI128(arg: i128) callconv(.C) RocDec { + return @call(.always_inline, RocDec.fromI128, .{arg}); +} + pub fn eqC(arg1: RocDec, arg2: RocDec) callconv(.C) bool { return @call(.always_inline, RocDec.eq, .{ arg1, arg2 }); } diff --git a/crates/compiler/builtins/bitcode/src/main.zig b/crates/compiler/builtins/bitcode/src/main.zig index bdb26e2482..e36272b193 100644 --- a/crates/compiler/builtins/bitcode/src/main.zig +++ b/crates/compiler/builtins/bitcode/src/main.zig @@ -49,6 +49,7 @@ comptime { exportDecFn(dec.tanC, "tan"); exportDecFn(dec.toF64, "to_f64"); exportDecFn(dec.toI128, "to_i128"); + exportDecFn(dec.fromI128, "from_i128"); exportDecFn(dec.toStr, "to_str"); inline for (INTEGERS) |T| { diff --git a/crates/compiler/builtins/roc/Num.roc b/crates/compiler/builtins/roc/Num.roc index b7e6a76f01..26b70ee077 100644 --- a/crates/compiler/builtins/roc/Num.roc +++ b/crates/compiler/builtins/roc/Num.roc @@ -151,7 +151,7 @@ interface Num toF64, toF64Checked, withoutDecimalPoint, - # withDecimalPoint + withDecimalPoint ] imports [ Bool.{ Bool }, @@ -1414,4 +1414,4 @@ toF64Checked : Num * -> Result F64 [OutOfBounds] withoutDecimalPoint : Dec -> I128 ## Turns a [I128] into the coresponding [Dec], effectifely addoing the decimal point. -#withDecimalPoint : I128 -> Dec \ No newline at end of file +withDecimalPoint : I128 -> Dec \ No newline at end of file diff --git a/crates/compiler/builtins/src/bitcode.rs b/crates/compiler/builtins/src/bitcode.rs index d2e7e178e6..6204e8967a 100644 --- a/crates/compiler/builtins/src/bitcode.rs +++ b/crates/compiler/builtins/src/bitcode.rs @@ -415,6 +415,7 @@ pub const DEC_SUB_SATURATED: &str = "roc_builtins.dec.sub_saturated"; pub const DEC_SUB_WITH_OVERFLOW: &str = "roc_builtins.dec.sub_with_overflow"; pub const DEC_TAN: &str = "roc_builtins.dec.tan"; pub const DEC_TO_I128: &str = "roc_builtins.dec.to_i128"; +pub const DEC_FROM_I128: &str = "roc_builtins.dec.from_i128"; pub const DEC_TO_STR: &str = "roc_builtins.dec.to_str"; pub const DEC_ROUND: IntrinsicName = int_intrinsic!("roc_builtins.dec.round"); pub const DEC_FLOOR: IntrinsicName = int_intrinsic!("roc_builtins.dec.floor"); diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index 5eb1b38bc3..11c4452752 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -205,7 +205,8 @@ map_symbol_to_lowlevel_and_arity! { NumCountTrailingZeroBits; NUM_COUNT_TRAILING_ZERO_BITS; 1, NumCountOneBits; NUM_COUNT_ONE_BITS; 1, I128OfDec; I128_OF_DEC; 1, - DecWithoutDecimalPoint; NUM_DEC_WITHOUT_DECIMAL_POINT; 1, + NumWithoutDecimalPoint; NUM_WITHOUT_DECIMAL_POINT; 1, + NumWithDecimalPoint; NUM_WITH_DECIMAL_POINT; 1, Eq; BOOL_STRUCTURAL_EQ; 2, NotEq; BOOL_STRUCTURAL_NOT_EQ; 2, diff --git a/crates/compiler/gen_dev/src/lib.rs b/crates/compiler/gen_dev/src/lib.rs index e0029fd35d..e99516d14f 100644 --- a/crates/compiler/gen_dev/src/lib.rs +++ b/crates/compiler/gen_dev/src/lib.rs @@ -2029,11 +2029,16 @@ trait Backend<'a> { } } - LowLevel::DecWithoutDecimalPoint => { + LowLevel::NumWithoutDecimalPoint => { let intrinsic = bitcode::DEC_TO_I128.to_string(); self.build_fn_call(sym, intrinsic, args, arg_layouts, ret_layout) } + LowLevel::NumWithDecimalPoint => { + let intrinsic = bitcode::DEC_FROM_I128.to_string(); + self.build_fn_call(sym, intrinsic, args, arg_layouts, ret_layout) + } + x => todo!("low level, {:?}", x), } } diff --git a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs index 072c78b083..1a334e8a43 100644 --- a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs +++ b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs @@ -1172,9 +1172,9 @@ pub(crate) fn run_low_level<'a, 'ctx>( // which could be useful to look at when implementing this. todo!("implement checked float conversion"); } - I128OfDec | DecWithoutDecimalPoint => { - arguments!(dec); - dec_unary_op(env, bitcode::DEC_TO_I128, dec) + I128OfDec | NumWithoutDecimalPoint | NumWithDecimalPoint => { + arguments!(arg); + arg } Eq => { arguments_with_layouts!((lhs_arg, lhs_layout), (rhs_arg, rhs_layout)); diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 9225524201..601f1ce10b 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -2017,9 +2017,10 @@ impl<'a> LowLevelCall<'a> { NumToFloatChecked => { todo!("implement toF32Checked and toF64Checked"); } - I128OfDec | DecWithoutDecimalPoint => { + I128OfDec | NumWithoutDecimalPoint => { self.load_args_and_call_zig(backend, bitcode::DEC_TO_I128) } + NumWithDecimalPoint => self.load_args_and_call_zig(backend, bitcode::DEC_FROM_I128), And => { self.load_args(backend); backend.code_builder.i32_and(); diff --git a/crates/compiler/module/src/low_level.rs b/crates/compiler/module/src/low_level.rs index ef6505c56a..6733963b94 100644 --- a/crates/compiler/module/src/low_level.rs +++ b/crates/compiler/module/src/low_level.rs @@ -102,8 +102,9 @@ pub enum LowLevel { NumCountLeadingZeroBits, NumCountTrailingZeroBits, NumCountOneBits, + NumWithoutDecimalPoint, + NumWithDecimalPoint, I128OfDec, - DecWithoutDecimalPoint, Eq, NotEq, And, @@ -338,7 +339,8 @@ map_symbol_to_lowlevel! { NumCountTrailingZeroBits <= NUM_COUNT_TRAILING_ZERO_BITS; NumCountOneBits <= NUM_COUNT_ONE_BITS; I128OfDec <= I128_OF_DEC; - DecWithoutDecimalPoint <= I128_OF_DEC; + NumWithoutDecimalPoint <= NUM_WITHOUT_DECIMAL_POINT; + NumWithDecimalPoint <= NUM_WITH_DECIMAL_POINT; Eq <= BOOL_STRUCTURAL_EQ; NotEq <= BOOL_STRUCTURAL_NOT_EQ; And <= BOOL_AND; diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index c132fb59f7..69310f5e22 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -1268,7 +1268,8 @@ define_builtins! { 156 NUM_BYTES_TO_U128_LOWLEVEL: "bytesToU128Lowlevel" 157 NUM_DIV_TRUNC_UNCHECKED: "divTruncUnchecked" // traps on division by zero 158 NUM_REM_UNCHECKED: "remUnchecked" // traps on division by zero - 159 NUM_DEC_WITHOUT_DECIMAL_POINT: "withoutDecimalPoint" + 159 NUM_WITHOUT_DECIMAL_POINT: "withoutDecimalPoint" + 160 NUM_WITH_DECIMAL_POINT: "withDecimalPoint" } 4 BOOL: "Bool" => { 0 BOOL_BOOL: "Bool" exposed_type=true // the Bool.Bool type alias diff --git a/crates/compiler/mono/src/drop_specialization.rs b/crates/compiler/mono/src/drop_specialization.rs index 9a087ae20e..48579a756b 100644 --- a/crates/compiler/mono/src/drop_specialization.rs +++ b/crates/compiler/mono/src/drop_specialization.rs @@ -1593,7 +1593,7 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC { | NumCountLeadingZeroBits | NumCountTrailingZeroBits | NumCountOneBits => RC::NoRc, - I128OfDec | DecWithoutDecimalPoint => RC::NoRc, + I128OfDec | NumWithoutDecimalPoint | NumWithDecimalPoint => RC::NoRc, DictPseudoSeed => RC::NoRc, StrStartsWith | StrEndsWith => RC::NoRc, StrFromUtf8 => RC::Rc, diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index f13319678c..6c7ee70601 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -1346,7 +1346,8 @@ pub(crate) fn lowlevel_borrow_signature(op: LowLevel) -> &'static [Ownership] { | NumCountTrailingZeroBits | NumCountOneBits | I128OfDec - | DecWithoutDecimalPoint => &[IRRELEVANT], + | NumWithoutDecimalPoint + | NumWithDecimalPoint => &[IRRELEVANT], StrStartsWith | StrEndsWith => &[BORROWED, BORROWED], StrFromUtf8 => &[OWNED], StrToUtf8 => &[OWNED],