change the return type of List.replace

This commit is contained in:
Folkert 2022-02-27 22:47:08 +01:00
parent 4d42d81c63
commit 78fe734113
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
2 changed files with 34 additions and 42 deletions

View file

@ -1056,20 +1056,17 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
Box::new(result_type(flex(TVAR1), list_was_empty.clone())), Box::new(result_type(flex(TVAR1), list_was_empty.clone())),
); );
// replace : List elem, Nat, elem -> Result { list: List elem, value: elem } [ OutOfBounds ]* // replace : List elem, Nat, elem -> { list: List elem, value: elem }
add_top_level_function_type!( add_top_level_function_type!(
Symbol::LIST_REPLACE, Symbol::LIST_REPLACE,
vec![list_type(flex(TVAR1)), nat_type(), flex(TVAR1)], vec![list_type(flex(TVAR1)), nat_type(), flex(TVAR1)],
Box::new(result_type( Box::new(SolvedType::Record {
SolvedType::Record { fields: vec![
fields: vec![ ("list".into(), RecordField::Required(list_type(flex(TVAR1)))),
("list".into(), RecordField::Required(list_type(flex(TVAR1)))), ("value".into(), RecordField::Required(flex(TVAR1))),
("value".into(), RecordField::Required(flex(TVAR1))), ],
], ext: Box::new(SolvedType::EmptyRecord),
ext: Box::new(SolvedType::EmptyRecord), }),
},
index_out_of_bounds
)),
); );
// set : List elem, Nat, elem -> List elem // set : List elem, Nat, elem -> List elem

View file

@ -2304,13 +2304,7 @@ fn list_get(symbol: Symbol, var_store: &mut VarStore) -> Def {
) )
} }
/// List.replace : List elem, Nat, elem -> Result { list: List elem, value: elem } [ OutOfBounds ]* /// List.replace : List elem, Nat, elem -> { list: List elem, value: elem }
///
/// List.replace :
/// Attr (w | u | v) (List (Attr u a)),
/// Attr * Int,
/// Attr (u | v) a
/// -> Attr * (Result { list: List (Attr u a), value: Attr u a } (Attr * [ OutOfBounds ]*))
fn list_replace(symbol: Symbol, var_store: &mut VarStore) -> Def { fn list_replace(symbol: Symbol, var_store: &mut VarStore) -> Def {
let arg_list = Symbol::ARG_1; let arg_list = Symbol::ARG_1;
let arg_index = Symbol::ARG_2; let arg_index = Symbol::ARG_2;
@ -2322,6 +2316,18 @@ fn list_replace(symbol: Symbol, var_store: &mut VarStore) -> Def {
let ret_record_var = var_store.fresh(); let ret_record_var = var_store.fresh();
let ret_result_var = var_store.fresh(); let ret_result_var = var_store.fresh();
let list_field = Field {
var: list_arg_var,
region: Region::zero(),
loc_expr: Box::new(Loc::at_zero(Expr::Var(arg_list))),
};
let value_field = Field {
var: elem_var,
region: Region::zero(),
loc_expr: Box::new(Loc::at_zero(Expr::Var(arg_elem))),
};
// Perform a bounds check. If it passes, run LowLevel::ListReplaceUnsafe. // Perform a bounds check. If it passes, run LowLevel::ListReplaceUnsafe.
// Otherwise, return the list unmodified. // Otherwise, return the list unmodified.
let body = If { let body = If {
@ -2349,35 +2355,24 @@ fn list_replace(symbol: Symbol, var_store: &mut VarStore) -> Def {
), ),
// then-branch // then-branch
no_region( no_region(
// Ok // List.replaceUnsafe list index elem
tag( RunLowLevel {
"Ok", op: LowLevel::ListReplaceUnsafe,
vec![ args: vec![
// List.replaceUnsafe list index elem (list_arg_var, Var(arg_list)),
RunLowLevel { (len_var, Var(arg_index)),
op: LowLevel::ListReplaceUnsafe, (elem_var, Var(arg_elem)),
args: vec![
(list_arg_var, Var(arg_list)),
(len_var, Var(arg_index)),
(elem_var, Var(arg_elem)),
],
ret_var: ret_record_var,
},
], ],
var_store, ret_var: ret_record_var,
), },
), ),
)], )],
final_else: Box::new( final_else: Box::new(
// else-branch // else-branch
no_region( no_region(record(
// Err vec![("list".into(), list_field), ("value".into(), value_field)],
tag( var_store,
"Err", )),
vec![tag("OutOfBounds", Vec::new(), var_store)],
var_store,
),
),
), ),
}; };