mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
better desugared idents
This commit is contained in:
parent
9a37aeb82f
commit
10bdabf52e
2 changed files with 58 additions and 28 deletions
|
@ -159,7 +159,7 @@ fn desugar_value_def<'a>(
|
||||||
// _ = stmt_expr!
|
// _ = stmt_expr!
|
||||||
|
|
||||||
let region = stmt_expr.region;
|
let region = stmt_expr.region;
|
||||||
let new_pat = arena.alloc(Loc::at(region, Pattern::Underscore("")));
|
let new_pat = arena.alloc(Loc::at(region, Pattern::Underscore("#!stmt")));
|
||||||
|
|
||||||
ValueDef::AnnotatedBody {
|
ValueDef::AnnotatedBody {
|
||||||
ann_pattern: new_pat,
|
ann_pattern: new_pat,
|
||||||
|
@ -265,7 +265,7 @@ pub fn desugar_value_def_suffixed<'a>(arena: &'a Bump, value_def: ValueDef<'a>)
|
||||||
sub_arg,
|
sub_arg,
|
||||||
sub_pat,
|
sub_pat,
|
||||||
sub_new,
|
sub_new,
|
||||||
Some(ann_type),
|
Some((ann_pattern, ann_type)),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn next_unique_suffixed_ident() -> String {
|
||||||
|
|
||||||
// # is used as prefix because it's impossible for code authors to define names like this.
|
// # is used as prefix because it's impossible for code authors to define names like this.
|
||||||
// This makes it easy to see this identifier was created by the compiler.
|
// This makes it easy to see this identifier was created by the compiler.
|
||||||
format!("#!a{}", count)
|
format!("#!{}", count)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,19 +70,17 @@ fn init_unwrapped_err<'a>(
|
||||||
// Provide an intermediate answer expression and pattern when unwrapping a
|
// Provide an intermediate answer expression and pattern when unwrapping a
|
||||||
// (sub) expression.
|
// (sub) expression.
|
||||||
// e.g. `x = foo (bar!)` unwraps to `x = Task.await (bar) \#!a0 -> foo #!a0`
|
// e.g. `x = foo (bar!)` unwraps to `x = Task.await (bar) \#!a0 -> foo #!a0`
|
||||||
let answer_ident = arena.alloc(next_unique_suffixed_ident());
|
let ident = arena.alloc(format!("{}_arg", next_unique_suffixed_ident()));
|
||||||
let sub_new = arena.alloc(Loc::at(
|
let sub_new = arena.alloc(Loc::at(
|
||||||
unwrapped_expr.region,
|
unwrapped_expr.region,
|
||||||
Expr::Var {
|
Expr::Var {
|
||||||
module_name: "",
|
module_name: "",
|
||||||
ident: answer_ident,
|
ident,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
let sub_pat = arena.alloc(Loc::at(
|
let sub_pat = arena.alloc(Loc::at(
|
||||||
unwrapped_expr.region,
|
unwrapped_expr.region,
|
||||||
Pattern::Identifier {
|
Pattern::Identifier { ident },
|
||||||
ident: answer_ident,
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
|
|
||||||
Err(EUnwrapped::UnwrappedSubExpr {
|
Err(EUnwrapped::UnwrappedSubExpr {
|
||||||
|
@ -619,8 +617,7 @@ pub fn unwrap_suffixed_expression_defs_help<'a>(
|
||||||
|
|
||||||
let maybe_suffixed_value_def = match current_value_def {
|
let maybe_suffixed_value_def = match current_value_def {
|
||||||
Annotation(..) | Dbg{..} | Expect{..} | ExpectFx{..} | Stmt(..) | ModuleImport{..} | IngestedFileImport(_) => None,
|
Annotation(..) | Dbg{..} | Expect{..} | ExpectFx{..} | Stmt(..) | ModuleImport{..} | IngestedFileImport(_) => None,
|
||||||
AnnotatedBody { body_pattern, body_expr, ann_type, ann_pattern, .. } if body_pattern.value == ann_pattern.value => Some((body_pattern, body_expr, Some(ann_type))),
|
AnnotatedBody { body_pattern, body_expr, ann_type, ann_pattern, .. } => Some((body_pattern, body_expr, Some((ann_pattern, ann_type)))),
|
||||||
AnnotatedBody { body_pattern, body_expr, .. } => Some((body_pattern, body_expr, None)),
|
|
||||||
Body (def_pattern, def_expr) => Some((def_pattern, def_expr, None)),
|
Body (def_pattern, def_expr) => Some((def_pattern, def_expr, None)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -846,47 +843,72 @@ pub fn apply_task_await<'a>(
|
||||||
loc_expr: &'a Loc<Expr<'a>>,
|
loc_expr: &'a Loc<Expr<'a>>,
|
||||||
loc_pat: &'a Loc<Pattern<'a>>,
|
loc_pat: &'a Loc<Pattern<'a>>,
|
||||||
loc_cont: &'a Loc<Expr<'a>>,
|
loc_cont: &'a Loc<Expr<'a>>,
|
||||||
maybe_loc_type: Option<&'a Loc<TypeAnnotation<'a>>>,
|
maybe_loc_ann: Option<(&'a Loc<Pattern>, &'a Loc<TypeAnnotation<'a>>)>,
|
||||||
) -> &'a Loc<Expr<'a>> {
|
) -> &'a Loc<Expr<'a>> {
|
||||||
let task_await_first_arg = match maybe_loc_type {
|
let task_await_first_arg = match maybe_loc_ann {
|
||||||
Some(loc_type) => {
|
Some((loc_ann_pat, loc_type)) => {
|
||||||
// loc_pat : loc_type
|
// loc_ann_pat : loc_type
|
||||||
// loc_pat = loc_expr!
|
// loc_pat = loc_expr!
|
||||||
// loc_cont
|
// loc_cont
|
||||||
|
|
||||||
// desugar to
|
// desugar to
|
||||||
// Task.await
|
// Task.await
|
||||||
// (
|
// (
|
||||||
// #!a0 : Task loc_type _
|
// #!0_expr : Task loc_type _
|
||||||
// #!a0 = loc_expr
|
// #!0_expr = loc_expr
|
||||||
// #!a0
|
// #!0_expr
|
||||||
// )
|
// )
|
||||||
// \loc_pat -> loc_cont
|
// \loc_pat -> loc_cont
|
||||||
use roc_parse::ast::*;
|
use roc_parse::ast::*;
|
||||||
|
|
||||||
// #!a0
|
// #!a0
|
||||||
let new_ident = arena.alloc(next_unique_suffixed_ident());
|
let new_ident = next_unique_suffixed_ident();
|
||||||
// #!a0 (pattern)
|
let new_ident = match loc_pat.value {
|
||||||
let new_pat = arena.alloc(Loc::at(region, Pattern::Identifier { ident: new_ident }));
|
Pattern::Underscore("#!stmt") => format!("{}_stmt", new_ident),
|
||||||
|
Pattern::Identifier { ident }
|
||||||
|
if ident.starts_with('#') && ident.ends_with("_stmt") =>
|
||||||
|
{
|
||||||
|
format!("{}_stmt", new_ident)
|
||||||
|
}
|
||||||
|
_ => format!("{}_expr", new_ident),
|
||||||
|
};
|
||||||
|
let new_ident = arena.alloc(new_ident);
|
||||||
|
|
||||||
// #!a0 : Task loc_type _
|
// #!0_expr (pattern)
|
||||||
// #!a0 = loc_expr
|
// #!0_expr : Task loc_type _
|
||||||
|
// #!0_expr = loc_expr
|
||||||
let value_def = ValueDef::AnnotatedBody {
|
let value_def = ValueDef::AnnotatedBody {
|
||||||
ann_pattern: new_pat,
|
ann_pattern: arena.alloc(Loc::at(
|
||||||
|
loc_ann_pat.region,
|
||||||
|
Pattern::Identifier {
|
||||||
|
ident: if loc_ann_pat.value.equivalent(&loc_pat.value) {
|
||||||
|
new_ident
|
||||||
|
} else {
|
||||||
|
// create another pattern to preserve inconsistency
|
||||||
|
arena.alloc(next_unique_suffixed_ident())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)),
|
||||||
ann_type: arena.alloc(Loc::at(
|
ann_type: arena.alloc(Loc::at(
|
||||||
region,
|
loc_type.region,
|
||||||
TypeAnnotation::Apply(
|
TypeAnnotation::Apply(
|
||||||
arena.alloc(""),
|
arena.alloc(""),
|
||||||
arena.alloc("Task"),
|
arena.alloc("Task"),
|
||||||
arena.alloc([*loc_type, Loc::at(region, TypeAnnotation::Inferred)]),
|
arena.alloc([
|
||||||
|
*loc_type,
|
||||||
|
Loc::at(loc_type.region, TypeAnnotation::Inferred),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
comment: None,
|
comment: None,
|
||||||
body_pattern: new_pat,
|
body_pattern: arena.alloc(Loc::at(
|
||||||
|
loc_pat.region,
|
||||||
|
Pattern::Identifier { ident: new_ident },
|
||||||
|
)),
|
||||||
body_expr: loc_expr,
|
body_expr: loc_expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
// #!a0 (variable)
|
// #!0_expr (variable)
|
||||||
let new_var = arena.alloc(Loc::at(
|
let new_var = arena.alloc(Loc::at(
|
||||||
region,
|
region,
|
||||||
Expr::Var {
|
Expr::Var {
|
||||||
|
@ -895,10 +917,18 @@ pub fn apply_task_await<'a>(
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
// (
|
||||||
|
// #!0_expr : Task loc_type _
|
||||||
|
// #!0_expr = loc_expr
|
||||||
|
// #!0_expr
|
||||||
|
// )
|
||||||
let mut defs = roc_parse::ast::Defs::default();
|
let mut defs = roc_parse::ast::Defs::default();
|
||||||
defs.push_value_def(value_def, region, &[], &[]);
|
defs.push_value_def(value_def, region, &[], &[]);
|
||||||
|
|
||||||
arena.alloc(Loc::at(region, Defs(arena.alloc(defs), new_var)))
|
arena.alloc(Loc::at(
|
||||||
|
Region::span_across(&loc_ann_pat.region, &loc_expr.region),
|
||||||
|
Defs(arena.alloc(defs), new_var),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// loc_pat = loc_expr!
|
// loc_pat = loc_expr!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue