refactor Path -> Expr conversion

This commit is contained in:
Folkert 2020-11-13 17:04:22 +01:00
parent 11ea52731c
commit 0c86d09ccf

View file

@ -935,32 +935,59 @@ pub fn optimize_when<'a>(
) )
} }
fn path_to_expr_help<'a>( #[derive(Debug)]
env: &mut Env<'a, '_>, struct PathInstruction {
mut symbol: Symbol, index: u64,
mut path: &Path, tag_id: u8,
mut layout: Layout<'a>, }
) -> (Symbol, StoresVec<'a>, Layout<'a>) {
let mut stores = bumpalo::collections::Vec::new_in(env.arena); fn reverse_path(mut path: &Path) -> Vec<PathInstruction> {
let mut result = Vec::new();
loop { loop {
match path { match path {
Path::Unbox(unboxed) => { Path::Unbox(nested) => {
path = unboxed; path = nested;
} }
Path::Empty => break, Path::Empty => break,
Path::Index { Path::Index {
index, index,
tag_id, tag_id,
path: nested, path: nested,
} => match Wrapped::opt_from_layout(&layout) { } => {
result.push(PathInstruction {
index: *index,
tag_id: *tag_id,
});
path = nested;
}
}
}
result.reverse();
result
}
fn path_to_expr_help<'a>(
env: &mut Env<'a, '_>,
mut symbol: Symbol,
path: &Path,
mut layout: Layout<'a>,
) -> (Symbol, StoresVec<'a>, Layout<'a>) {
let mut stores = bumpalo::collections::Vec::new_in(env.arena);
let instructions = reverse_path(path);
let mut it = instructions.iter().peekable();
while let Some(PathInstruction { index, tag_id }) = it.next() {
match Wrapped::opt_from_layout(&layout) {
None => { None => {
// this MUST be an index into a single-element (hence unwrapped) record // this MUST be an index into a single-element (hence unwrapped) record
debug_assert_eq!(*index, 0); debug_assert_eq!(*index, 0);
debug_assert_eq!(*tag_id, 0); debug_assert_eq!(*tag_id, 0);
debug_assert_eq!(**nested, Path::Empty); debug_assert!(it.peek().is_none());
let field_layouts = vec![layout.clone()]; let field_layouts = vec![layout.clone()];
@ -982,10 +1009,10 @@ fn path_to_expr_help<'a>(
Some(wrapped) => { Some(wrapped) => {
let field_layouts = match &layout { let field_layouts = match &layout {
Layout::Union(layouts) | Layout::RecursiveUnion(layouts) => { Layout::Union(layouts) | Layout::RecursiveUnion(layouts) => {
layouts[*tag_id as usize].to_vec() layouts[*tag_id as usize]
} }
Layout::Struct(layouts) => layouts.to_vec(), Layout::Struct(layouts) => layouts,
other => vec![other.clone()], other => env.arena.alloc([other.clone()]),
}; };
debug_assert!(*index < field_layouts.len() as u64); debug_assert!(*index < field_layouts.len() as u64);
@ -997,7 +1024,7 @@ fn path_to_expr_help<'a>(
let inner_expr = Expr::AccessAtIndex { let inner_expr = Expr::AccessAtIndex {
index: *index, index: *index,
field_layouts: env.arena.alloc(field_layouts), field_layouts,
structure: symbol, structure: symbol,
wrapped, wrapped,
}; };
@ -1006,9 +1033,7 @@ fn path_to_expr_help<'a>(
stores.push((symbol, inner_layout.clone(), inner_expr)); stores.push((symbol, inner_layout.clone(), inner_expr));
layout = inner_layout; layout = inner_layout;
path = nested;
} }
},
} }
} }