mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
Lower top-level value references in home module with params
This commit is contained in:
parent
519ff56a85
commit
07ec24502e
5 changed files with 77 additions and 29 deletions
|
@ -5090,6 +5090,8 @@ fn canonicalize_and_constrain<'a>(
|
|||
|
||||
// lower module params
|
||||
roc_lower_params::lower(
|
||||
module_id,
|
||||
// todo(agus): borrow params?
|
||||
module_output.module_params.clone(),
|
||||
&mut module_output.declarations,
|
||||
&mut var_store,
|
||||
|
|
|
@ -8,23 +8,39 @@ use roc_can::{
|
|||
module::ModuleParams,
|
||||
pattern::Pattern,
|
||||
};
|
||||
use roc_module::symbol::{IdentId, ModuleId, Symbol};
|
||||
use roc_region::all::Loc;
|
||||
use roc_types::subs::{VarStore, Variable};
|
||||
use roc_types::types::Type;
|
||||
|
||||
struct LowerParams<'a> {
|
||||
// todo: remove var as we can't use it
|
||||
home_id: ModuleId,
|
||||
/// Top-level idents that we need to extend in a module with params. Empty if no params.
|
||||
home_top_level_idents: Vec<IdentId>,
|
||||
home_params: Option<ModuleParams>,
|
||||
var_store: &'a mut VarStore,
|
||||
}
|
||||
|
||||
pub fn lower(
|
||||
home_id: ModuleId,
|
||||
home_params: Option<ModuleParams>,
|
||||
decls: &mut Declarations,
|
||||
var_store: &mut VarStore,
|
||||
) {
|
||||
let home_top_level_idents = if home_params.is_some() {
|
||||
decls
|
||||
.symbols
|
||||
.iter()
|
||||
.map(|loc_sym| loc_sym.value.ident_id())
|
||||
.collect()
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let mut env = LowerParams {
|
||||
home_id,
|
||||
home_params,
|
||||
home_top_level_idents,
|
||||
var_store,
|
||||
};
|
||||
|
||||
|
@ -76,20 +92,6 @@ pub fn lower(
|
|||
}
|
||||
|
||||
impl<'a> LowerParams<'a> {
|
||||
fn home_params_argument(&mut self) -> Option<(Variable, AnnotatedMark, Loc<Pattern>)> {
|
||||
match &self.home_params {
|
||||
Some(module_params) => {
|
||||
let new_var = self.var_store.fresh();
|
||||
Some((
|
||||
new_var,
|
||||
AnnotatedMark::new(self.var_store),
|
||||
module_params.pattern(),
|
||||
))
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_expr(&mut self, expr: &mut Expr) {
|
||||
match expr {
|
||||
ParamsVar {
|
||||
|
@ -98,19 +100,18 @@ impl<'a> LowerParams<'a> {
|
|||
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,
|
||||
);
|
||||
// A referece to a top-level value def in an imported module with params
|
||||
*expr = self.call_params_var(*symbol, *var, *params_symbol, *params_var);
|
||||
}
|
||||
Var(symbol, var) => {
|
||||
if symbol.module_id() == self.home_id
|
||||
&& self.home_top_level_idents.contains(&symbol.ident_id())
|
||||
{
|
||||
// A reference to a top-level value def in the home module with params
|
||||
let params = self.home_params.as_ref().unwrap();
|
||||
*expr =
|
||||
self.call_params_var(*symbol, *var, params.whole_symbol, params.whole_var);
|
||||
}
|
||||
}
|
||||
Call(fun, args, _called_via) => {
|
||||
for arg in args.iter_mut() {
|
||||
|
@ -119,6 +120,7 @@ impl<'a> LowerParams<'a> {
|
|||
}
|
||||
|
||||
match fun.1.value {
|
||||
// A call to a function in an imported module with params
|
||||
ParamsVar {
|
||||
symbol,
|
||||
var,
|
||||
|
@ -148,4 +150,39 @@ impl<'a> LowerParams<'a> {
|
|||
_ => { /* todo */ }
|
||||
}
|
||||
}
|
||||
|
||||
fn call_params_var(
|
||||
&mut self,
|
||||
symbol: Symbol,
|
||||
var: Variable,
|
||||
params_symbol: Symbol,
|
||||
params_var: Variable,
|
||||
) -> Expr {
|
||||
let params_arg = (params_var, Loc::at_zero(Var(params_symbol, params_var)));
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
fn home_params_argument(&mut self) -> Option<(Variable, AnnotatedMark, Loc<Pattern>)> {
|
||||
match &self.home_params {
|
||||
Some(module_params) => {
|
||||
let new_var = self.var_store.fresh();
|
||||
Some((
|
||||
new_var,
|
||||
AnnotatedMark::new(self.var_store),
|
||||
module_params.pattern(),
|
||||
))
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue