mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
feat: switch to using a builtin per num type to convert from a string
This commit is contained in:
parent
bc5b1abcba
commit
e587e20de2
6 changed files with 122 additions and 25 deletions
|
@ -3,9 +3,9 @@ use roc_module::ident::TagName;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
use roc_region::all::Region;
|
use roc_region::all::Region;
|
||||||
use roc_types::builtin_aliases::{
|
use roc_types::builtin_aliases::{
|
||||||
bool_type, dict_type, float_type, i128_type, int_type, list_type, nat_type, num_type,
|
bool_type, dec_type, dict_type, f32_type, f64_type, float_type, i128_type, int_type, list_type,
|
||||||
ordering_type, result_type, set_type, str_type, str_utf8_byte_problem_type, u16_type, u32_type,
|
nat_type, num_type, ordering_type, result_type, set_type, str_type, str_utf8_byte_problem_type,
|
||||||
u8_type,
|
u16_type, u32_type, u64_type, u8_type,
|
||||||
};
|
};
|
||||||
use roc_types::solved_types::SolvedType;
|
use roc_types::solved_types::SolvedType;
|
||||||
use roc_types::subs::VarId;
|
use roc_types::subs::VarId;
|
||||||
|
@ -702,16 +702,52 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||||
Box::new(list_type(u8_type()))
|
Box::new(list_type(u8_type()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// toNum : Str -> Result (Num a) {}
|
// toNum : Str -> Result (Num a) [ InvalidNumStr ]
|
||||||
let invalid_str = SolvedType::TagUnion(
|
// Because toNum doesn't work with floats & decimals by default without
|
||||||
|
// a point of usage to be able to infer the proper layout
|
||||||
|
// we decided that separate functions for each sub num type
|
||||||
|
// is the best approach. These below all end up mapping to
|
||||||
|
// `str_to_num` in can `builtins.rs`
|
||||||
|
let invalid_str = || {
|
||||||
|
SolvedType::TagUnion(
|
||||||
vec![(TagName::Global("InvalidNumStr".into()), vec![])],
|
vec![(TagName::Global("InvalidNumStr".into()), vec![])],
|
||||||
Box::new(SolvedType::Wildcard),
|
Box::new(SolvedType::Wildcard),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// toDec : Str -> Result Dec [ InvalidNumStr ]
|
||||||
|
add_top_level_function_type!(
|
||||||
|
Symbol::STR_TO_DEC,
|
||||||
|
vec![str_type()],
|
||||||
|
Box::new(result_type(dec_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// toF64 : Str -> Result F64 [ InvalidNumStr ]
|
||||||
add_top_level_function_type!(
|
add_top_level_function_type!(
|
||||||
Symbol::STR_TO_NUM,
|
Symbol::STR_TO_F64,
|
||||||
vec![str_type()],
|
vec![str_type()],
|
||||||
Box::new(result_type(num_type(flex(TVAR1)), invalid_str))
|
Box::new(result_type(f64_type(), invalid_str()))
|
||||||
|
);
|
||||||
|
|
||||||
|
// toF32 : Str -> Result F32 [ InvalidNumStr ]
|
||||||
|
add_top_level_function_type!(
|
||||||
|
Symbol::STR_TO_F32,
|
||||||
|
vec![str_type()],
|
||||||
|
Box::new(result_type(f32_type(), invalid_str()))
|
||||||
|
);
|
||||||
|
|
||||||
|
// toNat : Str -> Result Nat [ InvalidNumStr ]
|
||||||
|
add_top_level_function_type!(
|
||||||
|
Symbol::STR_TO_NAT,
|
||||||
|
vec![str_type()],
|
||||||
|
Box::new(result_type(nat_type(), invalid_str()))
|
||||||
|
);
|
||||||
|
|
||||||
|
// toU64 : Str -> Result U64 [ InvalidNumStr ]
|
||||||
|
add_top_level_function_type!(
|
||||||
|
Symbol::STR_TO_U64,
|
||||||
|
vec![str_type()],
|
||||||
|
Box::new(result_type(u64_type(), invalid_str()))
|
||||||
);
|
);
|
||||||
|
|
||||||
// List module
|
// List module
|
||||||
|
|
|
@ -68,7 +68,11 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||||
STR_TRIM => str_trim,
|
STR_TRIM => str_trim,
|
||||||
STR_TRIM_LEFT => str_trim_left,
|
STR_TRIM_LEFT => str_trim_left,
|
||||||
STR_TRIM_RIGHT => str_trim_right,
|
STR_TRIM_RIGHT => str_trim_right,
|
||||||
STR_TO_NUM => str_to_num,
|
STR_TO_DEC => str_to_num,
|
||||||
|
STR_TO_F64 => str_to_num,
|
||||||
|
STR_TO_F32 => str_to_num,
|
||||||
|
STR_TO_NAT => str_to_num,
|
||||||
|
STR_TO_U64 => str_to_num,
|
||||||
LIST_LEN => list_len,
|
LIST_LEN => list_len,
|
||||||
LIST_GET => list_get,
|
LIST_GET => list_get,
|
||||||
LIST_SET => list_set,
|
LIST_SET => list_set,
|
||||||
|
|
|
@ -195,7 +195,11 @@ impl LowLevel {
|
||||||
Symbol::STR_TRIM => Some(StrTrim),
|
Symbol::STR_TRIM => Some(StrTrim),
|
||||||
Symbol::STR_TRIM_LEFT => Some(StrTrimLeft),
|
Symbol::STR_TRIM_LEFT => Some(StrTrimLeft),
|
||||||
Symbol::STR_TRIM_RIGHT => Some(StrTrimRight),
|
Symbol::STR_TRIM_RIGHT => Some(StrTrimRight),
|
||||||
Symbol::STR_TO_NUM => Some(StrToNum),
|
Symbol::STR_TO_DEC => Some(StrToNum),
|
||||||
|
Symbol::STR_TO_F64 => Some(StrToNum),
|
||||||
|
Symbol::STR_TO_F32 => Some(StrToNum),
|
||||||
|
Symbol::STR_TO_NAT => Some(StrToNum),
|
||||||
|
Symbol::STR_TO_U64 => Some(StrToNum),
|
||||||
Symbol::LIST_LEN => Some(ListLen),
|
Symbol::LIST_LEN => Some(ListLen),
|
||||||
Symbol::LIST_GET => None,
|
Symbol::LIST_GET => None,
|
||||||
Symbol::LIST_SET => None,
|
Symbol::LIST_SET => None,
|
||||||
|
|
|
@ -1029,7 +1029,12 @@ define_builtins! {
|
||||||
18 STR_TRIM: "trim"
|
18 STR_TRIM: "trim"
|
||||||
19 STR_TRIM_LEFT: "trimLeft"
|
19 STR_TRIM_LEFT: "trimLeft"
|
||||||
20 STR_TRIM_RIGHT: "trimRight"
|
20 STR_TRIM_RIGHT: "trimRight"
|
||||||
21 STR_TO_NUM: "toNum"
|
21 STR_TO_DEC: "toDec"
|
||||||
|
22 STR_TO_F64: "toF64"
|
||||||
|
23 STR_TO_F32: "toF32"
|
||||||
|
24 STR_TO_NAT: "toNat"
|
||||||
|
25 STR_TO_U64: "toU64"
|
||||||
|
|
||||||
}
|
}
|
||||||
4 LIST: "List" => {
|
4 LIST: "List" => {
|
||||||
0 LIST_LIST: "List" imported // the List.List type alias
|
0 LIST_LIST: "List" imported // the List.List type alias
|
||||||
|
|
|
@ -1300,56 +1300,53 @@ fn str_trim_right_small_to_small_shared() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn str_to_num() {
|
fn str_to_nat() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.toNum "1" is
|
when Str.toNat "1" is
|
||||||
Ok n -> n
|
Ok n -> n
|
||||||
Err _ -> 0
|
Err _ -> 0
|
||||||
|
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
1,
|
1,
|
||||||
i64
|
usize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn str_to_num_float() {
|
fn str_to_f64() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
when Str.toNum "1.0" is
|
when Str.toF64 "1.0" is
|
||||||
Ok n -> n + 2.0
|
Ok n -> n
|
||||||
Err _ -> 0
|
Err _ -> 0
|
||||||
|
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
3.0,
|
1.0,
|
||||||
f64
|
f64
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm"))]
|
#[cfg(any(feature = "gen-llvm"))]
|
||||||
fn str_to_num_dec() {
|
fn str_to_dec() {
|
||||||
use roc_std::RocDec;
|
use roc_std::RocDec;
|
||||||
|
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
r#"
|
r#"
|
||||||
x : Dec
|
when Str.toDec "1.0" is
|
||||||
x = 2.0
|
|
||||||
|
|
||||||
when Str.toNum "1.0" is
|
|
||||||
Ok n -> n + x
|
Ok n -> n + x
|
||||||
Err _ -> 0
|
Err _ -> 0
|
||||||
|
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
RocDec::from_str("3.0").unwrap(),
|
RocDec::from_str("1.0").unwrap(),
|
||||||
RocDec
|
RocDec
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,6 +409,40 @@ fn float_alias_content(range: SolvedType) -> SolvedType {
|
||||||
num_type(floatingpoint_type(range))
|
num_type(floatingpoint_type(range))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// F64
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn f64_type() -> SolvedType {
|
||||||
|
SolvedType::Alias(
|
||||||
|
Symbol::NUM_F64,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
Box::new(f64_alias_content()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn f64_alias_content() -> SolvedType {
|
||||||
|
float_alias_content(binary64_type())
|
||||||
|
}
|
||||||
|
|
||||||
|
// F32
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn f32_type() -> SolvedType {
|
||||||
|
SolvedType::Alias(
|
||||||
|
Symbol::NUM_F32,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
Box::new(f32_alias_content()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn f32_alias_content() -> SolvedType {
|
||||||
|
float_alias_content(binary32_type())
|
||||||
|
}
|
||||||
|
|
||||||
// Nat
|
// Nat
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -731,6 +765,23 @@ fn decimal_alias_content() -> SolvedType {
|
||||||
single_private_tag(Symbol::NUM_AT_DECIMAL, vec![])
|
single_private_tag(Symbol::NUM_AT_DECIMAL, vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dec
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn dec_type() -> SolvedType {
|
||||||
|
SolvedType::Alias(
|
||||||
|
Symbol::NUM_DEC,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
Box::new(dec_alias_content()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn dec_alias_content() -> SolvedType {
|
||||||
|
float_alias_content(decimal_type())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn decimal_type() -> SolvedType {
|
pub fn decimal_type() -> SolvedType {
|
||||||
SolvedType::Alias(
|
SolvedType::Alias(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue