mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 10:02:38 +03:00
Merge pull request #2832 from rtfeldman/div-no-result
`div`, `divCeil`, `divFloor` panic + add checked versions returning `Result`
This commit is contained in:
commit
f39f7eda03
@ -310,9 +310,7 @@ pub const RocDec = extern struct {
|
||||
|
||||
// (n / 0) is an error
|
||||
if (denominator_i128 == 0) {
|
||||
// The compiler frontend does the `denominator == 0` check for us,
|
||||
// therefore this case is unreachable from roc user code
|
||||
unreachable;
|
||||
@panic("TODO runtime exception for dividing by 0!");
|
||||
}
|
||||
|
||||
// If they're both negative, or if neither is negative, the final answer
|
||||
|
@ -102,7 +102,7 @@ pub fn exportRound(comptime T: type, comptime name: []const u8) void {
|
||||
pub fn exportDivCeil(comptime T: type, comptime name: []const u8) void {
|
||||
comptime var f = struct {
|
||||
fn func(a: T, b: T) callconv(.C) T {
|
||||
return math.divCeil(T, a, b) catch unreachable;
|
||||
return math.divCeil(T, a, b) catch @panic("TODO runtime exception for dividing by 0!");
|
||||
}
|
||||
}.func;
|
||||
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
|
||||
|
@ -69,6 +69,7 @@ interface Num
|
||||
isNegative,
|
||||
rem,
|
||||
div,
|
||||
divChecked,
|
||||
modInt,
|
||||
modFloat,
|
||||
sqrt,
|
||||
@ -97,7 +98,9 @@ interface Num
|
||||
bytesToU16,
|
||||
bytesToU32,
|
||||
divCeil,
|
||||
divCeilChecked,
|
||||
divFloor,
|
||||
divFloorChecked,
|
||||
toStr,
|
||||
isMultipleOf,
|
||||
minI8,
|
||||
@ -229,10 +232,13 @@ atan : Float a -> Float a
|
||||
|
||||
sqrt : Float a -> Result (Float a) [ SqrtOfNegative ]*
|
||||
log : Float a -> Result (Float a) [ LogNeedsPositive ]*
|
||||
div : Float a, Float a -> Result (Float a) [ DivByZero ]*
|
||||
div : Float a, Float a -> Float a
|
||||
divChecked : Float a, Float a -> Result (Float a) [ DivByZero ]*
|
||||
|
||||
divCeil: Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
divFloor: Int a, Int a -> Result (Int 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 ]*
|
||||
|
@ -316,17 +316,31 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||
Box::new(SolvedType::Wildcard),
|
||||
);
|
||||
|
||||
// divInt : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
// divInt : Int a, Int a -> Int a
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_DIV_INT,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(int_type(flex(TVAR1)))
|
||||
);
|
||||
|
||||
// divIntChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_DIV_INT_CHECKED,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())),
|
||||
);
|
||||
|
||||
//divCeil: Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
// divCeil : Int a, Int a -> Int a
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_DIV_CEIL,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(int_type(flex(TVAR1)))
|
||||
);
|
||||
|
||||
//divCeilChecked : Int a, Int a -> Result (Int a) [ DivByZero ]*
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_DIV_CEIL_CHECKED,
|
||||
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
|
||||
Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())),
|
||||
);
|
||||
|
||||
@ -659,6 +673,13 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
|
||||
add_top_level_function_type!(
|
||||
Symbol::NUM_DIV_FLOAT,
|
||||
vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))],
|
||||
Box::new(float_type(flex(TVAR1)))
|
||||
);
|
||||
|
||||
// divChecked : Float a, Float a -> Result (Float a) [ DivByZero ]*
|
||||
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())),
|
||||
);
|
||||
|
||||
|
@ -195,8 +195,11 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
|
||||
NUM_COS => num_cos,
|
||||
NUM_TAN => num_tan,
|
||||
NUM_DIV_FLOAT => num_div_float,
|
||||
NUM_DIV_FLOAT_CHECKED => num_div_float_checked,
|
||||
NUM_DIV_INT => num_div_int,
|
||||
NUM_DIV_INT_CHECKED => num_div_int_checked,
|
||||
NUM_DIV_CEIL => num_div_ceil,
|
||||
NUM_DIV_CEIL_CHECKED => num_div_ceil_checked,
|
||||
NUM_ABS => num_abs,
|
||||
NUM_NEG => num_neg,
|
||||
NUM_REM => num_rem,
|
||||
@ -4295,8 +4298,13 @@ fn num_abs(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.div : Float, Float -> Result Float [ DivByZero ]*
|
||||
/// Num.div : Float, Float -> Float
|
||||
fn num_div_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_binop(symbol, var_store, LowLevel::NumDivUnchecked)
|
||||
}
|
||||
|
||||
/// Num.divChecked : Float, Float -> Result Float [ DivByZero ]*
|
||||
fn num_div_float_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let num_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
@ -4361,8 +4369,13 @@ fn num_div_float(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.div : Int a , Int a -> Result (Int a) [ DivByZero ]*
|
||||
/// Num.div : Int a, Int a -> Int a
|
||||
fn num_div_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_binop(symbol, var_store, LowLevel::NumDivUnchecked)
|
||||
}
|
||||
|
||||
/// Num.divChecked : Int a , Int a -> Result (Int a) [ DivByZero ]*
|
||||
fn num_div_int_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let num_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
@ -4432,8 +4445,13 @@ fn num_div_int(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
)
|
||||
}
|
||||
|
||||
/// Num.divCeil : Int a , Int a -> Result (Int a) [ DivByZero ]*
|
||||
/// Num.divCeil : Int a, Int a -> Int a
|
||||
fn num_div_ceil(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
num_binop(symbol, var_store, LowLevel::NumDivCeilUnchecked)
|
||||
}
|
||||
|
||||
/// Num.divCeilChecked : Int a , Int a -> Result (Int a) [ DivByZero ]*
|
||||
fn num_div_ceil_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||
let bool_var = var_store.fresh();
|
||||
let num_var = var_store.fresh();
|
||||
let unbound_zero_var = var_store.fresh();
|
||||
|
@ -426,12 +426,12 @@ mod test_load {
|
||||
loaded_module,
|
||||
hashmap! {
|
||||
"floatTest" => "Float *",
|
||||
"divisionFn" => "Float a, Float a -> Result (Float a) [ DivByZero ]*",
|
||||
"divisionTest" => "Result (Float *) [ DivByZero ]*",
|
||||
"divisionFn" => "Float a, Float a -> Float a",
|
||||
"divisionTest" => "Float *",
|
||||
"intTest" => "I64",
|
||||
"x" => "Float *",
|
||||
"constantNum" => "Num *",
|
||||
"divDep1ByDep2" => "Result (Float *) [ DivByZero ]*",
|
||||
"divDep1ByDep2" => "Float *",
|
||||
"fromDep2" => "Float *",
|
||||
},
|
||||
);
|
||||
|
@ -289,8 +289,10 @@ impl LowLevelWrapperType {
|
||||
Symbol::NUM_LT => CanBeReplacedBy(NumLt),
|
||||
Symbol::NUM_LTE => CanBeReplacedBy(NumLte),
|
||||
Symbol::NUM_COMPARE => CanBeReplacedBy(NumCompare),
|
||||
Symbol::NUM_DIV_FLOAT => WrapperIsRequired,
|
||||
Symbol::NUM_DIV_CEIL => WrapperIsRequired,
|
||||
Symbol::NUM_DIV_FLOAT => CanBeReplacedBy(NumDivUnchecked),
|
||||
Symbol::NUM_DIV_FLOAT_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_DIV_CEIL => CanBeReplacedBy(NumDivCeilUnchecked),
|
||||
Symbol::NUM_DIV_CEIL_CHECKED => WrapperIsRequired,
|
||||
Symbol::NUM_REM => WrapperIsRequired,
|
||||
Symbol::NUM_IS_MULTIPLE_OF => CanBeReplacedBy(NumIsMultipleOf),
|
||||
Symbol::NUM_ABS => CanBeReplacedBy(NumAbs),
|
||||
|
@ -945,118 +945,126 @@ define_builtins! {
|
||||
36 NUM_IS_POSITIVE: "isPositive"
|
||||
37 NUM_IS_NEGATIVE: "isNegative"
|
||||
38 NUM_REM: "rem"
|
||||
39 NUM_DIV_FLOAT: "div"
|
||||
40 NUM_DIV_INT: "divFloor"
|
||||
41 NUM_MOD_INT: "modInt"
|
||||
42 NUM_MOD_FLOAT: "modFloat"
|
||||
43 NUM_SQRT: "sqrt"
|
||||
44 NUM_LOG: "log"
|
||||
45 NUM_ROUND: "round"
|
||||
46 NUM_COMPARE: "compare"
|
||||
47 NUM_POW: "pow"
|
||||
48 NUM_CEILING: "ceiling"
|
||||
49 NUM_POW_INT: "powInt"
|
||||
50 NUM_FLOOR: "floor"
|
||||
51 NUM_ADD_WRAP: "addWrap"
|
||||
52 NUM_ADD_CHECKED: "addChecked"
|
||||
53 NUM_ADD_SATURATED: "addSaturated"
|
||||
54 NUM_ATAN: "atan"
|
||||
55 NUM_ACOS: "acos"
|
||||
56 NUM_ASIN: "asin"
|
||||
57 NUM_AT_SIGNED128: "@Signed128"
|
||||
58 NUM_SIGNED128: "Signed128" imported
|
||||
59 NUM_AT_SIGNED64: "@Signed64"
|
||||
60 NUM_SIGNED64: "Signed64" imported
|
||||
61 NUM_AT_SIGNED32: "@Signed32"
|
||||
62 NUM_SIGNED32: "Signed32" imported
|
||||
63 NUM_AT_SIGNED16: "@Signed16"
|
||||
64 NUM_SIGNED16: "Signed16" imported
|
||||
65 NUM_AT_SIGNED8: "@Signed8"
|
||||
66 NUM_SIGNED8: "Signed8" imported
|
||||
67 NUM_AT_UNSIGNED128: "@Unsigned128"
|
||||
68 NUM_UNSIGNED128: "Unsigned128" imported
|
||||
69 NUM_AT_UNSIGNED64: "@Unsigned64"
|
||||
70 NUM_UNSIGNED64: "Unsigned64" imported
|
||||
71 NUM_AT_UNSIGNED32: "@Unsigned32"
|
||||
72 NUM_UNSIGNED32: "Unsigned32" imported
|
||||
73 NUM_AT_UNSIGNED16: "@Unsigned16"
|
||||
74 NUM_UNSIGNED16: "Unsigned16" imported
|
||||
75 NUM_AT_UNSIGNED8: "@Unsigned8"
|
||||
76 NUM_UNSIGNED8: "Unsigned8" imported
|
||||
77 NUM_AT_BINARY64: "@Binary64"
|
||||
78 NUM_BINARY64: "Binary64" imported
|
||||
79 NUM_AT_BINARY32: "@Binary32"
|
||||
80 NUM_BINARY32: "Binary32" imported
|
||||
81 NUM_BITWISE_AND: "bitwiseAnd"
|
||||
82 NUM_BITWISE_XOR: "bitwiseXor"
|
||||
83 NUM_BITWISE_OR: "bitwiseOr"
|
||||
84 NUM_SHIFT_LEFT: "shiftLeftBy"
|
||||
85 NUM_SHIFT_RIGHT: "shiftRightBy"
|
||||
86 NUM_SHIFT_RIGHT_ZERO_FILL: "shiftRightZfBy"
|
||||
87 NUM_SUB_WRAP: "subWrap"
|
||||
88 NUM_SUB_CHECKED: "subChecked"
|
||||
89 NUM_SUB_SATURATED: "subSaturated"
|
||||
90 NUM_MUL_WRAP: "mulWrap"
|
||||
91 NUM_MUL_CHECKED: "mulChecked"
|
||||
92 NUM_INT: "Int" imported
|
||||
93 NUM_FLOAT: "Float" imported
|
||||
94 NUM_AT_NATURAL: "@Natural"
|
||||
95 NUM_NATURAL: "Natural" imported
|
||||
96 NUM_NAT: "Nat" imported
|
||||
97 NUM_INT_CAST: "intCast"
|
||||
98 NUM_IS_MULTIPLE_OF: "isMultipleOf"
|
||||
99 NUM_AT_DECIMAL: "@Decimal"
|
||||
100 NUM_DECIMAL: "Decimal" imported
|
||||
101 NUM_DEC: "Dec" imported // the Num.Dectype alias
|
||||
102 NUM_BYTES_TO_U16: "bytesToU16"
|
||||
103 NUM_BYTES_TO_U32: "bytesToU32"
|
||||
104 NUM_CAST_TO_NAT: "#castToNat"
|
||||
105 NUM_DIV_CEIL: "divCeil"
|
||||
106 NUM_TO_STR: "toStr"
|
||||
107 NUM_MIN_I8: "minI8"
|
||||
108 NUM_MAX_I8: "maxI8"
|
||||
109 NUM_MIN_U8: "minU8"
|
||||
110 NUM_MAX_U8: "maxU8"
|
||||
111 NUM_MIN_I16: "minI16"
|
||||
112 NUM_MAX_I16: "maxI16"
|
||||
113 NUM_MIN_U16: "minU16"
|
||||
114 NUM_MAX_U16: "maxU16"
|
||||
115 NUM_MIN_I32: "minI32"
|
||||
116 NUM_MAX_I32: "maxI32"
|
||||
117 NUM_MIN_U32: "minU32"
|
||||
118 NUM_MAX_U32: "maxU32"
|
||||
119 NUM_MIN_I64: "minI64"
|
||||
120 NUM_MAX_I64: "maxI64"
|
||||
121 NUM_MIN_U64: "minU64"
|
||||
122 NUM_MAX_U64: "maxU64"
|
||||
123 NUM_MIN_I128: "minI128"
|
||||
124 NUM_MAX_I128: "maxI128"
|
||||
125 NUM_TO_I8: "toI8"
|
||||
126 NUM_TO_I8_CHECKED: "toI8Checked"
|
||||
127 NUM_TO_I16: "toI16"
|
||||
128 NUM_TO_I16_CHECKED: "toI16Checked"
|
||||
129 NUM_TO_I32: "toI32"
|
||||
130 NUM_TO_I32_CHECKED: "toI32Checked"
|
||||
131 NUM_TO_I64: "toI64"
|
||||
132 NUM_TO_I64_CHECKED: "toI64Checked"
|
||||
133 NUM_TO_I128: "toI128"
|
||||
134 NUM_TO_I128_CHECKED: "toI128Checked"
|
||||
135 NUM_TO_U8: "toU8"
|
||||
136 NUM_TO_U8_CHECKED: "toU8Checked"
|
||||
137 NUM_TO_U16: "toU16"
|
||||
138 NUM_TO_U16_CHECKED: "toU16Checked"
|
||||
139 NUM_TO_U32: "toU32"
|
||||
140 NUM_TO_U32_CHECKED: "toU32Checked"
|
||||
141 NUM_TO_U64: "toU64"
|
||||
142 NUM_TO_U64_CHECKED: "toU64Checked"
|
||||
143 NUM_TO_U128: "toU128"
|
||||
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"
|
||||
39 NUM_REM_CHECKED: "remChecked"
|
||||
40 NUM_DIV_FLOAT: "div"
|
||||
41 NUM_DIV_FLOAT_CHECKED: "divChecked"
|
||||
42 NUM_DIV_INT: "divFloor"
|
||||
43 NUM_DIV_INT_CHECKED: "divFloorChecked"
|
||||
44 NUM_MOD_INT: "modInt"
|
||||
45 NUM_MOD_INT_CHECKED: "modIntChecked"
|
||||
46 NUM_MOD_FLOAT: "modFloat"
|
||||
47 NUM_MOD_FLOAT_CHECKED: "modFloatChecked"
|
||||
48 NUM_SQRT: "sqrt"
|
||||
49 NUM_SQRT_CHECKED: "sqrtChecked"
|
||||
50 NUM_LOG: "log"
|
||||
51 NUM_LOG_CHECKED: "logChecked"
|
||||
52 NUM_ROUND: "round"
|
||||
53 NUM_COMPARE: "compare"
|
||||
54 NUM_POW: "pow"
|
||||
55 NUM_CEILING: "ceiling"
|
||||
56 NUM_POW_INT: "powInt"
|
||||
57 NUM_FLOOR: "floor"
|
||||
58 NUM_ADD_WRAP: "addWrap"
|
||||
59 NUM_ADD_CHECKED: "addChecked"
|
||||
60 NUM_ADD_SATURATED: "addSaturated"
|
||||
61 NUM_ATAN: "atan"
|
||||
62 NUM_ACOS: "acos"
|
||||
63 NUM_ASIN: "asin"
|
||||
64 NUM_AT_SIGNED128: "@Signed128"
|
||||
65 NUM_SIGNED128: "Signed128" imported
|
||||
66 NUM_AT_SIGNED64: "@Signed64"
|
||||
67 NUM_SIGNED64: "Signed64" imported
|
||||
68 NUM_AT_SIGNED32: "@Signed32"
|
||||
69 NUM_SIGNED32: "Signed32" imported
|
||||
70 NUM_AT_SIGNED16: "@Signed16"
|
||||
71 NUM_SIGNED16: "Signed16" imported
|
||||
72 NUM_AT_SIGNED8: "@Signed8"
|
||||
73 NUM_SIGNED8: "Signed8" imported
|
||||
74 NUM_AT_UNSIGNED128: "@Unsigned128"
|
||||
75 NUM_UNSIGNED128: "Unsigned128" imported
|
||||
76 NUM_AT_UNSIGNED64: "@Unsigned64"
|
||||
77 NUM_UNSIGNED64: "Unsigned64" imported
|
||||
78 NUM_AT_UNSIGNED32: "@Unsigned32"
|
||||
79 NUM_UNSIGNED32: "Unsigned32" imported
|
||||
80 NUM_AT_UNSIGNED16: "@Unsigned16"
|
||||
81 NUM_UNSIGNED16: "Unsigned16" imported
|
||||
82 NUM_AT_UNSIGNED8: "@Unsigned8"
|
||||
83 NUM_UNSIGNED8: "Unsigned8" imported
|
||||
84 NUM_AT_BINARY64: "@Binary64"
|
||||
85 NUM_BINARY64: "Binary64" imported
|
||||
86 NUM_AT_BINARY32: "@Binary32"
|
||||
87 NUM_BINARY32: "Binary32" imported
|
||||
88 NUM_BITWISE_AND: "bitwiseAnd"
|
||||
89 NUM_BITWISE_XOR: "bitwiseXor"
|
||||
90 NUM_BITWISE_OR: "bitwiseOr"
|
||||
91 NUM_SHIFT_LEFT: "shiftLeftBy"
|
||||
92 NUM_SHIFT_RIGHT: "shiftRightBy"
|
||||
93 NUM_SHIFT_RIGHT_ZERO_FILL: "shiftRightZfBy"
|
||||
94 NUM_SUB_WRAP: "subWrap"
|
||||
95 NUM_SUB_CHECKED: "subChecked"
|
||||
96 NUM_SUB_SATURATED: "subSaturated"
|
||||
97 NUM_MUL_WRAP: "mulWrap"
|
||||
98 NUM_MUL_CHECKED: "mulChecked"
|
||||
99 NUM_INT: "Int" imported
|
||||
100 NUM_FLOAT: "Float" imported
|
||||
101 NUM_AT_NATURAL: "@Natural"
|
||||
102 NUM_NATURAL: "Natural" imported
|
||||
103 NUM_NAT: "Nat" imported
|
||||
104 NUM_INT_CAST: "intCast"
|
||||
105 NUM_IS_MULTIPLE_OF: "isMultipleOf"
|
||||
106 NUM_AT_DECIMAL: "@Decimal"
|
||||
107 NUM_DECIMAL: "Decimal" imported
|
||||
108 NUM_DEC: "Dec" imported // the Num.Dectype alias
|
||||
109 NUM_BYTES_TO_U16: "bytesToU16"
|
||||
110 NUM_BYTES_TO_U32: "bytesToU32"
|
||||
111 NUM_CAST_TO_NAT: "#castToNat"
|
||||
112 NUM_DIV_CEIL: "divCeil"
|
||||
113 NUM_DIV_CEIL_CHECKED: "divCeilChecked"
|
||||
114 NUM_TO_STR: "toStr"
|
||||
115 NUM_MIN_I8: "minI8"
|
||||
116 NUM_MAX_I8: "maxI8"
|
||||
117 NUM_MIN_U8: "minU8"
|
||||
118 NUM_MAX_U8: "maxU8"
|
||||
119 NUM_MIN_I16: "minI16"
|
||||
120 NUM_MAX_I16: "maxI16"
|
||||
121 NUM_MIN_U16: "minU16"
|
||||
122 NUM_MAX_U16: "maxU16"
|
||||
123 NUM_MIN_I32: "minI32"
|
||||
124 NUM_MAX_I32: "maxI32"
|
||||
125 NUM_MIN_U32: "minU32"
|
||||
126 NUM_MAX_U32: "maxU32"
|
||||
127 NUM_MIN_I64: "minI64"
|
||||
128 NUM_MAX_I64: "maxI64"
|
||||
129 NUM_MIN_U64: "minU64"
|
||||
130 NUM_MAX_U64: "maxU64"
|
||||
131 NUM_MIN_I128: "minI128"
|
||||
132 NUM_MAX_I128: "maxI128"
|
||||
133 NUM_TO_I8: "toI8"
|
||||
134 NUM_TO_I8_CHECKED: "toI8Checked"
|
||||
135 NUM_TO_I16: "toI16"
|
||||
136 NUM_TO_I16_CHECKED: "toI16Checked"
|
||||
137 NUM_TO_I32: "toI32"
|
||||
138 NUM_TO_I32_CHECKED: "toI32Checked"
|
||||
139 NUM_TO_I64: "toI64"
|
||||
140 NUM_TO_I64_CHECKED: "toI64Checked"
|
||||
141 NUM_TO_I128: "toI128"
|
||||
142 NUM_TO_I128_CHECKED: "toI128Checked"
|
||||
143 NUM_TO_U8: "toU8"
|
||||
144 NUM_TO_U8_CHECKED: "toU8Checked"
|
||||
145 NUM_TO_U16: "toU16"
|
||||
146 NUM_TO_U16_CHECKED: "toU16Checked"
|
||||
147 NUM_TO_U32: "toU32"
|
||||
148 NUM_TO_U32_CHECKED: "toU32Checked"
|
||||
149 NUM_TO_U64: "toU64"
|
||||
150 NUM_TO_U64_CHECKED: "toU64Checked"
|
||||
151 NUM_TO_U128: "toU128"
|
||||
152 NUM_TO_U128_CHECKED: "toU128Checked"
|
||||
153 NUM_TO_NAT: "toNat"
|
||||
154 NUM_TO_NAT_CHECKED: "toNatChecked"
|
||||
155 NUM_TO_F32: "toF32"
|
||||
156 NUM_TO_F32_CHECKED: "toF32Checked"
|
||||
157 NUM_TO_F64: "toF64"
|
||||
158 NUM_TO_F64_CHECKED: "toF64Checked"
|
||||
}
|
||||
2 BOOL: "Bool" => {
|
||||
0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias
|
||||
|
@ -3296,6 +3296,30 @@ mod solve_expr {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.div
|
||||
"#
|
||||
),
|
||||
"Float a, Float a -> Float a",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_checked() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.divChecked
|
||||
"#
|
||||
),
|
||||
"Float a, Float a -> Result (Float a) [ DivByZero ]*",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_ceil() {
|
||||
infer_eq_without_problem(
|
||||
@ -3304,22 +3328,46 @@ mod solve_expr {
|
||||
Num.divCeil
|
||||
"#
|
||||
),
|
||||
"Int a, Int a -> Int a",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_ceil_checked() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.divCeilChecked
|
||||
"#
|
||||
),
|
||||
"Int a, Int a -> Result (Int a) [ DivByZero ]*",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pow_int() {
|
||||
fn div_floor() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.powInt
|
||||
Num.divFloor
|
||||
"#
|
||||
),
|
||||
"Int a, Int a -> Int a",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn div_floor_checked() {
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
Num.divFloorChecked
|
||||
"#
|
||||
),
|
||||
"Int a, Int a -> Result (Int a) [ DivByZero ]*",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atan() {
|
||||
infer_eq_without_problem(
|
||||
|
@ -723,11 +723,24 @@ fn gen_wrap_add_nums() {
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_f64() {
|
||||
// FIXME this works with normal types, but fails when checking uniqueness types
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when 48 / 2 is
|
||||
48 / 2
|
||||
"#
|
||||
),
|
||||
24.0,
|
||||
f64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_checked_f64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.divChecked 48 2 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
@ -736,6 +749,23 @@ fn gen_div_f64() {
|
||||
f64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_checked_by_zero_f64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.divChecked 47 0 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
),
|
||||
-1.0,
|
||||
f64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_dec() {
|
||||
@ -748,7 +778,27 @@ fn gen_div_dec() {
|
||||
y : Dec
|
||||
y = 3
|
||||
|
||||
when x / y is
|
||||
x / y
|
||||
"#
|
||||
),
|
||||
RocDec::from_str_to_i128_unsafe("3.333333333333333333"),
|
||||
i128
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_checked_dec() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
x : Dec
|
||||
x = 10
|
||||
|
||||
y : Dec
|
||||
y = 3
|
||||
|
||||
when Num.divChecked x y is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
@ -757,6 +807,27 @@ fn gen_div_dec() {
|
||||
i128
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_checked_by_zero_dec() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
x : Dec
|
||||
x = 10
|
||||
|
||||
y : Dec
|
||||
y = 0
|
||||
|
||||
when Num.divChecked x y is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
),
|
||||
RocDec::from_str_to_i128_unsafe("-1"),
|
||||
i128
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm", feature = "gen-dev", feature = "gen-wasm"))]
|
||||
@ -965,7 +1036,21 @@ fn gen_div_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when 1000 // 10 is
|
||||
1000 // 10
|
||||
"#
|
||||
),
|
||||
100,
|
||||
i64
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_checked_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when Num.divFloorChecked 1000 10 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
@ -977,11 +1062,11 @@ fn gen_div_i64() {
|
||||
|
||||
#[test]
|
||||
#[cfg(any(feature = "gen-llvm"))]
|
||||
fn gen_div_by_zero_i64() {
|
||||
fn gen_div_checked_by_zero_i64() {
|
||||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
when 1000 // 0 is
|
||||
when Num.divFloorChecked 1000 0 is
|
||||
Err DivByZero -> 99
|
||||
_ -> -24
|
||||
"#
|
||||
|
@ -274,7 +274,7 @@ fn ir_round() {
|
||||
#[mono_test]
|
||||
fn ir_when_idiv() {
|
||||
r#"
|
||||
when 1000 // 10 is
|
||||
when Num.divFloorChecked 1000 10 is
|
||||
Ok val -> val
|
||||
Err _ -> -1
|
||||
"#
|
||||
|
@ -42,7 +42,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
|
||||
Pair (Ok div) (Ok mod) ->
|
||||
Pair div (Ok mod) ->
|
||||
Ok { div, mod }
|
||||
|
||||
_ ->
|
||||
|
@ -47,7 +47,7 @@ makeMapHelp = \total, n, m ->
|
||||
isFrequency =
|
||||
n |> Num.isMultipleOf 4
|
||||
|
||||
key = n1 + ((total - n1) // 5 |> resultWithDefault 0)
|
||||
key = n1 + ((total - n1) // 5)
|
||||
t2 = if isFrequency then delete t1 key else t1
|
||||
|
||||
makeMapHelp total n1 t2
|
||||
|
@ -434,7 +434,7 @@ stepExecCtx = \ctx, char ->
|
||||
(
|
||||
(T popCtx1 numR) <- Result.after (popNumber ctx)
|
||||
(T popCtx2 numL) <- Result.after (popNumber popCtx1)
|
||||
res <- Result.after (Num.divFloor numL numR)
|
||||
res <- Result.after (Num.divFloorChecked numL numR)
|
||||
Ok (Context.pushStack popCtx2 (Number res))
|
||||
)
|
||||
|
||||
|
@ -4,9 +4,7 @@ app "hello-gui"
|
||||
provides [ render ] to pf
|
||||
|
||||
render =
|
||||
div0 = \numerator, denominator -> (numerator / denominator) |> Result.withDefault 0
|
||||
|
||||
rgba = \r, g, b, a -> { r: div0 r 255, g: div0 g 255, b: div0 b 255, a }
|
||||
rgba = \r, g, b, a -> { r: r / 255, g: g / 255, b: b / 255, a }
|
||||
|
||||
styles = { bgColor: rgba 100 50 50 1, borderColor: rgba 10 20 30 1, borderWidth: 10, textColor: rgba 220 220 250 1 }
|
||||
|
||||
|
@ -61,23 +61,41 @@ fn num_rem() {
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
#[test]
|
||||
fn num_floor_division_success() {
|
||||
expect_success("Num.divFloor 4 3", "Ok 1 : Result (Int *) [ DivByZero ]*");
|
||||
fn num_floor_division() {
|
||||
expect_success("Num.divFloor 4 3", "1 : Int *");
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
#[test]
|
||||
fn num_floor_division_divby_zero() {
|
||||
fn num_floor_checked_division_success() {
|
||||
expect_success(
|
||||
"Num.divFloor 4 0",
|
||||
"Num.divFloorChecked 4 3",
|
||||
"Ok 1 : Result (Int *) [ DivByZero ]*",
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
#[test]
|
||||
fn num_floor_checked_division_divby_zero() {
|
||||
expect_success(
|
||||
"Num.divFloorChecked 4 0",
|
||||
"Err DivByZero : Result (Int *) [ DivByZero ]*",
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
#[test]
|
||||
fn num_ceil_division_success() {
|
||||
expect_success("Num.divCeil 4 3", "Ok 2 : Result (Int *) [ DivByZero ]*")
|
||||
fn num_ceil_division() {
|
||||
expect_success("Num.divCeil 4 3", "2 : Int *")
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "wasm"))]
|
||||
#[test]
|
||||
fn num_ceil_checked_division_success() {
|
||||
expect_success(
|
||||
"Num.divCeilChecked 4 3",
|
||||
"Ok 2 : Result (Int *) [ DivByZero ]*",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user