mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
Merge branch 'main' into get-pointer
This commit is contained in:
commit
70a10e45c1
22 changed files with 922 additions and 868 deletions
|
@ -634,8 +634,10 @@ fn test_for_pattern<'a>(pattern: &Pattern<'a>) -> Option<Test<'a>> {
|
|||
|
||||
List {
|
||||
arity,
|
||||
list_layout: _,
|
||||
element_layout: _,
|
||||
elements: _,
|
||||
opt_rest: _,
|
||||
} => IsListLen {
|
||||
bound: match arity {
|
||||
ListArity::Exact(_) => ListLenBound::Exact,
|
||||
|
@ -908,7 +910,9 @@ fn to_relevant_branch_help<'a>(
|
|||
List {
|
||||
arity: my_arity,
|
||||
elements,
|
||||
list_layout: _,
|
||||
element_layout: _,
|
||||
opt_rest: _,
|
||||
} => match test {
|
||||
IsListLen {
|
||||
bound: test_bound,
|
||||
|
|
|
@ -61,8 +61,10 @@ pub enum Pattern<'a> {
|
|||
},
|
||||
List {
|
||||
arity: ListArity,
|
||||
list_layout: InLayout<'a>,
|
||||
element_layout: InLayout<'a>,
|
||||
elements: Vec<'a, Pattern<'a>>,
|
||||
opt_rest: Option<(usize, Option<Symbol>)>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -1050,10 +1052,18 @@ fn from_can_pattern_help<'a>(
|
|||
}
|
||||
|
||||
List {
|
||||
list_var: _,
|
||||
list_var,
|
||||
elem_var,
|
||||
patterns,
|
||||
} => {
|
||||
let list_layout = match layout_cache.from_var(env.arena, *list_var, env.subs) {
|
||||
Ok(lay) => lay,
|
||||
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||
return Err(RuntimeError::UnresolvedTypeVar)
|
||||
}
|
||||
Err(LayoutProblem::Erroneous) => return Err(RuntimeError::ErroneousType),
|
||||
};
|
||||
|
||||
let element_layout = match layout_cache.from_var(env.arena, *elem_var, env.subs) {
|
||||
Ok(lay) => lay,
|
||||
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||
|
@ -1073,8 +1083,10 @@ fn from_can_pattern_help<'a>(
|
|||
|
||||
Ok(Pattern::List {
|
||||
arity,
|
||||
list_layout,
|
||||
element_layout,
|
||||
elements: mono_patterns,
|
||||
opt_rest: patterns.opt_rest,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1240,8 +1252,10 @@ fn store_pattern_help<'a>(
|
|||
|
||||
List {
|
||||
arity,
|
||||
list_layout,
|
||||
element_layout,
|
||||
elements,
|
||||
opt_rest,
|
||||
} => {
|
||||
return store_list_pattern(
|
||||
env,
|
||||
|
@ -1249,8 +1263,10 @@ fn store_pattern_help<'a>(
|
|||
layout_cache,
|
||||
outer_symbol,
|
||||
*arity,
|
||||
*list_layout,
|
||||
*element_layout,
|
||||
elements,
|
||||
opt_rest,
|
||||
stmt,
|
||||
)
|
||||
}
|
||||
|
@ -1447,8 +1463,10 @@ fn store_list_pattern<'a>(
|
|||
layout_cache: &mut LayoutCache<'a>,
|
||||
list_sym: Symbol,
|
||||
list_arity: ListArity,
|
||||
list_layout: InLayout<'a>,
|
||||
element_layout: InLayout<'a>,
|
||||
elements: &[Pattern<'a>],
|
||||
opt_rest: &Option<(usize, Option<Symbol>)>,
|
||||
mut stmt: Stmt<'a>,
|
||||
) -> StorePattern<'a> {
|
||||
use Pattern::*;
|
||||
|
@ -1526,6 +1544,8 @@ fn store_list_pattern<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
stmt = store_list_rest(env, list_sym, list_arity, list_layout, opt_rest, stmt);
|
||||
|
||||
if is_productive {
|
||||
StorePattern::Productive(stmt)
|
||||
} else {
|
||||
|
@ -1533,6 +1553,64 @@ fn store_list_pattern<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn store_list_rest<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
list_sym: Symbol,
|
||||
list_arity: ListArity,
|
||||
list_layout: InLayout<'a>,
|
||||
opt_rest: &Option<(usize, Option<Symbol>)>,
|
||||
mut stmt: Stmt<'a>,
|
||||
) -> Stmt<'a> {
|
||||
if let Some((index, Some(rest_sym))) = opt_rest {
|
||||
let usize_layout = Layout::usize(env.target_info);
|
||||
|
||||
let total_dropped = list_arity.min_len();
|
||||
|
||||
let total_dropped_sym = env.unique_symbol();
|
||||
let total_dropped_expr = Expr::Literal(Literal::Int((total_dropped as u128).to_ne_bytes()));
|
||||
|
||||
let list_len_sym = env.unique_symbol();
|
||||
let list_len_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::ListLen,
|
||||
update_mode: env.next_update_mode_id(),
|
||||
},
|
||||
arguments: env.arena.alloc([list_sym]),
|
||||
});
|
||||
|
||||
let rest_len_sym = env.unique_symbol();
|
||||
let rest_len_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::NumSub,
|
||||
update_mode: env.next_update_mode_id(),
|
||||
},
|
||||
arguments: env.arena.alloc([list_len_sym, total_dropped_sym]),
|
||||
});
|
||||
|
||||
let start_sym = env.unique_symbol();
|
||||
let start_expr = Expr::Literal(Literal::Int((*index as u128).to_ne_bytes()));
|
||||
|
||||
let rest_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::ListSublist,
|
||||
update_mode: env.next_update_mode_id(),
|
||||
},
|
||||
arguments: env.arena.alloc([list_sym, start_sym, rest_len_sym]),
|
||||
});
|
||||
let needed_stores = [
|
||||
(total_dropped_sym, total_dropped_expr, usize_layout),
|
||||
(list_len_sym, list_len_expr, usize_layout),
|
||||
(rest_len_sym, rest_len_expr, usize_layout),
|
||||
(start_sym, start_expr, usize_layout),
|
||||
(*rest_sym, rest_expr, list_layout),
|
||||
];
|
||||
for (sym, expr, lay) in needed_stores.into_iter().rev() {
|
||||
stmt = Stmt::Let(sym, expr, lay, env.arena.alloc(stmt));
|
||||
}
|
||||
}
|
||||
stmt
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn store_tag_pattern<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue