use only references (no Vec) in canonical AST

This commit is contained in:
Folkert 2020-10-26 01:03:33 +01:00
parent b91a76bb5c
commit 93a1baad1d
7 changed files with 74 additions and 35 deletions

View File

@ -110,7 +110,7 @@ pub fn canonicalize_defs<'a>(
mut output: Output,
var_store: &mut VarStore,
original_scope: &Scope,
loc_defs: &'a bumpalo::collections::Vec<'a, &'a Located<ast::Def<'a>>>,
loc_defs: &'a [&'a Located<ast::Def<'a>>],
pattern_type: PatternType,
) -> (CanDefs, Scope, Output, MutMap<Symbol, Region>) {
// Canonicalizing defs while detecting shadowing involves a multi-step process:
@ -1239,7 +1239,7 @@ pub fn can_defs_with_return<'a>(
env: &mut Env<'a>,
var_store: &mut VarStore,
scope: Scope,
loc_defs: &'a bumpalo::collections::Vec<'a, &'a Located<ast::Def<'a>>>,
loc_defs: &'a [&'a Located<ast::Def<'a>>],
loc_ret: &'a Located<ast::Expr<'a>>,
) -> (Expr, Output) {
let (unsorted, mut scope, defs_output, symbols_introduced) = canonicalize_defs(

View File

@ -309,7 +309,7 @@ pub fn canonicalize_expr<'a>(
let mut args = Vec::new();
let mut outputs = Vec::new();
for loc_arg in loc_args {
for loc_arg in loc_args.iter() {
let (arg_expr, arg_out) =
canonicalize_expr(env, var_store, scope, loc_arg.region, &loc_arg.value);
@ -562,7 +562,7 @@ pub fn canonicalize_expr<'a>(
let mut can_branches = Vec::with_capacity(branches.len());
for branch in branches {
for branch in branches.iter() {
let (can_when_branch, branch_references) =
canonicalize_when_branch(env, var_store, scope, region, *branch, &mut output);
@ -788,7 +788,7 @@ fn canonicalize_when_branch<'a>(
let mut scope = original_scope.clone();
// TODO report symbols not bound in all patterns
for loc_pattern in &branch.patterns {
for loc_pattern in branch.patterns.iter() {
let (new_output, can_pattern) = canonicalize_pattern(
env,
var_store,

View File

@ -42,7 +42,7 @@ pub struct ModuleOutput {
#[allow(clippy::too_many_arguments)]
pub fn canonicalize_module_defs<'a>(
arena: &Bump,
loc_defs: bumpalo::collections::Vec<'a, Located<ast::Def<'a>>>,
loc_defs: &'a [Located<ast::Def<'a>>],
home: ModuleId,
module_ids: &ModuleIds,
exposed_ident_ids: IdentIds,
@ -65,9 +65,9 @@ pub fn canonicalize_module_defs<'a>(
let mut desugared =
bumpalo::collections::Vec::with_capacity_in(loc_defs.len() + num_deps, arena);
for loc_def in loc_defs {
for loc_def in loc_defs.iter() {
desugared.push(&*arena.alloc(Located {
value: desugar_def(arena, arena.alloc(loc_def.value)),
value: desugar_def(arena, &loc_def.value),
region: loc_def.region,
}));
}

View File

@ -90,9 +90,10 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
List(elems) | Nested(List(elems)) => {
let mut new_elems = Vec::with_capacity_in(elems.len(), arena);
for elem in elems {
for elem in elems.iter() {
new_elems.push(desugar_expr(arena, elem));
}
let new_elems = new_elems.into_bump_slice();
let value: Expr<'a> = List(new_elems);
arena.alloc(Located {
@ -103,7 +104,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
Record { fields, update } | Nested(Record { fields, update }) => {
let mut new_fields = Vec::with_capacity_in(fields.len(), arena);
for field in fields {
for field in fields.iter() {
let value = desugar_field(arena, &field.value);
new_fields.push(Located {
@ -112,6 +113,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
});
}
let new_fields = new_fields.into_bump_slice();
arena.alloc(Located {
region: loc_expr.region,
value: Record {
@ -139,6 +142,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
desugared_defs.push(&*arena.alloc(loc_def));
}
let desugared_defs = desugared_defs.into_bump_slice();
arena.alloc(Located {
value: Defs(desugared_defs, desugar_expr(arena, loc_ret)),
region: loc_expr.region,
@ -147,10 +152,12 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
Apply(loc_fn, loc_args, called_via) | Nested(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 {
for loc_arg in loc_args.iter() {
desugared_args.push(desugar_expr(arena, loc_arg));
}
let desugared_args = desugared_args.into_bump_slice();
arena.alloc(Located {
value: Apply(desugar_expr(arena, loc_fn), desugared_args, *called_via),
region: loc_expr.region,
@ -164,7 +171,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
let desugared = desugar_expr(arena, &branch.value);
let mut alternatives = Vec::with_capacity_in(branch.patterns.len(), arena);
for loc_pattern in &branch.patterns {
for loc_pattern in branch.patterns.iter() {
alternatives.push(Located {
region: loc_pattern.region,
value: Pattern::Nested(&loc_pattern.value),
@ -177,6 +184,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
None
};
let alternatives = alternatives.into_bump_slice();
desugared_branches.push(&*arena.alloc(WhenBranch {
patterns: alternatives,
value: Located {
@ -187,6 +196,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
}));
}
let desugared_branches = desugared_branches.into_bump_slice();
arena.alloc(Located {
value: When(loc_desugared_cond, desugared_branches),
region: loc_expr.region,
@ -213,6 +224,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'a>>) -> &'a
let loc_fn_var = arena.alloc(Located { region, value });
let desugared_args = bumpalo::vec![in arena; desugar_expr(arena, loc_arg)];
let desugared_args = desugared_args.into_bump_slice();
arena.alloc(Located {
value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)),
region: loc_expr.region,
@ -463,10 +476,12 @@ fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'_>>) -> &'a L
args.push(left);
for arg in arguments {
for arg in arguments.iter() {
args.push(arg);
}
let args = args.into_bump_slice();
Apply(function, args, CalledVia::BinOp(Pizza))
}
expr => {
@ -480,6 +495,8 @@ fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'_>>) -> &'a L
region: right.region,
});
let args = args.into_bump_slice();
Apply(function, args, CalledVia::BinOp(Pizza))
}
}
@ -498,6 +515,8 @@ fn desugar_bin_op<'a>(arena: &'a Bump, loc_expr: &'a Located<Expr<'_>>) -> &'a L
region: loc_op.region,
});
let args = args.into_bump_slice();
Apply(loc_expr, args, CalledVia::BinOp(binop))
}
};

View File

@ -32,7 +32,7 @@ pub struct DocEntry {
pub fn generate_module_docs<'a>(
module_name: ModuleName,
exposed_ident_ids: &'a IdentIds,
parsed_defs: &'a bumpalo::collections::Vec<'a, Located<Def<'a>>>,
parsed_defs: &'a [Located<Def<'a>>],
) -> ModuleDocumentation {
let (entries, _) =
parsed_defs

View File

@ -29,7 +29,7 @@ pub struct InterfaceHeader<'a> {
#[derive(Clone, Debug, PartialEq)]
pub struct WhenBranch<'a> {
pub patterns: Vec<'a, Loc<Pattern<'a>>>,
pub patterns: &'a [Loc<Pattern<'a>>],
pub value: Loc<Expr<'a>>,
pub guard: Option<Loc<Expr<'a>>>,
}
@ -188,10 +188,10 @@ pub enum Expr<'a> {
AccessorFunction(&'a str),
// Collection Literals
List(Vec<'a, &'a Loc<Expr<'a>>>),
List(&'a [&'a Loc<Expr<'a>>]),
Record {
update: Option<&'a Loc<Expr<'a>>>,
fields: Vec<'a, Loc<AssignedField<'a, Expr<'a>>>>,
fields: &'a [Loc<AssignedField<'a, Expr<'a>>>],
},
// Lookups
@ -205,14 +205,14 @@ pub enum Expr<'a> {
PrivateTag(&'a str),
// Pattern Matching
Closure(&'a Vec<'a, Loc<Pattern<'a>>>, &'a Loc<Expr<'a>>),
Closure(&'a [Loc<Pattern<'a>>], &'a Loc<Expr<'a>>),
/// Multiple defs in a row
Defs(Vec<'a, &'a Loc<Def<'a>>>, &'a Loc<Expr<'a>>),
Defs(&'a [&'a Loc<Def<'a>>], &'a Loc<Expr<'a>>),
// Application
/// To apply by name, do Apply(Var(...), ...)
/// To apply a tag by name, do Apply(Tag(...), ...)
Apply(&'a Loc<Expr<'a>>, Vec<'a, &'a Loc<Expr<'a>>>, CalledVia),
Apply(&'a Loc<Expr<'a>>, &'a [&'a Loc<Expr<'a>>], CalledVia),
BinOp(&'a (Loc<Expr<'a>>, Loc<BinOp>, Loc<Expr<'a>>)),
UnaryOp(&'a Loc<Expr<'a>>, Loc<UnaryOp>),
@ -226,7 +226,7 @@ pub enum Expr<'a> {
/// Vec, because there may be many patterns, and the guard
/// is Option<Expr> because each branch may be preceded by
/// a guard (".. if ..").
Vec<'a, &'a WhenBranch<'a>>,
&'a [&'a WhenBranch<'a>],
),
// Blank Space (e.g. comments, spaces, newlines) before or after an expression.

View File

@ -82,7 +82,7 @@ macro_rules! loc_parenthetical_expr {
region: loc_expr_with_extras.region,
value: Expr::Apply(
arena.alloc(loc_expr),
allocated_args,
allocated_args.into_bump_slice(),
CalledVia::Space,
),
},
@ -250,7 +250,7 @@ fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>,
let mut arg_patterns = Vec::with_capacity_in(loc_args.len(), arena);
for loc_arg in loc_args {
for loc_arg in loc_args.iter() {
let region = loc_arg.region;
let value = expr_to_pattern(arena, &loc_arg.value)?;
@ -279,7 +279,7 @@ fn expr_to_pattern<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<'a>,
} => {
let mut loc_patterns = Vec::with_capacity_in(fields.len(), arena);
for loc_assigned_field in fields {
for loc_assigned_field in fields.iter() {
let region = loc_assigned_field.region;
let value = assigned_expr_field_to_pattern(arena, &loc_assigned_field.value)?;
@ -691,7 +691,10 @@ fn parse_def_expr<'a>(
// for formatting reasons, we must insert the first def first!
defs.insert(0, arena.alloc(loc_first_def));
Ok((Expr::Defs(defs, arena.alloc(loc_ret)), state))
Ok((
Expr::Defs(defs.into_bump_slice(), arena.alloc(loc_ret)),
state,
))
},
)
.parse(arena, state)
@ -766,6 +769,8 @@ fn parse_def_signature<'a>(
// corresponding definition (the one with the body).
defs.insert(0, arena.alloc(loc_first_def));
let defs = defs.into_bump_slice();
Ok((Expr::Defs(defs, arena.alloc(loc_ret)), state))
},
)
@ -848,7 +853,12 @@ fn closure<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
),
|arena: &'a Bump, opt_contents| match opt_contents {
None => Expr::MalformedClosure,
Some((params, loc_body)) => Expr::Closure(arena.alloc(params), arena.alloc(loc_body)),
Some((params, loc_body)) => {
let params: Vec<'a, Located<Pattern<'a>>> = params;
let params: &'a [Located<Pattern<'a>>] = params.into_bump_slice();
Expr::Closure(params, arena.alloc(loc_body))
}
}
)
}
@ -1119,7 +1129,10 @@ mod when {
let (branches, state) =
attempt!(Attempting::WhenBranch, branches(min_indent)).parse(arena, state)?;
Ok((Expr::When(arena.alloc(loc_condition), branches), state))
Ok((
Expr::When(arena.alloc(loc_condition), branches.into_bump_slice()),
state,
))
},
)
}
@ -1152,7 +1165,7 @@ mod when {
// Record this as the first branch, then optionally parse additional branches.
branches.push(arena.alloc(WhenBranch {
patterns: loc_first_patterns,
patterns: loc_first_patterns.into_bump_slice(),
value: loc_first_expr,
guard: loc_first_guard,
}));
@ -1173,10 +1186,13 @@ mod when {
),
branch_result(indented_more)
),
|((patterns, guard), expr)| WhenBranch {
patterns,
value: expr,
guard
|((patterns, guard), expr)| {
let patterns: Vec<'a, _> = patterns;
WhenBranch {
patterns: patterns.into_bump_slice(),
value: expr,
guard,
}
}
);
@ -1444,7 +1460,11 @@ fn ident_etc<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
}
Ok((
Expr::Apply(arena.alloc(loc_expr), allocated_args, CalledVia::Space),
Expr::Apply(
arena.alloc(loc_expr),
allocated_args.into_bump_slice(),
CalledVia::Space,
),
state,
))
}
@ -1638,7 +1658,7 @@ pub fn list_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
allocated.push(&*arena.alloc(parsed_elem));
}
Expr::List(allocated)
Expr::List(allocated.into_bump_slice())
}),
)
}
@ -1663,7 +1683,7 @@ pub fn record_literal<'a>(min_indent: u16) -> impl Parser<'a, Expr<'a>> {
// This is a record literal, not a destructure.
let mut value = Expr::Record {
update: opt_update.map(|loc_expr| &*arena.alloc(loc_expr)),
fields: loc_assigned_fields.value,
fields: loc_assigned_fields.value.into_bump_slice(),
};
// there can be field access, e.g. `{ x : 4 }.x`