Convert top-level value def to fn taking params

This commit is contained in:
Agus Zubiaga 2024-08-17 11:21:21 -03:00
parent 1dd7e0b41f
commit e80e3e5b2d
No known key found for this signature in database
8 changed files with 147 additions and 28 deletions

View file

@ -11,14 +11,19 @@ use roc_region::all::Loc;
use roc_types::subs::{VarStore, Variable};
use roc_types::types::Type;
struct LowerParams {
struct LowerParams<'a> {
// todo: remove var as we can't use it
home_params: Option<HomeParams>,
var_store: &'a mut VarStore,
}
type HomeParams = (Variable, AnnotatedMark, Loc<Pattern>);
pub fn lower(home_params: Option<HomeParams>, decls: &mut Declarations, var_store: &mut VarStore) {
let env = LowerParams { home_params };
let mut env = LowerParams {
home_params,
var_store,
};
let mut index = 0;
@ -27,12 +32,15 @@ pub fn lower(home_params: Option<HomeParams>, decls: &mut Declarations, var_stor
match tag {
Value => {
// todo: thunk in module with params
env.lower_expr(&mut decls.expressions[index].value)
env.lower_expr(&mut decls.expressions[index].value);
if let Some(new_arg) = env.home_params_argument() {
decls.convert_value_to_function(index, vec![new_arg], env.var_store);
}
}
Function(fn_def_index) => {
if let Some((_, mark, pattern)) = env.home_params.clone() {
let var = var_store.fresh();
if let Some((_, mark, pattern)) = env.home_params_argument() {
let var = env.var_store.fresh();
decls.function_bodies[fn_def_index.index()]
.value
@ -64,9 +72,39 @@ pub fn lower(home_params: Option<HomeParams>, decls: &mut Declarations, var_stor
}
}
impl LowerParams {
fn lower_expr(&self, expr: &mut Expr) {
impl<'a> LowerParams<'a> {
fn home_params_argument(&mut self) -> Option<(Variable, AnnotatedMark, Loc<Pattern>)> {
match &self.home_params {
Some((_, mark, pattern)) => {
let new_var = self.var_store.fresh();
Some((new_var, *mark, pattern.clone()))
}
None => None,
}
}
fn lower_expr(&mut self, expr: &mut Expr) {
match expr {
ParamsVar {
symbol,
var,
params_symbol,
params_var,
} => {
let params_arg = (*params_var, Loc::at_zero(Var(*params_symbol, *params_var)));
*expr = Call(
Box::new((
self.var_store.fresh(),
Loc::at_zero(Var(*symbol, *var)),
self.var_store.fresh(),
self.var_store.fresh(),
)),
vec![params_arg],
// todo: custom called via
roc_module::called_via::CalledVia::Space,
);
}
Call(fun, args, _called_via) => {
for arg in args.iter_mut() {
// todo: params var in arg