mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
centralize overflow error reporting
This commit is contained in:
parent
074aba0012
commit
2b5ec3dcf1
1 changed files with 11 additions and 175 deletions
|
@ -455,8 +455,7 @@ fn num_add_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumAddWrap)
|
num_binop(symbol, var_store, LowLevel::NumAddWrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.addChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
fn num_overflow_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) -> Def {
|
||||||
fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
|
||||||
let bool_var = var_store.fresh();
|
let bool_var = var_store.fresh();
|
||||||
let num_var_1 = var_store.fresh();
|
let num_var_1 = var_store.fresh();
|
||||||
let num_var_2 = var_store.fresh();
|
let num_var_2 = var_store.fresh();
|
||||||
|
@ -464,7 +463,7 @@ fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let ret_var = var_store.fresh();
|
let ret_var = var_store.fresh();
|
||||||
let record_var = var_store.fresh();
|
let record_var = var_store.fresh();
|
||||||
|
|
||||||
// let arg_3 = RunLowLevel NumAddChecked arg_1 arg_2
|
// let arg_3 = RunLowLevel NumXXXChecked arg_1 arg_2
|
||||||
//
|
//
|
||||||
// if arg_3.b then
|
// if arg_3.b then
|
||||||
// # overflow
|
// # overflow
|
||||||
|
@ -517,11 +516,11 @@ fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
// arg_3 = RunLowLevel NumAddChecked arg_1 arg_2
|
// arg_3 = RunLowLevel NumXXXChecked arg_1 arg_2
|
||||||
let def = crate::def::Def {
|
let def = crate::def::Def {
|
||||||
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_3)),
|
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_3)),
|
||||||
loc_expr: no_region(RunLowLevel {
|
loc_expr: no_region(RunLowLevel {
|
||||||
op: LowLevel::NumAddChecked,
|
op: lowlevel,
|
||||||
args: vec![
|
args: vec![
|
||||||
(num_var_1, Var(Symbol::ARG_1)),
|
(num_var_1, Var(Symbol::ARG_1)),
|
||||||
(num_var_2, Var(Symbol::ARG_2)),
|
(num_var_2, Var(Symbol::ARG_2)),
|
||||||
|
@ -544,6 +543,11 @@ fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Num.addChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
|
fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
num_overflow_checked(symbol, var_store, LowLevel::NumAddChecked)
|
||||||
|
}
|
||||||
|
|
||||||
/// Num.sub : Num a, Num a -> Num a
|
/// Num.sub : Num a, Num a -> Num a
|
||||||
fn num_sub(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_sub(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
num_binop(symbol, var_store, LowLevel::NumSub)
|
num_binop(symbol, var_store, LowLevel::NumSub)
|
||||||
|
@ -556,91 +560,7 @@ fn num_sub_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
|
||||||
/// Num.subChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
/// Num.subChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
fn num_sub_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_sub_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
num_overflow_checked(symbol, var_store, LowLevel::NumSubChecked)
|
||||||
let num_var_1 = var_store.fresh();
|
|
||||||
let num_var_2 = var_store.fresh();
|
|
||||||
let num_var_3 = var_store.fresh();
|
|
||||||
let ret_var = var_store.fresh();
|
|
||||||
let record_var = var_store.fresh();
|
|
||||||
|
|
||||||
// let arg_3 = RunLowLevel NumSubChecked arg_1 arg_2
|
|
||||||
//
|
|
||||||
// if arg_3.b then
|
|
||||||
// # overflow
|
|
||||||
// Err Overflow
|
|
||||||
// else
|
|
||||||
// # all is well
|
|
||||||
// Ok arg_3.a
|
|
||||||
|
|
||||||
let cont = If {
|
|
||||||
branch_var: ret_var,
|
|
||||||
cond_var: bool_var,
|
|
||||||
branches: vec![(
|
|
||||||
// if-condition
|
|
||||||
no_region(
|
|
||||||
// arg_3.b
|
|
||||||
Access {
|
|
||||||
record_var,
|
|
||||||
ext_var: var_store.fresh(),
|
|
||||||
field: "b".into(),
|
|
||||||
field_var: var_store.fresh(),
|
|
||||||
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
// overflow!
|
|
||||||
no_region(tag(
|
|
||||||
"Err",
|
|
||||||
vec![tag("Overflow", Vec::new(), var_store)],
|
|
||||||
var_store,
|
|
||||||
)),
|
|
||||||
)],
|
|
||||||
final_else: Box::new(
|
|
||||||
// all is well
|
|
||||||
no_region(
|
|
||||||
// Ok arg_3.a
|
|
||||||
tag(
|
|
||||||
"Ok",
|
|
||||||
vec![
|
|
||||||
// arg_3.a
|
|
||||||
Access {
|
|
||||||
record_var,
|
|
||||||
ext_var: var_store.fresh(),
|
|
||||||
field: "a".into(),
|
|
||||||
field_var: num_var_3,
|
|
||||||
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
var_store,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
// arg_3 = RunLowLevel NumSubChecked arg_1 arg_2
|
|
||||||
let def = crate::def::Def {
|
|
||||||
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_3)),
|
|
||||||
loc_expr: no_region(RunLowLevel {
|
|
||||||
op: LowLevel::NumSubChecked,
|
|
||||||
args: vec![
|
|
||||||
(num_var_1, Var(Symbol::ARG_1)),
|
|
||||||
(num_var_2, Var(Symbol::ARG_2)),
|
|
||||||
],
|
|
||||||
ret_var: record_var,
|
|
||||||
}),
|
|
||||||
expr_var: record_var,
|
|
||||||
pattern_vars: SendMap::default(),
|
|
||||||
annotation: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let body = LetNonRec(Box::new(def), Box::new(no_region(cont)), ret_var);
|
|
||||||
|
|
||||||
defn(
|
|
||||||
symbol,
|
|
||||||
vec![(num_var_1, Symbol::ARG_1), (num_var_2, Symbol::ARG_2)],
|
|
||||||
var_store,
|
|
||||||
body,
|
|
||||||
ret_var,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.mul : Num a, Num a -> Num a
|
/// Num.mul : Num a, Num a -> Num a
|
||||||
|
@ -655,91 +575,7 @@ fn num_mul_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
|
|
||||||
/// Num.mulChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
/// Num.mulChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def {
|
||||||
let bool_var = var_store.fresh();
|
num_overflow_checked(symbol, var_store, LowLevel::NumMulChecked)
|
||||||
let num_var_1 = var_store.fresh();
|
|
||||||
let num_var_2 = var_store.fresh();
|
|
||||||
let num_var_3 = var_store.fresh();
|
|
||||||
let ret_var = var_store.fresh();
|
|
||||||
let record_var = var_store.fresh();
|
|
||||||
|
|
||||||
// let arg_3 = RunLowLevel NumMulChecked arg_1 arg_2
|
|
||||||
//
|
|
||||||
// if arg_3.b then
|
|
||||||
// # overflow
|
|
||||||
// Err Overflow
|
|
||||||
// else
|
|
||||||
// # all is well
|
|
||||||
// Ok arg_3.a
|
|
||||||
|
|
||||||
let cont = If {
|
|
||||||
branch_var: ret_var,
|
|
||||||
cond_var: bool_var,
|
|
||||||
branches: vec![(
|
|
||||||
// if-condition
|
|
||||||
no_region(
|
|
||||||
// arg_3.b
|
|
||||||
Access {
|
|
||||||
record_var,
|
|
||||||
ext_var: var_store.fresh(),
|
|
||||||
field: "b".into(),
|
|
||||||
field_var: var_store.fresh(),
|
|
||||||
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
// overflow!
|
|
||||||
no_region(tag(
|
|
||||||
"Err",
|
|
||||||
vec![tag("Overflow", Vec::new(), var_store)],
|
|
||||||
var_store,
|
|
||||||
)),
|
|
||||||
)],
|
|
||||||
final_else: Box::new(
|
|
||||||
// all is well
|
|
||||||
no_region(
|
|
||||||
// Ok arg_3.a
|
|
||||||
tag(
|
|
||||||
"Ok",
|
|
||||||
vec![
|
|
||||||
// arg_3.a
|
|
||||||
Access {
|
|
||||||
record_var,
|
|
||||||
ext_var: var_store.fresh(),
|
|
||||||
field: "a".into(),
|
|
||||||
field_var: num_var_3,
|
|
||||||
loc_expr: Box::new(no_region(Var(Symbol::ARG_3))),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
var_store,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
// arg_3 = RunLowLevel NumMulChecked arg_1 arg_2
|
|
||||||
let def = crate::def::Def {
|
|
||||||
loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_3)),
|
|
||||||
loc_expr: no_region(RunLowLevel {
|
|
||||||
op: LowLevel::NumMulChecked,
|
|
||||||
args: vec![
|
|
||||||
(num_var_1, Var(Symbol::ARG_1)),
|
|
||||||
(num_var_2, Var(Symbol::ARG_2)),
|
|
||||||
],
|
|
||||||
ret_var: record_var,
|
|
||||||
}),
|
|
||||||
expr_var: record_var,
|
|
||||||
pattern_vars: SendMap::default(),
|
|
||||||
annotation: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let body = LetNonRec(Box::new(def), Box::new(no_region(cont)), ret_var);
|
|
||||||
|
|
||||||
defn(
|
|
||||||
symbol,
|
|
||||||
vec![(num_var_1, Symbol::ARG_1), (num_var_2, Symbol::ARG_2)],
|
|
||||||
var_store,
|
|
||||||
body,
|
|
||||||
ret_var,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Num.isGt : Num a, Num a -> Bool
|
/// Num.isGt : Num a, Num a -> Bool
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue