mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
IT WORKS
This commit is contained in:
parent
d0f031fe6c
commit
40ffca2b7b
16 changed files with 511 additions and 200 deletions
|
@ -100,9 +100,10 @@ pub enum Expr {
|
|||
Closure {
|
||||
function_type: Variable,
|
||||
closure_type: Variable,
|
||||
closure_ext_var: Variable,
|
||||
return_type: Variable,
|
||||
name: Symbol,
|
||||
captured_symbols: MutSet<Symbol>,
|
||||
captured_symbols: Vec<(Symbol, Variable)>,
|
||||
recursive: Recursive,
|
||||
arguments: Vec<(Variable, Located<Pattern>)>,
|
||||
loc_body: Box<Located<Expr>>,
|
||||
|
@ -442,6 +443,8 @@ pub fn canonicalize_expr<'a>(
|
|||
let mut can_args = Vec::with_capacity(loc_arg_patterns.len());
|
||||
let mut output = Output::default();
|
||||
|
||||
let mut bound_by_argument_patterns = MutSet::default();
|
||||
|
||||
for loc_pattern in loc_arg_patterns.into_iter() {
|
||||
let (new_output, can_arg) = canonicalize_pattern(
|
||||
env,
|
||||
|
@ -452,6 +455,9 @@ pub fn canonicalize_expr<'a>(
|
|||
loc_pattern.region,
|
||||
);
|
||||
|
||||
bound_by_argument_patterns
|
||||
.extend(new_output.references.bound_symbols.iter().copied());
|
||||
|
||||
output.union(new_output);
|
||||
|
||||
can_args.push((var_store.fresh(), can_arg));
|
||||
|
@ -465,6 +471,20 @@ pub fn canonicalize_expr<'a>(
|
|||
&loc_body_expr.value,
|
||||
);
|
||||
|
||||
let mut captured_symbols: MutSet<Symbol> =
|
||||
new_output.references.lookups.iter().copied().collect();
|
||||
|
||||
// filter out the closure's name itself
|
||||
captured_symbols.remove(&symbol);
|
||||
|
||||
// symbols bound either in this pattern or deeper down are not captured!
|
||||
captured_symbols.retain(|s| !new_output.references.bound_symbols.contains(s));
|
||||
captured_symbols.retain(|s| !bound_by_argument_patterns.contains(s));
|
||||
|
||||
// TODO filter out top-level symbols, and imported symbols
|
||||
// those will be globally available, and don't need to be captured
|
||||
captured_symbols.retain(|s| !s.is_builtin());
|
||||
|
||||
output.union(new_output);
|
||||
|
||||
// Now that we've collected all the references, check to see if any of the args we defined
|
||||
|
@ -485,13 +505,22 @@ pub fn canonicalize_expr<'a>(
|
|||
|
||||
env.register_closure(symbol, output.references.clone());
|
||||
|
||||
let mut captured_symbols: Vec<_> = captured_symbols
|
||||
.into_iter()
|
||||
.map(|s| (s, var_store.fresh()))
|
||||
.collect();
|
||||
|
||||
// sort symbols, so we know the order in which they're stored in the closure record
|
||||
captured_symbols.sort();
|
||||
|
||||
(
|
||||
Closure {
|
||||
function_type: var_store.fresh(),
|
||||
closure_type: var_store.fresh(),
|
||||
closure_ext_var: var_store.fresh(),
|
||||
return_type: var_store.fresh(),
|
||||
name: symbol,
|
||||
captured_symbols: MutSet::default(),
|
||||
captured_symbols,
|
||||
recursive: Recursive::NotRecursive,
|
||||
arguments: can_args,
|
||||
loc_body: Box::new(loc_body_expr),
|
||||
|
@ -1216,6 +1245,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
|||
Closure {
|
||||
function_type,
|
||||
closure_type,
|
||||
closure_ext_var,
|
||||
return_type,
|
||||
recursive,
|
||||
name,
|
||||
|
@ -1232,6 +1262,7 @@ pub fn inline_calls(var_store: &mut VarStore, scope: &mut Scope, expr: Expr) ->
|
|||
Closure {
|
||||
function_type,
|
||||
closure_type,
|
||||
closure_ext_var,
|
||||
return_type,
|
||||
recursive,
|
||||
name,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue