wip lots of shared references

This commit is contained in:
Richard Feldman 2019-10-29 01:12:15 -04:00
parent 4894293e6b
commit 01d84c7221
2 changed files with 84 additions and 68 deletions

View file

@ -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

View file

@ -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),
} }