mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
add closure size variable
This commit is contained in:
parent
0422d565ce
commit
2e1e87ad6a
21 changed files with 546 additions and 262 deletions
|
@ -438,7 +438,9 @@ impl<'a> Procs<'a> {
|
|||
|
||||
fn get_args_ret_var(subs: &Subs, var: Variable) -> Option<(std::vec::Vec<Variable>, Variable)> {
|
||||
match subs.get_without_compacting(var).content {
|
||||
Content::Structure(FlatType::Func(pattern_vars, ret_var)) => Some((pattern_vars, ret_var)),
|
||||
Content::Structure(FlatType::Func(pattern_vars, _closure_var, ret_var)) => {
|
||||
Some((pattern_vars, ret_var))
|
||||
}
|
||||
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, args)) => {
|
||||
get_args_ret_var(subs, args[1])
|
||||
}
|
||||
|
@ -1334,24 +1336,32 @@ pub fn with_hole<'a>(
|
|||
},
|
||||
LetNonRec(def, cont, _, _) => {
|
||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||
if let Closure(ann, _, recursivity, loc_args, boxed_body) = def.loc_expr.value {
|
||||
if let Closure {
|
||||
function_type,
|
||||
return_type,
|
||||
recursive,
|
||||
arguments,
|
||||
loc_body: boxed_body,
|
||||
..
|
||||
} = def.loc_expr.value
|
||||
{
|
||||
// Extract Procs, but discard the resulting Expr::Load.
|
||||
// That Load looks up the pointer, which we won't use here!
|
||||
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
let loc_body = *boxed_body;
|
||||
|
||||
let is_self_recursive =
|
||||
!matches!(recursivity, roc_can::expr::Recursive::NotRecursive);
|
||||
!matches!(recursive, roc_can::expr::Recursive::NotRecursive);
|
||||
|
||||
procs.insert_named(
|
||||
env,
|
||||
layout_cache,
|
||||
*symbol,
|
||||
ann,
|
||||
loc_args,
|
||||
function_type,
|
||||
arguments,
|
||||
loc_body,
|
||||
is_self_recursive,
|
||||
ret_var,
|
||||
return_type,
|
||||
);
|
||||
|
||||
return with_hole(env, cont.value, procs, layout_cache, assigned, hole);
|
||||
|
@ -1418,24 +1428,32 @@ pub fn with_hole<'a>(
|
|||
// because Roc is strict, only functions can be recursive!
|
||||
for def in defs.into_iter() {
|
||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||
if let Closure(ann, _, recursivity, loc_args, boxed_body) = def.loc_expr.value {
|
||||
if let Closure {
|
||||
function_type,
|
||||
return_type,
|
||||
recursive,
|
||||
arguments,
|
||||
loc_body: boxed_body,
|
||||
..
|
||||
} = def.loc_expr.value
|
||||
{
|
||||
// Extract Procs, but discard the resulting Expr::Load.
|
||||
// That Load looks up the pointer, which we won't use here!
|
||||
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
let loc_body = *boxed_body;
|
||||
|
||||
let is_self_recursive =
|
||||
!matches!(recursivity, roc_can::expr::Recursive::NotRecursive);
|
||||
!matches!(recursive, roc_can::expr::Recursive::NotRecursive);
|
||||
|
||||
procs.insert_named(
|
||||
env,
|
||||
layout_cache,
|
||||
*symbol,
|
||||
ann,
|
||||
loc_args,
|
||||
function_type,
|
||||
arguments,
|
||||
loc_body,
|
||||
is_self_recursive,
|
||||
ret_var,
|
||||
return_type,
|
||||
);
|
||||
|
||||
continue;
|
||||
|
@ -1943,11 +1961,25 @@ pub fn with_hole<'a>(
|
|||
|
||||
Accessor { .. } | Update { .. } => todo!("record access/accessor/update"),
|
||||
|
||||
Closure(ann, name, _, loc_args, boxed_body) => {
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
Closure {
|
||||
function_type,
|
||||
return_type,
|
||||
name,
|
||||
arguments,
|
||||
loc_body: boxed_body,
|
||||
..
|
||||
} => {
|
||||
let loc_body = *boxed_body;
|
||||
|
||||
match procs.insert_anonymous(env, name, ann, loc_args, loc_body, ret_var, layout_cache)
|
||||
{
|
||||
match procs.insert_anonymous(
|
||||
env,
|
||||
name,
|
||||
function_type,
|
||||
arguments,
|
||||
loc_body,
|
||||
return_type,
|
||||
layout_cache,
|
||||
) {
|
||||
Ok(layout) => {
|
||||
// TODO should the let have layout Pointer?
|
||||
Stmt::Let(
|
||||
|
@ -1965,7 +1997,7 @@ pub fn with_hole<'a>(
|
|||
}
|
||||
|
||||
Call(boxed, loc_args, _) => {
|
||||
let (fn_var, loc_expr, ret_var) = *boxed;
|
||||
let (fn_var, loc_expr, _closure_var, ret_var) = *boxed;
|
||||
|
||||
// even if a call looks like it's by name, it may in fact be by-pointer.
|
||||
// E.g. in `(\f, x -> f x)` the call is in fact by pointer.
|
||||
|
@ -2197,24 +2229,31 @@ pub fn from_can<'a>(
|
|||
// Now that we know for sure it's a closure, get an owned
|
||||
// version of these variant args so we can use them properly.
|
||||
match def.loc_expr.value {
|
||||
Closure(ann, _, recursivity, loc_args, boxed_body) => {
|
||||
Closure {
|
||||
function_type,
|
||||
return_type,
|
||||
recursive,
|
||||
arguments,
|
||||
loc_body: boxed_body,
|
||||
..
|
||||
} => {
|
||||
// Extract Procs, but discard the resulting Expr::Load.
|
||||
// That Load looks up the pointer, which we won't use here!
|
||||
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
let loc_body = *boxed_body;
|
||||
|
||||
let is_self_recursive =
|
||||
!matches!(recursivity, roc_can::expr::Recursive::NotRecursive);
|
||||
!matches!(recursive, roc_can::expr::Recursive::NotRecursive);
|
||||
|
||||
procs.insert_named(
|
||||
env,
|
||||
layout_cache,
|
||||
*symbol,
|
||||
ann,
|
||||
loc_args,
|
||||
function_type,
|
||||
arguments,
|
||||
loc_body,
|
||||
is_self_recursive,
|
||||
ret_var,
|
||||
return_type,
|
||||
);
|
||||
|
||||
continue;
|
||||
|
@ -2229,28 +2268,35 @@ pub fn from_can<'a>(
|
|||
}
|
||||
LetNonRec(def, cont, _, _) => {
|
||||
if let roc_can::pattern::Pattern::Identifier(symbol) = &def.loc_pattern.value {
|
||||
if let Closure(_, _, _, _, _) = &def.loc_expr.value {
|
||||
if let Closure { .. } = &def.loc_expr.value {
|
||||
// Now that we know for sure it's a closure, get an owned
|
||||
// version of these variant args so we can use them properly.
|
||||
match def.loc_expr.value {
|
||||
Closure(ann, _, recursivity, loc_args, boxed_body) => {
|
||||
Closure {
|
||||
function_type,
|
||||
return_type,
|
||||
recursive,
|
||||
arguments,
|
||||
loc_body: boxed_body,
|
||||
..
|
||||
} => {
|
||||
// Extract Procs, but discard the resulting Expr::Load.
|
||||
// That Load looks up the pointer, which we won't use here!
|
||||
|
||||
let (loc_body, ret_var) = *boxed_body;
|
||||
let loc_body = *boxed_body;
|
||||
|
||||
let is_self_recursive =
|
||||
!matches!(recursivity, roc_can::expr::Recursive::NotRecursive);
|
||||
!matches!(recursive, roc_can::expr::Recursive::NotRecursive);
|
||||
|
||||
procs.insert_named(
|
||||
env,
|
||||
layout_cache,
|
||||
*symbol,
|
||||
ann,
|
||||
loc_args,
|
||||
function_type,
|
||||
arguments,
|
||||
loc_body,
|
||||
is_self_recursive,
|
||||
ret_var,
|
||||
return_type,
|
||||
);
|
||||
|
||||
return from_can(env, cont.value, procs, layout_cache);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue