mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
Add toF32/64 and checked versions
This commit is contained in:
parent
bd623d65bc
commit
cd00a98636
11 changed files with 108 additions and 11 deletions
|
@ -628,6 +628,15 @@ toU16 : Int * -> U16
|
|||
toU32 : Int * -> U32
|
||||
toU64 : Int * -> U64
|
||||
toU128 : Int * -> U128
|
||||
|
||||
## Convert a [Num] to a [F32]. If the given number can't be precisely represented in a [F32],
|
||||
## there will be a loss of precision.
|
||||
toF32 : Num * -> F32
|
||||
|
||||
## Convert a [Num] to a [F64]. If the given number can't be precisely represented in a [F64],
|
||||
## there will be a loss of precision.
|
||||
toF64 : Num * -> F64
|
||||
|
||||
## Convert any [Int] to a specifically-sized [Int], after checking validity.
|
||||
## These are checked bitwise operations,
|
||||
## so if the source number is outside the target range, then these will
|
||||
|
@ -643,6 +652,9 @@ toU32Checked : Int * -> Result U32 [ OutOfBounds ]*
|
|||
toU64Checked : Int * -> Result U64 [ OutOfBounds ]*
|
||||
toU128Checked : Int * -> Result U128 [ OutOfBounds ]*
|
||||
|
||||
toF32Checked : Num * -> Result F32 [ OutOfBounds ]
|
||||
toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||
|
||||
## Convert a number to a [Str].
|
||||
##
|
||||
## This is the same as calling `Num.format {}` - so for more details on
|
||||
|
@ -765,14 +777,6 @@ toU32 : Int * -> U32
|
|||
toU64 : Int * -> U64
|
||||
toU128 : Int * -> U128
|
||||
|
||||
## Convert a #Num to a #F32. If the given number can't be precisely represented in a #F32,
|
||||
## there will be a loss of precision.
|
||||
toF32 : Num * -> F32
|
||||
|
||||
## Convert a #Num to a #F64. If the given number can't be precisely represented in a #F64,
|
||||
## there will be a loss of precision.
|
||||
toF64 : Num * -> F64
|
||||
|
||||
## Convert a #Num to a #Dec. If the given number can't be precisely represented in a #Dec,
|
||||
## there will be a loss of precision.
|
||||
toDec : Num * -> Dec
|
||||
|
|
|
@ -336,6 +336,9 @@ toU32 : Int * -> U32
|
|||
toU64 : Int * -> U64
|
||||
toU128 : Int * -> U128
|
||||
|
||||
toF32 : Num * -> F32
|
||||
toF64 : Num * -> F64
|
||||
|
||||
toI8Checked : Int * -> Result I8 [ OutOfBounds ]*
|
||||
toI16Checked : Int * -> Result I16 [ OutOfBounds ]*
|
||||
toI32Checked : Int * -> Result I32 [ OutOfBounds ]*
|
||||
|
@ -346,3 +349,5 @@ toU16Checked : Int * -> Result U16 [ OutOfBounds ]*
|
|||
toU32Checked : Int * -> Result U32 [ OutOfBounds ]*
|
||||
toU64Checked : Int * -> Result U64 [ OutOfBounds ]*
|
||||
toU128Checked : Int * -> Result U128 [ OutOfBounds ]*
|
||||
toF32Checked : Num * -> Result F32 [ OutOfBounds ]*
|
||||
toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||
|
|
|
@ -615,7 +615,35 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
|||
add_top_level_function_type!(
|
||||
Symbol::NUM_TO_NAT_CHECKED,
|
||||
vec![int_type(flex(TVAR1))],
|
||||
Box::new(result_type(nat_type(), out_of_bounds)),
|
||||
Box::new(result_type(nat_type(), out_of_bounds.clone())),
|
||||
);
|
||||
|
||||
// toF32 : Num * -> F32
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_TO_F32,
|
||||
vec![num_type(flex(TVAR1))],
|
||||
Box::new(f32_type()),
|
||||
);
|
||||
|
||||
// toF32Checked : Num * -> Result F32 [ OutOfBounds ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_TO_F32_CHECKED,
|
||||
vec![num_type(flex(TVAR1))],
|
||||
Box::new(result_type(f32_type(), out_of_bounds.clone())),
|
||||
);
|
||||
|
||||
// toF64 : Num * -> F64
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_TO_F64,
|
||||
vec![num_type(flex(TVAR1))],
|
||||
Box::new(f64_type()),
|
||||
);
|
||||
|
||||
// toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_TO_F64_CHECKED,
|
||||
vec![num_type(flex(TVAR1))],
|
||||
Box::new(result_type(f64_type(), out_of_bounds)),
|
||||
);
|
||||
|
||||
// toStr : Num a -> Str
|
||||
|
|
|
@ -482,6 +482,18 @@ fn num_to_nat(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|||
lowlevel_1(symbol, LowLevel::NumIntCast, var_store)
|
||||
}
|
||||
|
||||
// Num.toF32 : Num * -> F32
|
||||
fn num_to_f32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
// Defer to NumToFloatCast
|
||||
lowlevel_1(symbol, LowLevel::NumToFloatCast, var_store)
|
||||
}
|
||||
|
||||
// Num.toF64 : Num * -> F64
|
||||
fn num_to_f64(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
// Defer to NumToFloatCast
|
||||
lowlevel_1(symbol, LowLevel::NumToFloatCast, var_store)
|
||||
}
|
||||
|
||||
fn to_num_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let num_var_1 = var_store.fresh();
|
||||
|
@ -589,6 +601,8 @@ num_to_checked! {
|
|||
num_to_u64_checked
|
||||
num_to_u128_checked
|
||||
num_to_nat_checked
|
||||
num_to_f32_checked
|
||||
num_to_f64_checked
|
||||
}
|
||||
|
||||
// Num.toStr : Num a -> Str
|
||||
|
|
|
@ -5865,6 +5865,23 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
.build_int_cast_sign_flag(arg, to, to_signed, "inc_cast")
|
||||
.into()
|
||||
}
|
||||
NumToFloatCast => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
||||
let arg = load_symbol(scope, &args[0]).into_int_value();
|
||||
|
||||
todo!("TODO if it's a float, cast; if it's an int, do either signed_int_to_float or unsigned_int_to_float; if it's Dec, panic for now");
|
||||
// let to = basic_type_from_layout(env, layout).into_int_type();
|
||||
// let to_signed = intwidth_from_layout(*layout).is_signed();
|
||||
|
||||
// env.builder
|
||||
// .build_int_cast_sign_flag(arg, to, to_signed, "inc_cast")
|
||||
// .into()
|
||||
}
|
||||
NumToFloatChecked => {
|
||||
// NOTE: For some reason there's no entry here for NumToIntChecked - why is that?
|
||||
todo!("implement checked float conversion");
|
||||
}
|
||||
Eq => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
|
|
|
@ -677,9 +677,15 @@ impl<'a> LowLevelCall<'a> {
|
|||
_ => todo!("{:?}: {:?} -> {:?}", self.lowlevel, arg_type, ret_type),
|
||||
}
|
||||
}
|
||||
NumToFloatCast => {
|
||||
todo!("implement toF32 and toF64");
|
||||
}
|
||||
NumToIntChecked => {
|
||||
todo!()
|
||||
}
|
||||
NumToFloatChecked => {
|
||||
todo!("implement toF32Checked and toF64Checked");
|
||||
}
|
||||
And => {
|
||||
self.load_args(backend);
|
||||
backend.code_builder.i32_and();
|
||||
|
|
|
@ -111,7 +111,9 @@ pub enum LowLevel {
|
|||
NumShiftRightBy,
|
||||
NumShiftRightZfBy,
|
||||
NumIntCast,
|
||||
NumToFloatCast,
|
||||
NumToIntChecked,
|
||||
NumToFloatChecked,
|
||||
NumToStr,
|
||||
Eq,
|
||||
NotEq,
|
||||
|
|
|
@ -1053,6 +1053,10 @@ define_builtins! {
|
|||
144 NUM_TO_U128_CHECKED: "toU128Checked"
|
||||
145 NUM_TO_NAT: "toNat"
|
||||
146 NUM_TO_NAT_CHECKED: "toNatChecked"
|
||||
147 NUM_TO_F32: "toF32"
|
||||
148 NUM_TO_F32_CHECKED: "toF32Checked"
|
||||
149 NUM_TO_F64: "toF64"
|
||||
150 NUM_TO_F64_CHECKED: "toF64Checked"
|
||||
}
|
||||
2 BOOL: "Bool" => {
|
||||
0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias
|
||||
|
@ -1103,7 +1107,6 @@ define_builtins! {
|
|||
32 STR_TO_I16: "toI16"
|
||||
33 STR_TO_U8: "toU8"
|
||||
34 STR_TO_I8: "toI8"
|
||||
|
||||
}
|
||||
4 LIST: "List" => {
|
||||
0 LIST_LIST: "List" imported // the List.List type alias
|
||||
|
|
|
@ -1001,7 +1001,9 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
|||
|
||||
NumToStr | NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumLogUnchecked
|
||||
| NumRound | NumCeiling | NumFloor | NumToFloat | Not | NumIsFinite | NumAtan | NumAcos
|
||||
| NumAsin | NumIntCast | NumToIntChecked => arena.alloc_slice_copy(&[irrelevant]),
|
||||
| NumAsin | NumIntCast | NumToIntChecked | NumToFloatCast | NumToFloatChecked => {
|
||||
arena.alloc_slice_copy(&[irrelevant])
|
||||
}
|
||||
NumBytesToU16 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
NumBytesToU32 => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
StrStartsWith | StrEndsWith => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||
|
|
|
@ -170,6 +170,7 @@ enum FirstOrder {
|
|||
NumBytesToU32,
|
||||
NumShiftRightZfBy,
|
||||
NumIntCast,
|
||||
NumFloatCast,
|
||||
Eq,
|
||||
NotEq,
|
||||
And,
|
||||
|
|
|
@ -5271,6 +5271,21 @@ mod solve_expr {
|
|||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_float() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
{
|
||||
toF32: Num.toF32,
|
||||
toF64: Num.toF64,
|
||||
}
|
||||
"#
|
||||
),
|
||||
r#"{ toF32 : Num * -> F32, toF64 : Num * -> F64 }"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn opaque_wrap_infer() {
|
||||
infer_eq_without_problem(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue