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