Merge pull request #2354 from rtfeldman/add_builtin_Num.minI128

Add `Num.minI128` builtin
This commit is contained in:
Richard Feldman 2022-01-16 22:38:27 -05:00 committed by GitHub
commit 2ade76b373
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 80 additions and 0 deletions

View file

@ -65,6 +65,7 @@ interface Num
maxI128, maxI128,
maxInt, maxInt,
minFloat, minFloat,
minI128,
minInt, minInt,
modInt, modInt,
modFloat, modFloat,
@ -822,6 +823,25 @@ maxU32 : U32
## and zero is the lowest unsigned number. Unsigned numbers cannot be negative. ## and zero is the lowest unsigned number. Unsigned numbers cannot be negative.
minU32 : U32 minU32 : U32
## The highest number that can be stored in an #I128 without overflowing its
## available memory and crashing.
##
## For reference, this number is `170_141_183_460_469_231_731_687_303_715_884_105_727`,
## which is over 2 million.
##
## Note that this is smaller than the positive version of #Int.minI128,
## which means if you call #Num.abs on #Int.minI128, it will overflow and crash!
maxI128 : I128
## The min number that can be stored in an #I128 without underflowing its
## available memory and crashing.
##
## For reference, this number is `-170_141_183_460_469_231_731_687_303_715_884_105_728`.
##
## Note that the positive version of this number is larger than #Int.maxI128,
## which means if you call #Num.abs on #Int.minI128, it will overflow and crash!
minI128 : I128
## The highest supported #F64 value you can have, which is approximately 1.8 × 10^308. ## The highest supported #F64 value you can have, which is approximately 1.8 × 10^308.
## ##
## If you go higher than this, your running Roc code will crash - so be careful not to! ## If you go higher than this, your running Roc code will crash - so be careful not to!

View file

@ -397,6 +397,9 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
Box::new(bool_type()), Box::new(bool_type()),
); );
// minI128 : I128
add_type!(Symbol::NUM_MIN_I128, i128_type());
// maxI128 : I128 // maxI128 : I128
add_type!(Symbol::NUM_MAX_I128, i128_type()); add_type!(Symbol::NUM_MAX_I128, i128_type());

View file

@ -206,6 +206,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
NUM_SHIFT_RIGHT => num_shift_right_by, NUM_SHIFT_RIGHT => num_shift_right_by,
NUM_SHIFT_RIGHT_ZERO_FILL => num_shift_right_zf_by, NUM_SHIFT_RIGHT_ZERO_FILL => num_shift_right_zf_by,
NUM_INT_CAST=> num_int_cast, NUM_INT_CAST=> num_int_cast,
NUM_MIN_I128=> num_min_i128,
NUM_MAX_I128=> num_max_i128, NUM_MAX_I128=> num_max_i128,
NUM_TO_STR => num_to_str, NUM_TO_STR => num_to_str,
RESULT_MAP => result_map, RESULT_MAP => result_map,
@ -1237,6 +1238,35 @@ fn num_int_cast(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_1(symbol, LowLevel::NumIntCast, var_store) lowlevel_1(symbol, LowLevel::NumIntCast, var_store)
} }
/// Num.minI128: I128
fn num_min_i128(symbol: Symbol, var_store: &mut VarStore) -> Def {
let int_var = var_store.fresh();
let int_precision_var = var_store.fresh();
// TODO: or `i128::MIN.into()` ?
let body = int(int_var, int_precision_var, i128::MIN);
let std = roc_builtins::std::types();
let solved = std.get(&symbol).unwrap();
let mut free_vars = roc_types::solved_types::FreeVars::default();
let signature = roc_types::solved_types::to_type(&solved.0, &mut free_vars, var_store);
let annotation = crate::def::Annotation {
signature,
introduced_variables: Default::default(),
region: Region::zero(),
aliases: Default::default(),
};
Def {
// TODO: or `None` ?
annotation: Some(annotation),
expr_var: int_var,
loc_expr: Loc::at_zero(body),
loc_pattern: Loc::at_zero(Pattern::Identifier(symbol)),
pattern_vars: SendMap::default(),
}
}
/// Num.maxI128: I128 /// Num.maxI128: I128
fn num_max_i128(symbol: Symbol, var_store: &mut VarStore) -> Def { fn num_max_i128(symbol: Symbol, var_store: &mut VarStore) -> Def {
let int_var = var_store.fresh(); let int_var = var_store.fresh();

View file

@ -995,6 +995,7 @@ define_builtins! {
107 NUM_CAST_TO_NAT: "#castToNat" 107 NUM_CAST_TO_NAT: "#castToNat"
108 NUM_DIV_CEIL: "divCeil" 108 NUM_DIV_CEIL: "divCeil"
109 NUM_TO_STR: "toStr" 109 NUM_TO_STR: "toStr"
110 NUM_MIN_I128: "minI128"
} }
2 BOOL: "Bool" => { 2 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias 0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias

View file

@ -3341,6 +3341,18 @@ mod solve_expr {
); );
} }
#[test]
fn min_i128() {
infer_eq_without_problem(
indoc!(
r#"
Num.minI128
"#
),
"I128",
);
}
#[test] #[test]
fn max_i128() { fn max_i128() {
infer_eq_without_problem( infer_eq_without_problem(

View file

@ -1829,6 +1829,20 @@ fn shift_right_zf_by() {
assert_evals_to!("Num.shiftRightBy 3 0b0000_1100u8", 0b0000_0011, i64); assert_evals_to!("Num.shiftRightBy 3 0b0000_1100u8", 0b0000_0011, i64);
} }
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn min_i128() {
assert_evals_to!(
indoc!(
r#"
Num.minI128
"#
),
i128::MIN,
i128
);
}
#[test] #[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))] #[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn max_i128() { fn max_i128() {