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
|
// 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
|
// operators, and thena again on *their* nested operators, ultimately applying the
|
||||||
// rules multiple times unnecessarily.
|
// 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,
|
// 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"
|
// 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
|
// Used in constraint generation
|
||||||
let rigid_info = Info::with_capacity(defs.len());
|
let rigid_info = Info::with_capacity(defs.len());
|
||||||
let mut flex_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() {
|
while let Some(loc_def) = iter.next() {
|
||||||
// Each assignment gets to have all the idents in scope that are assigned in this
|
// 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,
|
/// 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.
|
/// 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 operator::Associativity::*;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
match &loc_expr.value {
|
match expr {
|
||||||
Float(_)
|
Float(_)
|
||||||
| Int(_)
|
| Int(_)
|
||||||
| HexInt(_)
|
| HexInt(_)
|
||||||
|
@ -51,30 +51,33 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
||||||
| MalformedIdent(_)
|
| MalformedIdent(_)
|
||||||
| MalformedClosure
|
| MalformedClosure
|
||||||
| PrecedenceConflict(_, _, _)
|
| PrecedenceConflict(_, _, _)
|
||||||
| Variant(_, _) => loc_expr,
|
| Variant(_, _) => Located {
|
||||||
|
value: expr,
|
||||||
|
region,
|
||||||
|
},
|
||||||
|
|
||||||
Field(sub_expr, paths) => arena.alloc(Located {
|
Field(sub_expr, paths) => Located {
|
||||||
region: loc_expr.region,
|
region,
|
||||||
value: Field(desugar(arena, sub_expr), paths.clone()),
|
value: Field(
|
||||||
}),
|
arena.alloc(desugar(arena, sub_expr.value, sub_expr.region)),
|
||||||
|
paths.clone(),
|
||||||
|
),
|
||||||
|
},
|
||||||
List(elems) => {
|
List(elems) => {
|
||||||
let mut new_elems = Vec::with_capacity_in(elems.len(), arena);
|
let mut new_elems = Vec::with_capacity_in(elems.len(), arena);
|
||||||
|
|
||||||
for elem in elems {
|
for loc_elem in elems.into_iter() {
|
||||||
new_elems.push(desugar(arena, elem));
|
new_elems.push(&*arena.alloc(desugar(arena, loc_elem.value, loc_elem.region)));
|
||||||
}
|
}
|
||||||
let value: Expr<'a> = List(new_elems);
|
let value: Expr<'a> = List(new_elems);
|
||||||
|
|
||||||
arena.alloc(Located {
|
Located { region, value }
|
||||||
region: loc_expr.region,
|
|
||||||
value,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Record(fields) => {
|
Record(fields) => {
|
||||||
let mut new_fields = Vec::with_capacity_in(fields.len(), arena);
|
let mut new_fields = Vec::with_capacity_in(fields.len(), arena);
|
||||||
|
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let value = desugar_field(arena, &field.value);
|
let value = desugar_field(arena, field.value);
|
||||||
|
|
||||||
new_fields.push(Located {
|
new_fields.push(Located {
|
||||||
value,
|
value,
|
||||||
|
@ -82,17 +85,23 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
arena.alloc(Located {
|
Located {
|
||||||
region: loc_expr.region,
|
region,
|
||||||
value: Record(new_fields),
|
value: Record(new_fields),
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Closure(loc_patterns, loc_ret) => arena.alloc(Located {
|
}
|
||||||
region: loc_expr.region,
|
Closure(loc_patterns, loc_ret) => Located {
|
||||||
value: Closure(loc_patterns, desugar(arena, loc_ret)),
|
region,
|
||||||
}),
|
value: Closure(
|
||||||
|
loc_patterns,
|
||||||
|
&*arena.alloc(desugar(arena, loc_ret.value, loc_ret.region)),
|
||||||
|
),
|
||||||
|
},
|
||||||
Operator(_) => {
|
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 arg_stack: Vec<&'a Located<Expr>> = Vec::new_in(arena);
|
||||||
let mut op_stack: Vec<Located<Operator>> = 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),
|
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);
|
assert_eq!(arg_stack.len(), 1);
|
||||||
|
|
||||||
arg_stack.pop().unwrap()
|
*arg_stack.pop().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
Defs(defs, loc_ret) => {
|
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() {
|
for loc_def in defs.into_iter() {
|
||||||
let loc_def = &*arena.alloc(Located {
|
let loc_def = &*arena.alloc(Located {
|
||||||
// TODO try to avoid this clone() if possible
|
value: desugar_def(arena, loc_def.value),
|
||||||
value: desugar_def(arena, loc_def.value, loc_expr),
|
|
||||||
region: loc_def.region,
|
region: loc_def.region,
|
||||||
});
|
});
|
||||||
|
|
||||||
desugared_defs.push(loc_def);
|
desugared_defs.push(loc_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
arena.alloc(Located {
|
Located {
|
||||||
value: Defs(desugared_defs, desugar(arena, loc_ret)),
|
value: Defs(
|
||||||
region: loc_expr.region,
|
desugared_defs,
|
||||||
})
|
&*arena.alloc(desugar(arena, loc_ret.value, loc_ret.region)),
|
||||||
|
),
|
||||||
|
region,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Apply(loc_fn, loc_args, called_via) => {
|
Apply(loc_fn, loc_args, called_via) => {
|
||||||
let mut desugared_args = Vec::with_capacity_in(loc_args.len(), arena);
|
let mut desugared_args = Vec::with_capacity_in(loc_args.len(), arena);
|
||||||
|
|
||||||
for loc_arg in loc_args {
|
for loc_arg in loc_args.into_iter() {
|
||||||
desugared_args.push(desugar(arena, loc_arg));
|
desugared_args.push(&*arena.alloc(desugar(arena, loc_arg.value, loc_arg.region)));
|
||||||
}
|
}
|
||||||
|
|
||||||
arena.alloc(Located {
|
Located {
|
||||||
value: Apply(desugar(arena, loc_fn), desugared_args, called_via.clone()),
|
value: Apply(
|
||||||
region: loc_expr.region,
|
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>>)),
|
// If(&'a (Loc<Expr<'a>>, Loc<Expr<'a>>, Loc<Expr<'a>>)),
|
||||||
// Case(
|
// Case(
|
||||||
|
@ -267,7 +282,6 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
||||||
// and should be dropped.
|
// and should be dropped.
|
||||||
desugar(
|
desugar(
|
||||||
arena,
|
arena,
|
||||||
arena.alloc(Located {
|
|
||||||
// TODO FIXME performance disaster!!! Must remove this clone!
|
// TODO FIXME performance disaster!!! Must remove this clone!
|
||||||
//
|
//
|
||||||
// This won't be easy because:
|
// This won't be easy because:
|
||||||
|
@ -275,9 +289,8 @@ pub fn desugar<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a Loca
|
||||||
// * If this function takes an &'a Expr, then Infixes hits a problem.
|
// * 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 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?
|
// * If all the existing &'a Loc<Expr> values become Loc<&'a Expr>...who knows?
|
||||||
value: (*expr).clone(),
|
// (*expr).clone(),
|
||||||
region: loc_expr.region,
|
*expr, region,
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SpaceAfter(expr, _) => {
|
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.
|
// and should be dropped.
|
||||||
desugar(
|
desugar(
|
||||||
arena,
|
arena,
|
||||||
arena.alloc(Located {
|
|
||||||
// TODO FIXME performance disaster!!! Must remove this clone! (Not easy.)
|
// TODO FIXME performance disaster!!! Must remove this clone! (Not easy.)
|
||||||
value: (*expr).clone(),
|
// (*expr).clone(),
|
||||||
region: loc_expr.region,
|
*expr, region,
|
||||||
}),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
other => panic!("TODO desugar {:?}", other),
|
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 {
|
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::Annotation(_, _) => def,
|
||||||
Def::CustomType(_, _) => def,
|
Def::CustomType(_, _) => def,
|
||||||
Def::TypeAlias(_, _) => def,
|
Def::TypeAlias(_, _) => def,
|
||||||
Def::SpaceBefore(other_def, _) => desugar_def(arena, other_def, loc_expr),
|
Def::SpaceBefore(other_def, _) | Def::SpaceAfter(other_def, _) => {
|
||||||
Def::SpaceAfter(_, _) => def,
|
desugar_def(arena, *other_def)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugar_field<'a>(
|
fn desugar_field<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
field: &'a AssignedField<'a, Expr<'a>>,
|
field: AssignedField<'a, Expr<'a>>,
|
||||||
) -> AssignedField<'a, Expr<'a>> {
|
) -> AssignedField<'a, Expr<'a>> {
|
||||||
use parse::ast::AssignedField::*;
|
use parse::ast::AssignedField::*;
|
||||||
|
|
||||||
match field {
|
match field {
|
||||||
LabeledValue(ref loc_str, spaces, loc_expr) => {
|
LabeledValue(ref loc_str, spaces, loc_expr) => AssignedField::LabeledValue(
|
||||||
AssignedField::LabeledValue(loc_str.clone(), spaces, desugar(arena, loc_expr))
|
loc_str.clone(),
|
||||||
}
|
spaces,
|
||||||
LabelOnly(ref loc_str, spaces) => LabelOnly(loc_str.clone(), spaces),
|
arena.alloc(desugar(arena, loc_expr.value, loc_expr.region)),
|
||||||
SpaceBefore(ref field, spaces) => {
|
),
|
||||||
SpaceBefore(arena.alloc(desugar_field(arena, field)), spaces)
|
LabelOnly(loc_str, spaces) => LabelOnly(loc_str, spaces),
|
||||||
}
|
SpaceBefore(field, spaces) => {
|
||||||
SpaceAfter(ref field, spaces) => {
|
SpaceBefore(arena.alloc(desugar_field(arena, *field)), spaces)
|
||||||
SpaceAfter(arena.alloc(desugar_field(arena, field)), spaces)
|
|
||||||
}
|
}
|
||||||
|
SpaceAfter(field, spaces) => SpaceAfter(arena.alloc(desugar_field(arena, *field)), spaces),
|
||||||
|
|
||||||
Malformed(string) => Malformed(string),
|
Malformed(string) => Malformed(string),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue