diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index b6d13be1da..4183f7cb99 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -455,8 +455,7 @@ fn num_add_wrap(symbol: Symbol, var_store: &mut VarStore) -> Def { num_binop(symbol, var_store, LowLevel::NumAddWrap) } -/// Num.addChecked : Num a, Num a -> Result (Num a) [ Overflow ]* -fn num_add_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { +fn num_overflow_checked(symbol: Symbol, var_store: &mut VarStore, lowlevel: LowLevel) -> Def { let bool_var = var_store.fresh(); let num_var_1 = 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 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 // # 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 { loc_pattern: no_region(Pattern::Identifier(Symbol::ARG_3)), loc_expr: no_region(RunLowLevel { - op: LowLevel::NumAddChecked, + op: lowlevel, args: vec![ (num_var_1, Var(Symbol::ARG_1)), (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 fn num_sub(symbol: Symbol, var_store: &mut VarStore) -> Def { 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 ]* fn num_sub_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { - let bool_var = var_store.fresh(); - 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_overflow_checked(symbol, var_store, LowLevel::NumSubChecked) } /// 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 ]* fn num_mul_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { - let bool_var = var_store.fresh(); - 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_overflow_checked(symbol, var_store, LowLevel::NumMulChecked) } /// Num.isGt : Num a, Num a -> Bool