mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 10:02:38 +03:00
rem, sqrt, log are unchecked but have checked variants
mod exists but is not implemented due to lack of hardware support (emulation, possibly in terms of rem, is needed).
This commit is contained in:
parent
d23d5f249f
commit
1908ff41c3
@ -61,6 +61,7 @@ interface Num
|
||||
isPositive,
|
||||
isZero,
|
||||
log,
|
||||
logChecked,
|
||||
maxFloat,
|
||||
maxI8,
|
||||
maxU8,
|
||||
@ -81,8 +82,8 @@ interface Num
|
||||
minI64,
|
||||
minU64,
|
||||
minI128,
|
||||
modInt,
|
||||
modFloat,
|
||||
mod,
|
||||
modChecked,
|
||||
mul,
|
||||
mulChecked,
|
||||
mulWrap,
|
||||
@ -90,6 +91,7 @@ interface Num
|
||||
pow,
|
||||
powInt,
|
||||
rem,
|
||||
remChecked,
|
||||
round,
|
||||
shiftLeftBy,
|
||||
shiftRightBy,
|
||||
@ -99,6 +101,7 @@ interface Num
|
||||
subChecked,
|
||||
subWrap,
|
||||
sqrt,
|
||||
sqrtChecked,
|
||||
tan,
|
||||
toI8,
|
||||
toI8Checked,
|
||||
@ -1316,7 +1319,7 @@ isInfinite : Float * -> Bool
|
||||
##
|
||||
## >>> Num.isNaN 12.3
|
||||
##
|
||||
## >>> Num.isNaN (Num.sqrt -2)
|
||||
## >>> Num.isNaN (Num.pow -1 0.5)
|
||||
##
|
||||
## *NaN* is unusual from other numberic values in that:
|
||||
## * *NaN* is not equal to any other number, even itself. [Bool.isEq] always returns `False` if either argument is *NaN*.
|
||||
|
@ -68,12 +68,15 @@ interface Num
|
||||
isPositive,
|
||||
isNegative,
|
||||
rem,
|
||||
remChecked,
|
||||
div,
|
||||
divChecked,
|
||||
modInt,
|
||||
modFloat,
|
||||
mod,
|
||||
modChecked,
|
||||
sqrt,
|
||||
sqrtChecked,
|
||||
log,
|
||||
logChecked,
|
||||
round,
|
||||
ceiling,
|
||||
floor,
|
||||
@ -230,19 +233,23 @@ asin : Float a -> Float a
|
||||
acos : Float a -> Float a
|
||||
atan : Float a -> Float a
|
||||
|
||||
sqrt : Float a -> Result (Float a) [ SqrtOfNegative ]*
|
||||
log : Float a -> Result (Float a) [ LogNeedsPositive ]*
|
||||
sqrt : Float a -> Float a
|
||||
sqrtChecked : Float a -> Result (Float a) [ SqrtOfNegative ]*
|
||||
log : Float a -> Float a
|
||||
logChecked : Float a -> Result (Float a) [ LogNeedsPositive ]*
|
||||
|
||||
div : Float a, Float a -> Float a
|
||||
divChecked : Float a, Float a -> Result (Float a) [ DivByZero ]*
|
||||
|
||||
divCeil : Int a, Int a -> Int a
|
||||
divCeilChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
divFloor : Int a, Int a -> Int a
|
||||
divFloorChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
# mod : Float a, Float a -> Result (Float a) [ DivByZero ]*
|
||||
|
||||
rem : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
# mod : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
rem : Int a, Int a -> Int a
|
||||
remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
mod : Int a, Int a -> Int a
|
||||
modChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
|
||||
isMultipleOf : Int a, Int a -> Bool
|
||||
|
||||
bitwiseAnd : Int a, Int a -> Int a
|
||||
|
@ -393,16 +393,30 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||
Box::new(int_type(flex(TVAR2)))
|
||||
);
|
||||
|
||||
// rem : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
// rem : Int a, Int a -> Int a
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_REM,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(int_type(flex(TVAR1))),
|
||||
);
|
||||
|
||||
// remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_REM_CHECKED,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())),
|
||||
);
|
||||
|
||||
// mod : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
// mod : Int a, Int a -> Int a
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_MOD_INT,
|
||||
Symbol::NUM_MOD,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(int_type(flex(TVAR1))),
|
||||
);
|
||||
|
||||
// modChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_MOD_CHECKED,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())),
|
||||
);
|
||||
@ -680,36 +694,43 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_DIV_FLOAT_CHECKED,
|
||||
vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))],
|
||||
Box::new(result_type(float_type(flex(TVAR1)), div_by_zero.clone())),
|
||||
);
|
||||
|
||||
// mod : Float a, Float a -> Result (Float a) [ DivByZero ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_MOD_FLOAT,
|
||||
vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))],
|
||||
Box::new(result_type(float_type(flex(TVAR1)), div_by_zero)),
|
||||
);
|
||||
|
||||
// sqrt : Float a -> Float a
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_SQRT,
|
||||
vec![float_type(flex(TVAR1))],
|
||||
Box::new(float_type(flex(TVAR1))),
|
||||
);
|
||||
|
||||
// sqrtChecked : Float a -> Result (Float a) [ SqrtOfNegative ]*
|
||||
let sqrt_of_negative = SolvedType::TagUnion(
|
||||
vec![(TagName::Global("SqrtOfNegative".into()), vec![])],
|
||||
Box::new(SolvedType::Wildcard),
|
||||
);
|
||||
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_SQRT,
|
||||
Symbol::NUM_SQRT_CHECKED,
|
||||
vec![float_type(flex(TVAR1))],
|
||||
Box::new(result_type(float_type(flex(TVAR1)), sqrt_of_negative)),
|
||||
);
|
||||
|
||||
// log : Float a -> Float a
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_LOG,
|
||||
vec![float_type(flex(TVAR1))],
|
||||
Box::new(float_type(flex(TVAR1))),
|
||||
);
|
||||
|
||||
// logChecked : Float a -> Result (Float a) [ LogNeedsPositive ]*
|
||||
let log_needs_positive = SolvedType::TagUnion(
|
||||
vec![(TagName::Global("LogNeedsPositive".into()), vec![])],
|
||||
Box::new(SolvedType::Wildcard),
|
||||
);
|
||||
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_LOG,
|
||||
Symbol::NUM_LOG_CHECKED,
|
||||
vec![float_type(flex(TVAR1))],
|
||||
Box::new(result_type(float_type(flex(TVAR1)), log_needs_positive)),
|
||||
);
|
||||
|
@ -203,9 +203,14 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||
NUM_ABS => num_abs,
|
||||
NUM_NEG => num_neg,
|
||||
NUM_REM => num_rem,
|
||||
NUM_REM_CHECKED => num_rem_checked,
|
||||
NUM_MOD => num_mod,
|
||||
NUM_MOD_CHECKED => num_mod_checked,
|
||||
NUM_IS_MULTIPLE_OF => num_is_multiple_of,
|
||||
NUM_SQRT => num_sqrt,
|
||||
NUM_SQRT_CHECKED => num_sqrt_checked,
|
||||
NUM_LOG => num_log,
|
||||
NUM_LOG_CHECKED => num_log_checked,
|
||||
NUM_ROUND => num_round,
|
||||
NUM_IS_ODD => num_is_odd,
|
||||
NUM_IS_EVEN => num_is_even,
|
||||
@ -730,6 +735,23 @@ fn bool_and(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
fn num_unaryop(symbol: Symbol, var_store: &mut VarStore, op: LowLevel) -> Def {
|
||||
let num_var = var_store.fresh();
|
||||
let body = RunLowLevel {
|
||||
op,
|
||||
args: vec![(num_var, Var(Symbol::ARG_1))],
|
||||
ret_var: num_var,
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(num_var, Symbol::ARG_1)],
|
||||
var_store,
|
||||
body,
|
||||
num_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// Num a, Num a -> Num a
|
||||
fn num_binop(symbol: Symbol, var_store: &mut VarStore, op: LowLevel) -> Def {
|
||||
let num_var = var_store.fresh();
|
||||
@ -1169,8 +1191,13 @@ fn num_to_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.sqrt : Float -> Result Float [ SqrtOfNegative ]*
|
||||
/// Num.sqrt : Float a -> Float a
|
||||
fn num_sqrt(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_unaryop(symbol, var_store, LowLevel::NumSqrtUnchecked)
|
||||
}
|
||||
|
||||
/// Num.sqrtChecked : Float a -> Result (Float a) [ SqrtOfNegative ]*
|
||||
fn num_sqrt_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let float_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
@ -1218,8 +1245,13 @@ fn num_sqrt(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.log : Float -> Result Float [ LogNeedsPositive ]*
|
||||
/// Num.log : Float a -> Float a
|
||||
fn num_log(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_unaryop(symbol, var_store, LowLevel::NumLogUnchecked)
|
||||
}
|
||||
|
||||
/// Num.logChecked : Float a -> Result (Float a) [ LogNeedsPositive ]*
|
||||
fn num_log_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let float_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
@ -4196,8 +4228,13 @@ fn set_walk(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.rem : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
/// Num.rem : Int a, Int a -> Int a
|
||||
fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_binop(symbol, var_store, LowLevel::NumRemUnchecked)
|
||||
}
|
||||
|
||||
/// Num.remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
fn num_rem_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let num_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
let bool_var = var_store.fresh();
|
||||
@ -4255,6 +4292,70 @@ fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.mod : Int a, Int a -> Int a
|
||||
fn num_mod(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_binop(symbol, var_store, LowLevel::NumModUnchecked)
|
||||
}
|
||||
|
||||
/// Num.modChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
fn num_mod_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let num_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
let bool_var = var_store.fresh();
|
||||
let ret_var = var_store.fresh();
|
||||
|
||||
let body = If {
|
||||
branch_var: ret_var,
|
||||
cond_var: bool_var,
|
||||
branches: vec![(
|
||||
// if condition
|
||||
no_region(
|
||||
// Num.isNeq arg2 0
|
||||
RunLowLevel {
|
||||
op: LowLevel::NotEq,
|
||||
args: vec![
|
||||
(num_var, Var(Symbol::ARG_2)),
|
||||
(num_var, num(unbound_zero_var, 0, num_no_bound())),
|
||||
],
|
||||
ret_var: bool_var,
|
||||
},
|
||||
),
|
||||
// arg1 was not zero
|
||||
no_region(
|
||||
// Ok (Int.#modUnsafe arg1 arg2)
|
||||
tag(
|
||||
"Ok",
|
||||
vec![
|
||||
// Num.#modUnsafe arg1 arg2
|
||||
RunLowLevel {
|
||||
op: LowLevel::NumModUnchecked,
|
||||
args: vec![
|
||||
(num_var, Var(Symbol::ARG_1)),
|
||||
(num_var, Var(Symbol::ARG_2)),
|
||||
],
|
||||
ret_var: num_var,
|
||||
},
|
||||
],
|
||||
var_store,
|
||||
),
|
||||
),
|
||||
)],
|
||||
final_else: Box::new(no_region(tag(
|
||||
"Err",
|
||||
vec![tag("DivByZero", Vec::new(), var_store)],
|
||||
var_store,
|
||||
))),
|
||||
};
|
||||
|
||||
defn(
|
||||
symbol,
|
||||
vec![(num_var, Symbol::ARG_1), (num_var, Symbol::ARG_2)],
|
||||
var_store,
|
||||
body,
|
||||
ret_var,
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.isMultipleOf : Int a, Int a -> Bool
|
||||
fn num_is_multiple_of(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
lowlevel_2(symbol, LowLevel::NumIsMultipleOf, var_store)
|
||||
|
@ -5814,9 +5814,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||
}
|
||||
|
||||
NumAdd | NumSub | NumMul | NumLt | NumLte | NumGt | NumGte | NumRemUnchecked
|
||||
| NumIsMultipleOf | NumAddWrap | NumAddChecked | NumAddSaturated | NumDivUnchecked
|
||||
| NumDivCeilUnchecked | NumPow | NumPowInt | NumSubWrap | NumSubChecked
|
||||
| NumSubSaturated | NumMulWrap | NumMulChecked => {
|
||||
| NumModUnchecked | NumIsMultipleOf | NumAddWrap | NumAddChecked | NumAddSaturated
|
||||
| NumDivUnchecked | NumDivCeilUnchecked | NumPow | NumPowInt | NumSubWrap
|
||||
| NumSubChecked | NumSubSaturated | NumMulWrap | NumMulChecked => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
||||
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
@ -6578,6 +6578,11 @@ fn build_int_binop<'a, 'ctx, 'env>(
|
||||
bd.build_int_unsigned_rem(lhs, rhs, "rem_uint").into()
|
||||
}
|
||||
}
|
||||
NumModUnchecked => {
|
||||
// there generally is not hardware support for flooring mod;
|
||||
// it could probably be implemented in pure Roc in terms of Num.rem.
|
||||
todo!("mod is not implemented")
|
||||
}
|
||||
NumIsMultipleOf => {
|
||||
// this builds the following construct
|
||||
//
|
||||
@ -6908,7 +6913,6 @@ fn build_float_binop<'a, 'ctx, 'env>(
|
||||
NumGte => bd.build_float_compare(OGE, lhs, rhs, "float_gte").into(),
|
||||
NumLt => bd.build_float_compare(OLT, lhs, rhs, "float_lt").into(),
|
||||
NumLte => bd.build_float_compare(OLE, lhs, rhs, "float_lte").into(),
|
||||
NumRemUnchecked => bd.build_float_rem(lhs, rhs, "rem_float").into(),
|
||||
NumDivUnchecked => bd.build_float_div(lhs, rhs, "div_float").into(),
|
||||
NumPow => env.call_intrinsic(&LLVM_POW[float_width], &[lhs.into(), rhs.into()]),
|
||||
_ => {
|
||||
|
@ -434,6 +434,11 @@ impl<'a> LowLevelCall<'a> {
|
||||
_ => todo!("{:?} for {:?}", self.lowlevel, self.ret_layout),
|
||||
}
|
||||
}
|
||||
NumModUnchecked => {
|
||||
// wasm does not provide a flooring modulo instruction,
|
||||
// so it would need to be emulated.
|
||||
todo!("{:?}", self.lowlevel)
|
||||
}
|
||||
NumIsMultipleOf => todo!("{:?}", self.lowlevel),
|
||||
NumAbs => {
|
||||
self.load_args(backend);
|
||||
|
@ -85,6 +85,7 @@ pub enum LowLevel {
|
||||
NumDivUnchecked,
|
||||
NumDivCeilUnchecked,
|
||||
NumRemUnchecked,
|
||||
NumModUnchecked,
|
||||
NumIsMultipleOf,
|
||||
NumAbs,
|
||||
NumNeg,
|
||||
@ -293,14 +294,19 @@ impl LowLevelWrapperType {
|
||||
Symbol::NUM_DIV_FLOAT_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_DIV_CEIL => CanBeReplacedBy(NumDivCeilUnchecked),
|
||||
Symbol::NUM_DIV_CEIL_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_REM => WrapperIsRequired,
|
||||
Symbol::NUM_REM => CanBeReplacedBy(NumRemUnchecked),
|
||||
Symbol::NUM_REM_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_MOD => CanBeReplacedBy(NumModUnchecked),
|
||||
Symbol::NUM_MOD_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_IS_MULTIPLE_OF => CanBeReplacedBy(NumIsMultipleOf),
|
||||
Symbol::NUM_ABS => CanBeReplacedBy(NumAbs),
|
||||
Symbol::NUM_NEG => CanBeReplacedBy(NumNeg),
|
||||
Symbol::NUM_SIN => CanBeReplacedBy(NumSin),
|
||||
Symbol::NUM_COS => CanBeReplacedBy(NumCos),
|
||||
Symbol::NUM_SQRT => WrapperIsRequired,
|
||||
Symbol::NUM_LOG => WrapperIsRequired,
|
||||
Symbol::NUM_SQRT => CanBeReplacedBy(NumSqrtUnchecked),
|
||||
Symbol::NUM_SQRT_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_LOG => CanBeReplacedBy(NumLogUnchecked),
|
||||
Symbol::NUM_LOG_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_ROUND => CanBeReplacedBy(NumRound),
|
||||
Symbol::NUM_TO_FLOAT => CanBeReplacedBy(NumToFloat),
|
||||
Symbol::NUM_POW => CanBeReplacedBy(NumPow),
|
||||
|
@ -950,8 +950,8 @@ define_builtins! {
|
||||
41 NUM_DIV_FLOAT_CHECKED: "divChecked"
|
||||
42 NUM_DIV_FLOOR: "divFloor"
|
||||
43 NUM_DIV_FLOOR_CHECKED: "divFloorChecked"
|
||||
44 NUM_MOD_INT: "modInt"
|
||||
45 NUM_MOD_INT_CHECKED: "modIntChecked"
|
||||
44 NUM_MOD: "mod"
|
||||
45 NUM_MOD_CHECKED: "modChecked"
|
||||
46 NUM_MOD_FLOAT: "modFloat"
|
||||
47 NUM_MOD_FLOAT_CHECKED: "modFloatChecked"
|
||||
48 NUM_SQRT: "sqrt"
|
||||
|
@ -994,10 +994,9 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap
|
||||
| NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulChecked | NumGt
|
||||
| NumGte | NumLt | NumLte | NumCompare | NumDivUnchecked | NumDivCeilUnchecked
|
||||
| NumRemUnchecked | NumIsMultipleOf | NumPow | NumPowInt | NumBitwiseAnd
|
||||
| NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy | NumShiftRightBy | NumShiftRightZfBy => {
|
||||
arena.alloc_slice_copy(&[irrelevant, irrelevant])
|
||||
}
|
||||
| NumRemUnchecked | NumModUnchecked | NumIsMultipleOf | NumPow | NumPowInt
|
||||
| NumBitwiseAnd | NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy | NumShiftRightBy
|
||||
| NumShiftRightZfBy => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
|
||||
|
||||
NumToStr | NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumLogUnchecked
|
||||
| NumRound | NumCeiling | NumFloor | NumToFloat | Not | NumIsFinite | NumAtan | NumAcos
|
||||
|
@ -144,6 +144,7 @@ enum FirstOrder {
|
||||
NumCompare,
|
||||
NumDivUnchecked,
|
||||
NumRemUnchecked,
|
||||
NumModUnchecked,
|
||||
NumIsMultipleOf,
|
||||
NumAbs,
|
||||
NumNeg,
|
||||
|
@ -2534,7 +2534,7 @@ fn list_keep_oks() {
|
||||
RocList<i64>
|
||||
);
|
||||
assert_evals_to!(
|
||||
"List.keepOks [1,2] (\\x -> x % 2)",
|
||||
"List.keepOks [1,2] (\\x -> Num.remChecked x 2)",
|
||||
RocList::from_slice(&[1, 0]),
|
||||
RocList<i64>
|
||||
);
|
||||
@ -2561,7 +2561,7 @@ fn list_keep_errs() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
List.keepErrs [0,1,2] (\x -> x % 0 |> Result.mapErr (\_ -> 32))
|
||||
List.keepErrs [0,1,2] (\x -> Num.remChecked x 0 |> Result.mapErr (\_ -> 32))
|
||||
"#
|
||||
),
|
||||
RocList::from_slice(&[32, 32, 32]),
|
||||
|
@ -473,7 +473,7 @@ fn f64_sqrt() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.sqrt 100 is
|
||||
when Num.sqrtChecked 100 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
@ -489,9 +489,7 @@ fn f64_log() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.log 7.38905609893 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
Num.log 7.38905609893
|
||||
"#
|
||||
),
|
||||
1.999999999999912,
|
||||
@ -501,11 +499,11 @@ fn f64_log() {
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn f64_log_one() {
|
||||
fn f64_log_checked_one() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.log 1 is
|
||||
when Num.logChecked 1 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
@ -521,7 +519,7 @@ fn f64_sqrt_zero() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.sqrt 0 is
|
||||
when Num.sqrtChecked 0 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
@ -533,11 +531,11 @@ fn f64_sqrt_zero() {
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn f64_sqrt_negative() {
|
||||
fn f64_sqrt_checked_negative() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.sqrt -1 is
|
||||
when Num.sqrtChecked -1 is
|
||||
Err _ -> 42
|
||||
Ok val -> val
|
||||
"#
|
||||
@ -549,11 +547,11 @@ fn f64_sqrt_negative() {
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn f64_log_zero() {
|
||||
fn f64_log_checked_zero() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.log 0 is
|
||||
when Num.logChecked 0 is
|
||||
Err _ -> 42
|
||||
Ok val -> val
|
||||
"#
|
||||
@ -569,13 +567,12 @@ fn f64_log_negative() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.log -1 is
|
||||
Err _ -> 42
|
||||
Ok val -> val
|
||||
Num.log -1
|
||||
"#
|
||||
),
|
||||
42.0,
|
||||
f64
|
||||
true,
|
||||
f64,
|
||||
|f: f64| f.is_nan()
|
||||
);
|
||||
}
|
||||
|
||||
@ -1082,9 +1079,7 @@ fn gen_rem_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.rem 8 3 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
Num.rem 8 3
|
||||
"#
|
||||
),
|
||||
2,
|
||||
@ -1094,11 +1089,11 @@ fn gen_rem_i64() {
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_rem_div_by_zero_i64() {
|
||||
fn gen_rem_checked_div_by_zero_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.rem 8 0 is
|
||||
when Num.remChecked 8 0 is
|
||||
Err DivByZero -> 4
|
||||
Ok _ -> -23
|
||||
"#
|
||||
|
@ -41,7 +41,7 @@ Expr : [ Val I64, Var Str, Add Expr Expr, Mul Expr Expr, Pow Expr Expr, Ln Expr
|
||||
|
||||
divmod : I64, I64 -> Result { div : I64, mod : I64 } [ DivByZero ]*
|
||||
divmod = \l, r ->
|
||||
when Pair (l // r) (l % r) is
|
||||
when Pair (Num.divFloorChecked l r) (Num.remChecked l r) is
|
||||
Pair div (Ok mod) ->
|
||||
Ok { div, mod }
|
||||
|
||||
|
@ -23,12 +23,12 @@ makeMapHelp = \freq, n, m, acc ->
|
||||
|
||||
_ ->
|
||||
powerOf10 =
|
||||
(n % 10 |> resultWithDefault 0) == 0
|
||||
n % 10 == 0
|
||||
|
||||
m1 = insert m n powerOf10
|
||||
|
||||
isFrequency =
|
||||
(n % freq |> resultWithDefault 0) == 0
|
||||
n % freq == 0
|
||||
|
||||
x = (if isFrequency then Cons m1 acc else acc)
|
||||
|
||||
@ -43,15 +43,6 @@ fold = \f, tree, b ->
|
||||
Node _ l k v r ->
|
||||
fold f r (f k v (fold f l b))
|
||||
|
||||
resultWithDefault : Result a e, a -> a
|
||||
resultWithDefault = \res, default ->
|
||||
when res is
|
||||
Ok v ->
|
||||
v
|
||||
|
||||
Err _ ->
|
||||
default
|
||||
|
||||
main : Task.Task {} []
|
||||
main =
|
||||
Task.after
|
||||
|
@ -56,7 +56,7 @@ fn float_addition() {
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
#[test]
|
||||
fn num_rem() {
|
||||
expect_success("299 % 10", "Ok 9 : Result (Int *) [ DivByZero ]*");
|
||||
expect_success("299 % 10", "9 : Int *");
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
|
Loading…
Reference in New Issue
Block a user