handle Suffixed is in the middle of our Defs

This commit is contained in:
Luke Boswell 2024-03-20 11:48:08 +11:00
parent 248c2a3f34
commit cc10df6db9
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
2 changed files with 84 additions and 30 deletions

View file

@ -164,11 +164,6 @@ fn desugar_defs_node_suffixed<'a>(
"we have only one value_def and so it must be Suffixed " "we have only one value_def and so it must be Suffixed "
); );
dbg!(
"We have only one value_def and it must be Suffixed",
loc_expr.value
);
// Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await // Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await
let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern( let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern(
arena, arena,
@ -212,11 +207,6 @@ fn desugar_defs_node_suffixed<'a>(
"we know we have other Defs that will need to be considered" "we know we have other Defs that will need to be considered"
); );
dbg!(
"We have a Suffixed in first index, and also other nodes in Defs",
loc_expr.value
);
// Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await // Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await
let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern( let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern(
arena, arena,
@ -270,17 +260,70 @@ fn desugar_defs_node_suffixed<'a>(
)) ))
} else { } else {
// The first Suffixed is in the middle of our Defs // The first Suffixed is in the middle of our Defs
// We will keep the value_defs before the Suffixed in our Defs node // We will keep the defs before the Suffixed in our Defs node
// We take the value_defs after the Suffixed and create a new Defs node using the current loc_return // We take the defs after the Suffixed and create a new Defs node using the current loc_return
// Then recurse on the new Defs node, wrap the result in an Apply(Task.await) and Closure, // Then recurse on the new Defs node, wrap the result in an Apply(Task.await) and Closure,
// which will become the new loc_return // which will become the new loc_return
dbg!( let (before, after) = defs.split_values_either_side_of(tag_index);
"The first Suffixed is in the middle of our Defs",
loc_expr.value // If there are no defs after, then just use loc_ret as we dont need a Defs node
let defs_after_suffixed_desugared = {
if after.len() > 0 {
desugar_defs_node_suffixed(
arena,
src,
line_info,
module_path,
arena.alloc(Loc::at(
loc_expr.region,
Defs(arena.alloc(after), loc_ret),
)),
)
} else {
loc_ret
}
};
// Unwrap Suffixed def within Apply, and the pattern so we can use in the call to Task.await
let (suffixed_sub_apply_loc, pattern) = unwrap_suffixed_def_and_pattern(
arena,
loc_expr.region,
defs.value_defs[value_index],
); );
loc_expr // Create Closure for the result of the recursion,
// use the pattern from our Suffixed Def as closure arument
let closure_expr =
Closure(arena.alloc([*pattern]), defs_after_suffixed_desugared);
// Apply arguments to Task.await, first is the unwrapped Suffix expr second is the Closure
let mut task_await_apply_args: Vec<&'a Loc<Expr<'a>>> = Vec::new_in(arena);
task_await_apply_args
.push(arena.alloc(Loc::at(loc_expr.region, suffixed_sub_apply_loc)));
task_await_apply_args
.push(arena.alloc(Loc::at(loc_expr.region, closure_expr)));
let new_loc_return = arena.alloc(Loc::at(
loc_expr.region,
Apply(
arena.alloc(Loc {
region: loc_expr.region,
value: Var {
module_name: ModuleName::TASK,
ident: "await",
},
}),
arena.alloc(task_await_apply_args),
CalledVia::Space,
),
));
arena.alloc(Loc::at(
loc_expr.region,
Defs(arena.alloc(before), new_loc_return),
))
} }
} }
} }

View file

@ -503,7 +503,6 @@ impl<'a> Defs<'a> {
.split() .split()
{ {
Ok(type_index) => { Ok(type_index) => {
let index = type_index.index(); let index = type_index.index();
// remove from vec // remove from vec
@ -511,16 +510,13 @@ impl<'a> Defs<'a> {
// update all of the remaining indexes in type_defs // update all of the remaining indexes in type_defs
for (tag_index, tag) in self.tags.iter_mut().enumerate() { for (tag_index, tag) in self.tags.iter_mut().enumerate() {
// only update later indexes into type_defs // only update later indexes into type_defs
if tag_index > index && tag.split().is_ok() { if tag_index > index && tag.split().is_ok() {
tag.decrement_index(); tag.decrement_index();
} }
} }
} }
Err(value_index) => { Err(value_index) => {
let index: usize = value_index.index(); let index: usize = value_index.index();
// remove from vec // remove from vec
@ -528,13 +524,11 @@ impl<'a> Defs<'a> {
// update all of the remaining indexes in value_defs // update all of the remaining indexes in value_defs
for (tag_index, tag) in self.tags.iter_mut().enumerate() { for (tag_index, tag) in self.tags.iter_mut().enumerate() {
// only update later indexes into value_defs // only update later indexes into value_defs
if tag_index > index && tag.split().is_err() { if tag_index > index && tag.split().is_err() {
tag.decrement_index(); tag.decrement_index();
} }
} }
} }
} }
self.tags.remove(index); self.tags.remove(index);
@ -605,7 +599,7 @@ impl<'a> Defs<'a> {
pub fn search_suffixed_defs(&self) -> Option<(usize, usize)> { pub fn search_suffixed_defs(&self) -> Option<(usize, usize)> {
for (tag_index, tag) in self.tags.iter().enumerate() { for (tag_index, tag) in self.tags.iter().enumerate() {
let index = match tag.split() { let index = match tag.split() {
Ok(_) => break, Ok(_) => continue,
Err(value_index) => value_index.index(), Err(value_index) => value_index.index(),
}; };
@ -615,16 +609,33 @@ impl<'a> Defs<'a> {
Expr::Suffixed(_) => { Expr::Suffixed(_) => {
return Some((tag_index, index)); return Some((tag_index, index));
} }
_ => break, _ => continue,
}, },
_ => break, _ => continue,
}, },
_ => break, _ => continue,
} }
} }
None None
} }
// For desugaring Suffixed Defs we need to split the defs around the Suffixed value
pub fn split_values_either_side_of(&self, index: usize) -> (Self, Self) {
let mut before = self.clone();
let mut after = self.clone();
before.tags = self.tags[0..index].to_vec();
if index + 1 > self.tags.len() {
after.tags = self.tags.clone();
after.tags.clear();
} else {
after.tags = self.tags[(index + 1)..].to_vec();
}
(before, after)
}
} }
/// Should always be a zero-argument `Apply`; we'll check this in canonicalization /// Should always be a zero-argument `Apply`; we'll check this in canonicalization