From bc5b1abcbabfb4205c85bd4a5444d2b1887165ed Mon Sep 17 00:00:00 2001 From: rvcas Date: Thu, 2 Dec 2021 15:35:34 -0500 Subject: [PATCH] feat(Str.toNum): support decimal --- compiler/builtins/bitcode/src/dec.zig | 9 +++++++++ compiler/builtins/bitcode/src/main.zig | 1 + compiler/builtins/src/bitcode.rs | 1 + compiler/gen_llvm/src/llvm/build.rs | 2 +- compiler/test_gen/src/gen_str.rs | 22 ++++++++++++++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/compiler/builtins/bitcode/src/dec.zig b/compiler/builtins/bitcode/src/dec.zig index aad37e91a5..ca24c12641 100644 --- a/compiler/builtins/bitcode/src/dec.zig +++ b/compiler/builtins/bitcode/src/dec.zig @@ -1,5 +1,6 @@ const std = @import("std"); const str = @import("str.zig"); +const num_ = @import("num.zig"); const utils = @import("utils.zig"); const math = std.math; @@ -1052,6 +1053,14 @@ test "div: 10 / 3" { // exports +pub fn fromStr(arg: RocStr) callconv(.C) num_.NumParseResult(i128) { + if (@call(.{ .modifier = always_inline }, RocDec.fromStr, .{arg})) |dec| { + return .{ .errorcode = 0, .value = dec.num }; + } else { + return .{ .errorcode = 1, .value = 0 }; + } +} + pub fn fromF64C(arg: f64) callconv(.C) i128 { return if (@call(.{ .modifier = always_inline }, RocDec.fromF64, .{arg})) |dec| dec.num else @panic("TODO runtime exception failing convert f64 to RocDec"); } diff --git a/compiler/builtins/bitcode/src/main.zig b/compiler/builtins/bitcode/src/main.zig index a4f5b231f9..4874c244ab 100644 --- a/compiler/builtins/bitcode/src/main.zig +++ b/compiler/builtins/bitcode/src/main.zig @@ -10,6 +10,7 @@ const STR = "str"; const dec = @import("dec.zig"); comptime { + exportDecFn(dec.fromStr, "from_str"); exportDecFn(dec.fromF64C, "from_f64"); exportDecFn(dec.eqC, "eq"); exportDecFn(dec.neqC, "neq"); diff --git a/compiler/builtins/src/bitcode.rs b/compiler/builtins/src/bitcode.rs index 33adcf78a4..3056c5b052 100644 --- a/compiler/builtins/src/bitcode.rs +++ b/compiler/builtins/src/bitcode.rs @@ -302,6 +302,7 @@ pub const LIST_ANY: &str = "roc_builtins.list.any"; pub const LIST_ALL: &str = "roc_builtins.list.all"; pub const LIST_FIND_UNSAFE: &str = "roc_builtins.list.find_unsafe"; +pub const DEC_FROM_STR: &str = "roc_builtins.dec.from_str"; pub const DEC_FROM_F64: &str = "roc_builtins.dec.from_f64"; pub const DEC_EQ: &str = "roc_builtins.dec.eq"; pub const DEC_NEQ: &str = "roc_builtins.dec.neq"; diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 445545d9ce..057c6a9aba 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -5281,7 +5281,7 @@ fn run_low_level<'a, 'ctx, 'env>( Layout::Builtin(Builtin::Float(float_width)) => { &bitcode::STR_TO_FLOAT[float_width] } - Layout::Builtin(Builtin::Decimal) => bitcode::STR_TO_DECIMAL, + Layout::Builtin(Builtin::Decimal) => bitcode::DEC_FROM_STR, _ => unreachable!(), }; diff --git a/compiler/test_gen/src/gen_str.rs b/compiler/test_gen/src/gen_str.rs index 9803ff8aff..961521418e 100644 --- a/compiler/test_gen/src/gen_str.rs +++ b/compiler/test_gen/src/gen_str.rs @@ -1331,3 +1331,25 @@ fn str_to_num_float() { f64 ); } + +#[test] +#[cfg(any(feature = "gen-llvm"))] +fn str_to_num_dec() { + use roc_std::RocDec; + + assert_evals_to!( + indoc!( + r#" + x : Dec + x = 2.0 + + when Str.toNum "1.0" is + Ok n -> n + x + Err _ -> 0 + + "# + ), + RocDec::from_str("3.0").unwrap(), + RocDec + ); +}