mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
WIP stuck on removing Defs
This commit is contained in:
parent
406ffdffab
commit
d6a01b3014
2 changed files with 159 additions and 51 deletions
|
@ -144,34 +144,121 @@ pub fn desugar_defs_node_values<'a>(
|
|||
}
|
||||
|
||||
fn desugar_defs_node_suffixed<'a>(
|
||||
_arena: &'a Bump,
|
||||
_src: &'a str,
|
||||
_line_info: &mut Option<LineInfo>,
|
||||
_module_path: &str,
|
||||
arena: &'a Bump,
|
||||
src: &'a str,
|
||||
line_info: &mut Option<LineInfo>,
|
||||
module_path: &str,
|
||||
loc_expr: &'a Loc<Expr<'a>>,
|
||||
) -> &'a Loc<Expr<'a>> {
|
||||
match loc_expr.value {
|
||||
Defs(defs, _loc_ret) => {
|
||||
match search_suffixed_defs(&defs.value_defs, 0) {
|
||||
FindSuffixedDefs::NoneFound => loc_expr,
|
||||
FindSuffixedDefs::FirstSuffixedAtIndex(index) => {
|
||||
Defs(defs, loc_ret) => {
|
||||
match defs.search_suffixed_defs() {
|
||||
None => loc_expr,
|
||||
Some((tag_index, value_index)) => {
|
||||
if defs.value_defs.len() == 1 {
|
||||
assert!(index == 0, "we have only one value_def and so it must be Suffixed ");
|
||||
// We have only one value_def and it must be Suffixed
|
||||
// We have only one value_def and it must be Suffixed
|
||||
// replace Defs with an Apply(Task.await) and Closure of loc_return
|
||||
|
||||
dbg!("We have only one value_def and it must be Suffixed", loc_expr.value);
|
||||
assert!(
|
||||
value_index == 0,
|
||||
"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
|
||||
);
|
||||
|
||||
loc_expr
|
||||
} else if index == 0 {
|
||||
assert!(defs.value_defs.len() > 1, "we know we have other Defs that will need to be considered");
|
||||
} else if value_index == 0 {
|
||||
// We have a Suffixed in first index, and also other nodes in Defs
|
||||
// pop the first Suffixed and recurse on Defs (without first) to handle any other Suffixed
|
||||
// the result will be wrapped in an Apply(Task.await) and Closure
|
||||
|
||||
dbg!("We have a Suffixed in first index, and also other nodes in Defs", loc_expr.value);
|
||||
assert!(
|
||||
defs.value_defs.len() > 1,
|
||||
"we know we have other Defs that will need to be considered"
|
||||
);
|
||||
|
||||
loc_expr
|
||||
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
|
||||
let (suffixed_sub_apply_loc, pattern) = match defs.value_defs[0] {
|
||||
ValueDef::Body(pattern, suffixed_expression) => {
|
||||
match suffixed_expression.value {
|
||||
Apply(sub_loc, suffixed_args, called_via) => {
|
||||
match sub_loc.value {
|
||||
Suffixed(sub_expr) => (
|
||||
Apply(
|
||||
arena
|
||||
.alloc(Loc::at(loc_expr.region, *sub_expr)),
|
||||
suffixed_args,
|
||||
called_via,
|
||||
),
|
||||
pattern,
|
||||
),
|
||||
_ => unreachable!(
|
||||
"should have a suffixed Apply inside Body def"
|
||||
),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
unreachable!("should have a suffixed Apply inside Body def")
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => unreachable!("should have a suffixed Body def"),
|
||||
};
|
||||
|
||||
// Get a mutable copy of the defs
|
||||
let mut copied_defs = defs.clone();
|
||||
|
||||
// Remove the suffixed def
|
||||
copied_defs.remove_value_def(tag_index);
|
||||
|
||||
dbg!(&copied_defs);
|
||||
|
||||
// Recurse using new Defs to get new expression
|
||||
let new_loc_expr = desugar_defs_node_suffixed(
|
||||
arena,
|
||||
src,
|
||||
line_info,
|
||||
module_path,
|
||||
arena.alloc(Loc::at(
|
||||
loc_expr.region,
|
||||
Defs(arena.alloc(copied_defs), loc_ret),
|
||||
)),
|
||||
);
|
||||
|
||||
// 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]), new_loc_expr);
|
||||
|
||||
// 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)));
|
||||
|
||||
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,
|
||||
),
|
||||
))
|
||||
} else {
|
||||
// The first Suffixed is in the middle of our Defs
|
||||
// We will keep the value_defs before the Suffixed in our Defs node
|
||||
|
@ -179,46 +266,20 @@ fn desugar_defs_node_suffixed<'a>(
|
|||
// Then recurse on the new Defs node, wrap the result in an Apply(Task.await) and Closure,
|
||||
// which will become the new loc_return
|
||||
|
||||
dbg!("The first Suffixed is in the middle of our Defs", loc_expr.value);
|
||||
|
||||
dbg!(
|
||||
"The first Suffixed is in the middle of our Defs",
|
||||
loc_expr.value
|
||||
);
|
||||
|
||||
loc_expr
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => unreachable!("should only be passed a Defs node as it is called from within desugar_expr for Defs"),
|
||||
}
|
||||
}
|
||||
|
||||
enum FindSuffixedDefs {
|
||||
NoneFound,
|
||||
FirstSuffixedAtIndex(usize),
|
||||
}
|
||||
|
||||
fn search_suffixed_defs<'a>(value_defs: &std::vec::Vec<ValueDef<'a>>, index: usize) -> FindSuffixedDefs {
|
||||
|
||||
use roc_parse::ast::ValueDef::Body;
|
||||
|
||||
if index < value_defs.len() {
|
||||
match value_defs.get(index) {
|
||||
Some(Body(_, expr)) =>
|
||||
match expr.value {
|
||||
Apply(sub_expr,_,_) => {
|
||||
match sub_expr.value {
|
||||
roc_parse::ast::Expr::Suffixed(_) => {
|
||||
FindSuffixedDefs::FirstSuffixedAtIndex(index)
|
||||
}
|
||||
_ => search_suffixed_defs(value_defs, index + 1),
|
||||
}
|
||||
}
|
||||
_ => search_suffixed_defs(value_defs, index + 1),
|
||||
}
|
||||
_ => search_suffixed_defs(value_defs, index + 1),
|
||||
}
|
||||
} else {
|
||||
FindSuffixedDefs::NoneFound
|
||||
_ => unreachable!(
|
||||
"should only be passed a Defs node as it is called from within desugar_expr for Defs"
|
||||
),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Reorder the expression tree based on operator precedence and associativity rules,
|
||||
|
@ -452,7 +513,7 @@ pub fn desugar_expr<'a>(
|
|||
line_info,
|
||||
module_path,
|
||||
arena.alloc(Loc::at(loc_expr.region, Defs(arena.alloc(defs), loc_ret))),
|
||||
)
|
||||
)
|
||||
}
|
||||
Apply(loc_fn, loc_args, called_via) => {
|
||||
let mut desugared_args = Vec::with_capacity_in(loc_args.len(), arena);
|
||||
|
@ -710,7 +771,7 @@ pub fn desugar_expr<'a>(
|
|||
arena.alloc(Loc {
|
||||
value: Suffixed(expr),
|
||||
region: loc_expr.region,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -494,6 +494,26 @@ impl<'a> Defs<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn remove_value_def(&mut self, index: usize) {
|
||||
match self
|
||||
.tags
|
||||
.get(index)
|
||||
.expect("got an invalid index for Defs")
|
||||
.split()
|
||||
{
|
||||
Ok(type_index) => {
|
||||
self.type_defs.remove(type_index.index());
|
||||
}
|
||||
Err(value_index) => {
|
||||
self.value_defs.remove(value_index.index());
|
||||
}
|
||||
}
|
||||
self.tags.remove(index);
|
||||
self.regions.remove(index);
|
||||
self.space_after.remove(index);
|
||||
self.space_before.remove(index);
|
||||
}
|
||||
|
||||
/// NOTE assumes the def itself is pushed already!
|
||||
fn push_def_help(
|
||||
&mut self,
|
||||
|
@ -549,6 +569,33 @@ impl<'a> Defs<'a> {
|
|||
let tag = EitherIndex::from_left(type_def_index);
|
||||
self.push_def_help(tag, region, spaces_before, spaces_after)
|
||||
}
|
||||
|
||||
// Find the first definition that is a Apply Suffixed
|
||||
// We need the tag_index so we can use it to remove the value
|
||||
// We need the value index to know if it is the first
|
||||
pub fn search_suffixed_defs(&self) -> Option<(usize, usize)> {
|
||||
for (tag_index, tag) in self.tags.iter().enumerate() {
|
||||
let index = match tag.split() {
|
||||
Ok(_) => break,
|
||||
Err(value_index) => value_index.index(),
|
||||
};
|
||||
|
||||
match &self.value_defs[index] {
|
||||
ValueDef::Body(_, expr) => match expr.value {
|
||||
Expr::Apply(sub_expr, _, _) => match sub_expr.value {
|
||||
Expr::Suffixed(_) => {
|
||||
return Some((tag_index, index));
|
||||
}
|
||||
_ => break,
|
||||
},
|
||||
_ => break,
|
||||
},
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Should always be a zero-argument `Apply`; we'll check this in canonicalization
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue