mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
wip lots of shared references
This commit is contained in:
parent
4894293e6b
commit
01d84c7221
2 changed files with 84 additions and 68 deletions
|
@ -55,7 +55,7 @@ pub fn canonicalize_declaration<'a>(
|
|||
// visited an Operator node we'd recursively try to apply this to each of its nested
|
||||
// operators, and thena again on *their* nested operators, ultimately applying the
|
||||
// rules multiple times unnecessarily.
|
||||
let loc_expr = operator::desugar(arena, &loc_expr);
|
||||
let loc_expr = operator::desugar(arena, loc_expr.value, loc_expr.region);
|
||||
|
||||
// If we're canonicalizing the declaration `foo = ...` inside the `Main` module,
|
||||
// scope_prefix will be "Main.foo$" and its first closure will be named "Main.foo$0"
|
||||
|
@ -1287,7 +1287,7 @@ fn can_defs<'a>(
|
|||
// Used in constraint generation
|
||||
let rigid_info = Info::with_capacity(defs.len());
|
||||
let mut flex_info = Info::with_capacity(defs.len());
|
||||
let mut iter = defs.iter();
|
||||
let mut iter = defs.into_iter();
|
||||
|
||||
while let Some(loc_def) = iter.next() {
|
||||
// Each assignment gets to have all the idents in scope that are assigned in this
|
||||
|
|
|
@ -33,11 +33,11 @@ fn new_op_expr<'a>(
|
|||
|
||||
/// Reorder the expression tree based on operator precedence and associativity rules,
|
||||
/// then replace the Operator nodes with Apply nodes. Also drop SpaceBefore and SpaceAfter nodes.
|
||||
pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Located<Expr<'a>> {
|
||||
pub fn desugar<'a>(arena: &'a Bump, expr: Expr<'a>, region: Region) -> Located<Expr<'a>> {
|
||||
use operator::Associativity::*;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
match &loc_expr.value {
|
||||
match expr {
|
||||
Float(_)
|
||||
| Int(_)
|
||||
| HexInt(_)
|
||||
|
@ -51,30 +51,33 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
| MalformedIdent(_)
|
||||
| MalformedClosure
|
||||
| PrecedenceConflict(_, _, _)
|
||||
| Variant(_, _) => loc_expr,
|
||||
| Variant(_, _) => Located {
|
||||
value: expr,
|
||||
region,
|
||||
},
|
||||
|
||||
Field(sub_expr, paths) => arena.alloc(Located {
|
||||
region: loc_expr.region,
|
||||
value: Field(desugar(arena, sub_expr), paths.clone()),
|
||||
}),
|
||||
Field(sub_expr, paths) => Located {
|
||||
region,
|
||||
value: Field(
|
||||
arena.alloc(desugar(arena, sub_expr.value, sub_expr.region)),
|
||||
paths.clone(),
|
||||
),
|
||||
},
|
||||
List(elems) => {
|
||||
let mut new_elems = Vec::with_capacity_in(elems.len(), arena);
|
||||
|
||||
for elem in elems {
|
||||
new_elems.push(desugar(arena, elem));
|
||||
for loc_elem in elems.into_iter() {
|
||||
new_elems.push(&*arena.alloc(desugar(arena, loc_elem.value, loc_elem.region)));
|
||||
}
|
||||
let value: Expr<'a> = List(new_elems);
|
||||
|
||||
arena.alloc(Located {
|
||||
region: loc_expr.region,
|
||||
value,
|
||||
})
|
||||
Located { region, value }
|
||||
}
|
||||
Record(fields) => {
|
||||
let mut new_fields = Vec::with_capacity_in(fields.len(), arena);
|
||||
|
||||
for field in fields {
|
||||
let value = desugar_field(arena, &field.value);
|
||||
let value = desugar_field(arena, field.value);
|
||||
|
||||
new_fields.push(Located {
|
||||
value,
|
||||
|
@ -82,17 +85,23 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
});
|
||||
}
|
||||
|
||||
arena.alloc(Located {
|
||||
region: loc_expr.region,
|
||||
Located {
|
||||
region,
|
||||
value: Record(new_fields),
|
||||
})
|
||||
}
|
||||
}
|
||||
Closure(loc_patterns, loc_ret) => arena.alloc(Located {
|
||||
region: loc_expr.region,
|
||||
value: Closure(loc_patterns, desugar(arena, loc_ret)),
|
||||
}),
|
||||
Closure(loc_patterns, loc_ret) => Located {
|
||||
region,
|
||||
value: Closure(
|
||||
loc_patterns,
|
||||
&*arena.alloc(desugar(arena, loc_ret.value, loc_ret.region)),
|
||||
),
|
||||
},
|
||||
Operator(_) => {
|
||||
let mut infixes = Infixes::new(arena.alloc(loc_expr));
|
||||
let mut infixes = Infixes::new(arena.alloc(Located {
|
||||
value: expr,
|
||||
region,
|
||||
}));
|
||||
let mut arg_stack: Vec<&'a Located<Expr>> = Vec::new_in(arena);
|
||||
let mut op_stack: Vec<Located<Operator>> = Vec::new_in(arena);
|
||||
|
||||
|
@ -167,7 +176,7 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
arena.alloc(broken_expr),
|
||||
);
|
||||
|
||||
return arena.alloc(Located { region, value });
|
||||
return Located { region, value };
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
@ -224,7 +233,7 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
|
||||
assert_eq!(arg_stack.len(), 1);
|
||||
|
||||
arg_stack.pop().unwrap()
|
||||
*arg_stack.pop().unwrap()
|
||||
}
|
||||
|
||||
Defs(defs, loc_ret) => {
|
||||
|
@ -232,30 +241,36 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
|
||||
for loc_def in defs.into_iter() {
|
||||
let loc_def = &*arena.alloc(Located {
|
||||
// TODO try to avoid this clone() if possible
|
||||
value: desugar_def(arena, loc_def.value, loc_expr),
|
||||
value: desugar_def(arena, loc_def.value),
|
||||
region: loc_def.region,
|
||||
});
|
||||
|
||||
desugared_defs.push(loc_def);
|
||||
}
|
||||
|
||||
arena.alloc(Located {
|
||||
value: Defs(desugared_defs, desugar(arena, loc_ret)),
|
||||
region: loc_expr.region,
|
||||
})
|
||||
Located {
|
||||
value: Defs(
|
||||
desugared_defs,
|
||||
&*arena.alloc(desugar(arena, loc_ret.value, loc_ret.region)),
|
||||
),
|
||||
region,
|
||||
}
|
||||
}
|
||||
Apply(loc_fn, loc_args, called_via) => {
|
||||
let mut desugared_args = Vec::with_capacity_in(loc_args.len(), arena);
|
||||
|
||||
for loc_arg in loc_args {
|
||||
desugared_args.push(desugar(arena, loc_arg));
|
||||
for loc_arg in loc_args.into_iter() {
|
||||
desugared_args.push(&*arena.alloc(desugar(arena, loc_arg.value, loc_arg.region)));
|
||||
}
|
||||
|
||||
arena.alloc(Located {
|
||||
value: Apply(desugar(arena, loc_fn), desugared_args, called_via.clone()),
|
||||
region: loc_expr.region,
|
||||
})
|
||||
Located {
|
||||
value: Apply(
|
||||
arena.alloc(desugar(arena, loc_fn.value, loc_fn.region)),
|
||||
desugared_args,
|
||||
called_via.clone(),
|
||||
),
|
||||
region,
|
||||
}
|
||||
}
|
||||
// If(&'a (Loc<Expr<'a>>, Loc<Expr<'a>>, Loc<Expr<'a>>)),
|
||||
// Case(
|
||||
|
@ -267,17 +282,15 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
// and should be dropped.
|
||||
desugar(
|
||||
arena,
|
||||
arena.alloc(Located {
|
||||
// TODO FIXME performance disaster!!! Must remove this clone!
|
||||
//
|
||||
// This won't be easy because:
|
||||
//
|
||||
// * If this function takes an &'a Expr, then Infixes hits a problem.
|
||||
// * If SpaceBefore holds a Loc<&'a Expr>, then Spaceable hits a problem.
|
||||
// * If all the existing &'a Loc<Expr> values become Loc<&'a Expr>...who knows?
|
||||
value: (*expr).clone(),
|
||||
region: loc_expr.region,
|
||||
}),
|
||||
// TODO FIXME performance disaster!!! Must remove this clone!
|
||||
//
|
||||
// This won't be easy because:
|
||||
//
|
||||
// * If this function takes an &'a Expr, then Infixes hits a problem.
|
||||
// * If SpaceBefore holds a Loc<&'a Expr>, then Spaceable hits a problem.
|
||||
// * If all the existing &'a Loc<Expr> values become Loc<&'a Expr>...who knows?
|
||||
// (*expr).clone(),
|
||||
*expr, region,
|
||||
)
|
||||
}
|
||||
SpaceAfter(expr, _) => {
|
||||
|
@ -285,44 +298,47 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
|||
// and should be dropped.
|
||||
desugar(
|
||||
arena,
|
||||
arena.alloc(Located {
|
||||
// TODO FIXME performance disaster!!! Must remove this clone! (Not easy.)
|
||||
value: (*expr).clone(),
|
||||
region: loc_expr.region,
|
||||
}),
|
||||
// TODO FIXME performance disaster!!! Must remove this clone! (Not easy.)
|
||||
// (*expr).clone(),
|
||||
*expr, region,
|
||||
)
|
||||
}
|
||||
other => panic!("TODO desugar {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
fn desugar_def<'a>(arena: &'a Bump, def: &'a Def<'a>, loc_expr: &'a Located<Expr<'a>>) -> Def<'a> {
|
||||
fn desugar_def<'a>(arena: &'a Bump, def: Def<'a>) -> Def<'a> {
|
||||
match def {
|
||||
Def::Body(pattern, loc_expr) => Def::Body(pattern.clone(), desugar(arena, loc_expr)),
|
||||
Def::Body(pattern, loc_expr) => Def::Body(
|
||||
pattern,
|
||||
arena.alloc(desugar(arena, loc_expr.value, loc_expr.region)),
|
||||
),
|
||||
Def::Annotation(_, _) => def,
|
||||
Def::CustomType(_, _) => def,
|
||||
Def::TypeAlias(_, _) => def,
|
||||
Def::SpaceBefore(other_def, _) => desugar_def(arena, other_def, loc_expr),
|
||||
Def::SpaceAfter(_, _) => def,
|
||||
Def::SpaceBefore(other_def, _) | Def::SpaceAfter(other_def, _) => {
|
||||
desugar_def(arena, *other_def)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn desugar_field<'a>(
|
||||
arena: &'a Bump,
|
||||
field: &'a AssignedField<'a, Expr<'a>>,
|
||||
field: AssignedField<'a, Expr<'a>>,
|
||||
) -> AssignedField<'a, Expr<'a>> {
|
||||
use parse::ast::AssignedField::*;
|
||||
|
||||
match field {
|
||||
LabeledValue(ref loc_str, spaces, loc_expr) => {
|
||||
AssignedField::LabeledValue(loc_str.clone(), spaces, desugar(arena, loc_expr))
|
||||
}
|
||||
LabelOnly(ref loc_str, spaces) => LabelOnly(loc_str.clone(), spaces),
|
||||
SpaceBefore(ref field, spaces) => {
|
||||
SpaceBefore(arena.alloc(desugar_field(arena, field)), spaces)
|
||||
}
|
||||
SpaceAfter(ref field, spaces) => {
|
||||
SpaceAfter(arena.alloc(desugar_field(arena, field)), spaces)
|
||||
LabeledValue(ref loc_str, spaces, loc_expr) => AssignedField::LabeledValue(
|
||||
loc_str.clone(),
|
||||
spaces,
|
||||
arena.alloc(desugar(arena, loc_expr.value, loc_expr.region)),
|
||||
),
|
||||
LabelOnly(loc_str, spaces) => LabelOnly(loc_str, spaces),
|
||||
SpaceBefore(field, spaces) => {
|
||||
SpaceBefore(arena.alloc(desugar_field(arena, *field)), spaces)
|
||||
}
|
||||
SpaceAfter(field, spaces) => SpaceAfter(arena.alloc(desugar_field(arena, *field)), spaces),
|
||||
|
||||
Malformed(string) => Malformed(string),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue