mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 16:30:04 +03:00
Add Num.(min/max)(I/U)(8/16)
builtins
This commit is contained in:
parent
38f0a3717f
commit
9a8a4c6ed7
@ -62,12 +62,20 @@ interface Num
|
||||
isZero,
|
||||
log,
|
||||
maxFloat,
|
||||
maxI8,
|
||||
maxU8,
|
||||
maxI16,
|
||||
maxU16,
|
||||
maxI32,
|
||||
maxU32,
|
||||
maxI64,
|
||||
maxU64,
|
||||
maxI128,
|
||||
minFloat,
|
||||
minI8,
|
||||
minU8,
|
||||
minI16,
|
||||
minU16,
|
||||
minI32,
|
||||
minU32,
|
||||
minI64,
|
||||
@ -791,6 +799,72 @@ minNat : Nat
|
||||
## 32-bit system, this will be equal to #Num.maxU32.
|
||||
maxNat : Nat
|
||||
|
||||
## The lowest number that can be stored in an #I8 without underflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is `-128`.
|
||||
##
|
||||
## Note that the positive version of this number is larger than #Int.maxI8,
|
||||
## which means if you call #Num.abs on #Int.minI8, it will overflow and crash!
|
||||
minI8 : I8
|
||||
|
||||
## The highest number that can be stored in an #I8 without overflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is `127`.
|
||||
##
|
||||
## Note that this is smaller than the positive version of #Int.minI8,
|
||||
## which means if you call #Num.abs on #Int.minI8, it will overflow and crash!
|
||||
maxI8 : I8
|
||||
|
||||
## The lowest number that can be stored in a #U8 without underflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is zero, because #U8 is
|
||||
## [unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
|
||||
## and zero is the lowest unsigned number.
|
||||
## Unsigned numbers cannot be negative.
|
||||
minU8 : U8
|
||||
|
||||
## The highest number that can be stored in a #U8 without overflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is `255`.
|
||||
maxU8 : U8
|
||||
|
||||
## The lowest number that can be stored in an #I16 without underflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is `-32_768`.
|
||||
##
|
||||
## Note that the positive version of this number is larger than #Int.maxI16,
|
||||
## which means if you call #Num.abs on #Int.minI16, it will overflow and crash!
|
||||
minI16 : I16
|
||||
|
||||
## The highest number that can be stored in an #I16 without overflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is `32_767`.
|
||||
##
|
||||
## Note that this is smaller than the positive version of #Int.minI16,
|
||||
## which means if you call #Num.abs on #Int.minI16, it will overflow and crash!
|
||||
maxI16 : I16
|
||||
|
||||
## The lowest number that can be stored in a #U16 without underflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is zero, because #U16 is
|
||||
## [unsigned](https://en.wikipedia.org/wiki/Signed_number_representations),
|
||||
## and zero is the lowest unsigned number.
|
||||
## Unsigned numbers cannot be negative.
|
||||
minU16 : U16
|
||||
|
||||
## The highest number that can be stored in a #U16 without overflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
## For reference, this number is `65_535`.
|
||||
maxU16 : U16
|
||||
|
||||
## The lowest number that can be stored in an #I32 without underflowing its
|
||||
## available memory and crashing.
|
||||
##
|
||||
|
@ -391,6 +391,30 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||
Box::new(bool_type()),
|
||||
);
|
||||
|
||||
// minI8 : I8
|
||||
add_type!(Symbol::NUM_MIN_I8, i8_type());
|
||||
|
||||
// maxI8 : I8
|
||||
add_type!(Symbol::NUM_MAX_I8, i8_type());
|
||||
|
||||
// minU8 : U8
|
||||
add_type!(Symbol::NUM_MIN_U8, u8_type());
|
||||
|
||||
// maxU8 : U8
|
||||
add_type!(Symbol::NUM_MAX_U8, u8_type());
|
||||
|
||||
// minI16 : I16
|
||||
add_type!(Symbol::NUM_MIN_I16, i16_type());
|
||||
|
||||
// maxI16 : I16
|
||||
add_type!(Symbol::NUM_MAX_I16, i16_type());
|
||||
|
||||
// minU16 : U16
|
||||
add_type!(Symbol::NUM_MIN_U16, u16_type());
|
||||
|
||||
// maxU16 : U16
|
||||
add_type!(Symbol::NUM_MAX_U16, u16_type());
|
||||
|
||||
// minI32 : I32
|
||||
add_type!(Symbol::NUM_MIN_I32, i32_type());
|
||||
|
||||
|
@ -223,6 +223,14 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||
NUM_SHIFT_RIGHT => num_shift_right_by,
|
||||
NUM_SHIFT_RIGHT_ZERO_FILL => num_shift_right_zf_by,
|
||||
NUM_INT_CAST=> num_int_cast,
|
||||
NUM_MIN_I8=> num_min_i8,
|
||||
NUM_MAX_I8=> num_max_i8,
|
||||
NUM_MIN_U8=> num_min_u8,
|
||||
NUM_MAX_U8=> num_max_u8,
|
||||
NUM_MIN_I16=> num_min_i16,
|
||||
NUM_MAX_I16=> num_max_i16,
|
||||
NUM_MIN_U16=> num_min_u16,
|
||||
NUM_MAX_U16=> num_max_u16,
|
||||
NUM_MIN_I32=> num_min_i32,
|
||||
NUM_MAX_I32=> num_max_i32,
|
||||
NUM_MIN_U32=> num_min_u32,
|
||||
@ -1236,56 +1244,94 @@ fn num_int_cast(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_1(symbol, LowLevel::NumIntCast, var_store)
|
||||
}
|
||||
|
||||
/// Num.minI8: I8
|
||||
fn num_min_i8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i8>(symbol, var_store, i8::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxI8: I8
|
||||
fn num_max_i8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i8>(symbol, var_store, i8::MAX)
|
||||
}
|
||||
|
||||
/// Num.minU8: U8
|
||||
fn num_min_u8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u8>(symbol, var_store, u8::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxU8: U8
|
||||
fn num_max_u8(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u8>(symbol, var_store, u8::MAX)
|
||||
}
|
||||
|
||||
/// Num.minI16: I16
|
||||
fn num_min_i16(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i16>(symbol, var_store, i16::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxI16: I16
|
||||
fn num_max_i16(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i16>(symbol, var_store, i16::MAX)
|
||||
}
|
||||
|
||||
/// Num.minU16: U16
|
||||
fn num_min_u16(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u16>(symbol, var_store, u16::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxU16: U16
|
||||
fn num_max_u16(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u16>(symbol, var_store, u16::MAX)
|
||||
}
|
||||
|
||||
/// Num.minI32: I32
|
||||
fn num_min_i32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i32>(symbol, var_store, i32::MIN);
|
||||
int_min_or_max::<i32>(symbol, var_store, i32::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxI32: I32
|
||||
fn num_max_i32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i32>(symbol, var_store, i32::MAX);
|
||||
int_min_or_max::<i32>(symbol, var_store, i32::MAX)
|
||||
}
|
||||
|
||||
/// Num.minU32: U32
|
||||
fn num_min_u32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u32>(symbol, var_store, u32::MIN);
|
||||
int_min_or_max::<u32>(symbol, var_store, u32::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxU32: U32
|
||||
fn num_max_u32(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u32>(symbol, var_store, u32::MAX);
|
||||
int_min_or_max::<u32>(symbol, var_store, u32::MAX)
|
||||
}
|
||||
|
||||
/// Num.minI64: I64
|
||||
fn num_min_i64(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i64>(symbol, var_store, i64::MIN);
|
||||
int_min_or_max::<i64>(symbol, var_store, i64::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxI64: I64
|
||||
fn num_max_i64(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i64>(symbol, var_store, i64::MAX);
|
||||
int_min_or_max::<i64>(symbol, var_store, i64::MAX)
|
||||
}
|
||||
|
||||
/// Num.minU64: U64
|
||||
fn num_min_u64(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u64>(symbol, var_store, u64::MIN);
|
||||
int_min_or_max::<u64>(symbol, var_store, u64::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxU64: U64
|
||||
fn num_max_u64(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<u64>(symbol, var_store, iu64::MAX);
|
||||
int_min_or_max::<u64>(symbol, var_store, u64::MAX)
|
||||
}
|
||||
|
||||
/// Num.minI128: I128
|
||||
fn num_min_i128(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i128>(symbol, var_store, i128::MIN);
|
||||
pattern_vars: SendMap::default(),
|
||||
}
|
||||
int_min_or_max::<i128>(symbol, var_store, i128::MIN)
|
||||
}
|
||||
|
||||
/// Num.maxI128: I128
|
||||
fn num_max_i128(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
int_min_or_max::<i128>(symbol, var_store, i128::MIN);
|
||||
int_min_or_max::<i128>(symbol, var_store, i128::MAX)
|
||||
}
|
||||
|
||||
/// List.isEmpty : List * -> Bool
|
||||
|
@ -1002,6 +1002,14 @@ define_builtins! {
|
||||
114 NUM_MAX_I64: "maxI64"
|
||||
115 NUM_MIN_U64: "minU64"
|
||||
116 NUM_MAX_U64: "maxU64"
|
||||
117 NUM_MIN_I8: "minI8"
|
||||
118 NUM_MAX_I8: "maxI8"
|
||||
119 NUM_MIN_U8: "minU8"
|
||||
120 NUM_MAX_U8: "maxU8"
|
||||
121 NUM_MIN_I16: "minI16"
|
||||
122 NUM_MAX_I16: "maxI16"
|
||||
123 NUM_MIN_U16: "minU16"
|
||||
124 NUM_MAX_U16: "maxU16"
|
||||
}
|
||||
2 BOOL: "Bool" => {
|
||||
0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias
|
||||
|
@ -1941,6 +1941,118 @@ fn max_u32() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn min_i16() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.minI16
|
||||
"#
|
||||
),
|
||||
i16::MIN,
|
||||
i16
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn max_i16() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.maxI16
|
||||
"#
|
||||
),
|
||||
i16::MAX,
|
||||
i16
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn min_u16() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.minU16
|
||||
"#
|
||||
),
|
||||
u16::MIN,
|
||||
u16
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn max_u16() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.maxU16
|
||||
"#
|
||||
),
|
||||
u16::MAX,
|
||||
u16
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn min_i8() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.minI8
|
||||
"#
|
||||
),
|
||||
i8::MIN,
|
||||
i8
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn max_i8() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.maxI8
|
||||
"#
|
||||
),
|
||||
i8::MAX,
|
||||
i8
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn min_u8() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.minU8
|
||||
"#
|
||||
),
|
||||
u8::MIN,
|
||||
u8
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||
fn max_u8() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.maxU8
|
||||
"#
|
||||
),
|
||||
u8::MAX,
|
||||
u8
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn is_multiple_of() {
|
||||
|
Loading…
Reference in New Issue
Block a user