mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 03:42:17 +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
|
@ -737,6 +737,8 @@ mod cli_run {
|
||||||
App2.baseUrl: http://api.example.com/two
|
App2.baseUrl: http://api.example.com/two
|
||||||
App1.getUser 1: https://api.example.com/one/users/1
|
App1.getUser 1: https://api.example.com/one/users/1
|
||||||
App2.getUser 2: http://api.example.com/two/users/2
|
App2.getUser 2: http://api.example.com/two/users/2
|
||||||
|
App1.getPost 1: https://api.example.com/one/posts/1
|
||||||
|
App2.getPost 2: http://api.example.com/two/posts/2
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
UseValgrind::No,
|
UseValgrind::No,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module { appId, protocol } -> [baseUrl, getUser]
|
module { appId, protocol } -> [baseUrl, getUser, getPost]
|
||||||
|
|
||||||
baseUrl : Str
|
baseUrl : Str
|
||||||
baseUrl =
|
baseUrl =
|
||||||
|
@ -7,4 +7,9 @@ baseUrl =
|
||||||
|
|
||||||
getUser : U32 -> Str
|
getUser : U32 -> Str
|
||||||
getUser = \userId ->
|
getUser = \userId ->
|
||||||
|
# purposefully not using baseUrl to test top-level fn referencing param
|
||||||
protocol "api.example.com/$(appId)/users/$(Num.toStr userId)"
|
protocol "api.example.com/$(appId)/users/$(Num.toStr userId)"
|
||||||
|
|
||||||
|
getPost : U32 -> Str
|
||||||
|
getPost = \postId ->
|
||||||
|
"$(baseUrl)/posts/$(Num.toStr postId)"
|
||||||
|
|
|
@ -14,4 +14,6 @@ main =
|
||||||
App2.baseUrl: $(App2.baseUrl)
|
App2.baseUrl: $(App2.baseUrl)
|
||||||
App1.getUser 1: $(App1.getUser 1)
|
App1.getUser 1: $(App1.getUser 1)
|
||||||
App2.getUser 2: $(App2.getUser 2)
|
App2.getUser 2: $(App2.getUser 2)
|
||||||
|
App1.getPost 1: $(App1.getPost 1)
|
||||||
|
App2.getPost 2: $(App2.getPost 2)
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5090,6 +5090,8 @@ fn canonicalize_and_constrain<'a>(
|
||||||
|
|
||||||
// lower module params
|
// lower module params
|
||||||
roc_lower_params::lower(
|
roc_lower_params::lower(
|
||||||
|
module_id,
|
||||||
|
// todo(agus): borrow params?
|
||||||
module_output.module_params.clone(),
|
module_output.module_params.clone(),
|
||||||
&mut module_output.declarations,
|
&mut module_output.declarations,
|
||||||
&mut var_store,
|
&mut var_store,
|
||||||
|
|
|
@ -8,23 +8,39 @@ use roc_can::{
|
||||||
module::ModuleParams,
|
module::ModuleParams,
|
||||||
pattern::Pattern,
|
pattern::Pattern,
|
||||||
};
|
};
|
||||||
|
use roc_module::symbol::{IdentId, ModuleId, Symbol};
|
||||||
use roc_region::all::Loc;
|
use roc_region::all::Loc;
|
||||||
use roc_types::subs::{VarStore, Variable};
|
use roc_types::subs::{VarStore, Variable};
|
||||||
use roc_types::types::Type;
|
use roc_types::types::Type;
|
||||||
|
|
||||||
struct LowerParams<'a> {
|
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>,
|
home_params: Option<ModuleParams>,
|
||||||
var_store: &'a mut VarStore,
|
var_store: &'a mut VarStore,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower(
|
pub fn lower(
|
||||||
|
home_id: ModuleId,
|
||||||
home_params: Option<ModuleParams>,
|
home_params: Option<ModuleParams>,
|
||||||
decls: &mut Declarations,
|
decls: &mut Declarations,
|
||||||
var_store: &mut VarStore,
|
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 {
|
let mut env = LowerParams {
|
||||||
|
home_id,
|
||||||
home_params,
|
home_params,
|
||||||
|
home_top_level_idents,
|
||||||
var_store,
|
var_store,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,20 +92,6 @@ pub fn lower(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> LowerParams<'a> {
|
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) {
|
fn lower_expr(&mut self, expr: &mut Expr) {
|
||||||
match expr {
|
match expr {
|
||||||
ParamsVar {
|
ParamsVar {
|
||||||
|
@ -98,19 +100,18 @@ impl<'a> LowerParams<'a> {
|
||||||
params_symbol,
|
params_symbol,
|
||||||
params_var,
|
params_var,
|
||||||
} => {
|
} => {
|
||||||
let params_arg = (*params_var, Loc::at_zero(Var(*params_symbol, *params_var)));
|
// 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);
|
||||||
*expr = Call(
|
}
|
||||||
Box::new((
|
Var(symbol, var) => {
|
||||||
self.var_store.fresh(),
|
if symbol.module_id() == self.home_id
|
||||||
Loc::at_zero(Var(*symbol, *var)),
|
&& self.home_top_level_idents.contains(&symbol.ident_id())
|
||||||
self.var_store.fresh(),
|
{
|
||||||
self.var_store.fresh(),
|
// A reference to a top-level value def in the home module with params
|
||||||
)),
|
let params = self.home_params.as_ref().unwrap();
|
||||||
vec![params_arg],
|
*expr =
|
||||||
// todo: custom called via
|
self.call_params_var(*symbol, *var, params.whole_symbol, params.whole_var);
|
||||||
roc_module::called_via::CalledVia::Space,
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Call(fun, args, _called_via) => {
|
Call(fun, args, _called_via) => {
|
||||||
for arg in args.iter_mut() {
|
for arg in args.iter_mut() {
|
||||||
|
@ -119,6 +120,7 @@ impl<'a> LowerParams<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match fun.1.value {
|
match fun.1.value {
|
||||||
|
// A call to a function in an imported module with params
|
||||||
ParamsVar {
|
ParamsVar {
|
||||||
symbol,
|
symbol,
|
||||||
var,
|
var,
|
||||||
|
@ -148,4 +150,39 @@ impl<'a> LowerParams<'a> {
|
||||||
_ => { /* todo */ }
|
_ => { /* 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