mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
Consolidate Accessor
data
This commit is contained in:
parent
3bff99b0a2
commit
0692caf7ba
4 changed files with 83 additions and 113 deletions
|
@ -138,18 +138,7 @@ pub enum Expr {
|
|||
field: Lowercase,
|
||||
},
|
||||
/// field accessor as a function, e.g. (.foo) expr
|
||||
Accessor {
|
||||
/// accessors are desugared to closures; they need to have a name
|
||||
/// so the closure can have a correct lambda set
|
||||
name: Symbol,
|
||||
function_var: Variable,
|
||||
record_var: Variable,
|
||||
closure_var: Variable,
|
||||
closure_ext_var: Variable,
|
||||
ext_var: Variable,
|
||||
field_var: Variable,
|
||||
field: Lowercase,
|
||||
},
|
||||
Accessor(AccessorData),
|
||||
|
||||
Update {
|
||||
record_var: Variable,
|
||||
|
@ -218,6 +207,70 @@ pub struct ClosureData {
|
|||
pub loc_body: Box<Loc<Expr>>,
|
||||
}
|
||||
|
||||
/// A record accessor like `.foo`, which is equivalent to `\r -> r.foo`
|
||||
/// Accessors are desugared to closures; they need to have a name
|
||||
/// so the closure can have a correct lambda set.
|
||||
///
|
||||
/// We distinguish them from closures so we can have better error messages
|
||||
/// during constraint generation.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct AccessorData {
|
||||
pub name: Symbol,
|
||||
pub function_var: Variable,
|
||||
pub record_var: Variable,
|
||||
pub closure_var: Variable,
|
||||
pub closure_ext_var: Variable,
|
||||
pub ext_var: Variable,
|
||||
pub field_var: Variable,
|
||||
pub field: Lowercase,
|
||||
}
|
||||
|
||||
impl AccessorData {
|
||||
pub fn to_closure_data(self, record_symbol: Symbol) -> ClosureData {
|
||||
let AccessorData {
|
||||
name,
|
||||
function_var,
|
||||
record_var,
|
||||
closure_var,
|
||||
closure_ext_var,
|
||||
ext_var,
|
||||
field_var,
|
||||
field,
|
||||
} = self;
|
||||
|
||||
// IDEA: convert accessor from
|
||||
//
|
||||
// .foo
|
||||
//
|
||||
// into
|
||||
//
|
||||
// (\r -> r.foo)
|
||||
let body = Expr::Access {
|
||||
record_var,
|
||||
ext_var,
|
||||
field_var,
|
||||
loc_expr: Box::new(Loc::at_zero(Expr::Var(record_symbol))),
|
||||
field,
|
||||
};
|
||||
|
||||
let loc_body = Loc::at_zero(body);
|
||||
|
||||
let arguments = vec![(record_var, Loc::at_zero(Pattern::Identifier(record_symbol)))];
|
||||
|
||||
ClosureData {
|
||||
function_type: function_var,
|
||||
closure_type: closure_var,
|
||||
closure_ext_var,
|
||||
return_type: field_var,
|
||||
name,
|
||||
captured_symbols: vec![],
|
||||
recursive: Recursive::NotRecursive,
|
||||
arguments,
|
||||
loc_body: Box::new(loc_body),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Field {
|
||||
pub var: Variable,
|
||||
|
@ -736,7 +789,7 @@ pub fn canonicalize_expr<'a>(
|
|||
)
|
||||
}
|
||||
ast::Expr::AccessorFunction(field) => (
|
||||
Accessor {
|
||||
Accessor(AccessorData {
|
||||
name: env.gen_unique_symbol(),
|
||||
function_var: var_store.fresh(),
|
||||
record_var: var_store.fresh(),
|
||||
|
@ -745,7 +798,7 @@ pub fn canonicalize_expr<'a>(
|
|||
closure_ext_var: var_store.fresh(),
|
||||
field_var: var_store.fresh(),
|
||||
field: (*field).into(),
|
||||
},
|
||||
}),
|
||||
Output::default(),
|
||||
),
|
||||
ast::Expr::GlobalTag(tag) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue