Desugar inside string interpolation

This commit is contained in:
Richard Feldman 2023-07-29 18:11:41 -04:00
parent 9e0e756d3b
commit 42fb593471
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
2 changed files with 64 additions and 4 deletions

View file

@ -7,7 +7,9 @@ use roc_module::called_via::BinOp::Pizza;
use roc_module::called_via::{BinOp, CalledVia};
use roc_module::ident::ModuleName;
use roc_parse::ast::Expr::{self, *};
use roc_parse::ast::{AssignedField, Collection, RecordBuilderField, ValueDef, WhenBranch};
use roc_parse::ast::{
AssignedField, Collection, RecordBuilderField, StrLiteral, StrSegment, ValueDef, WhenBranch,
};
use roc_region::all::{Loc, Region};
// BinOp precedence logic adapted from Gluon by Markus Westerlind
@ -129,7 +131,6 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
Float(..)
| Num(..)
| NonBase10Int { .. }
| Str(_)
| SingleQuote(_)
| AccessorFunction(_)
| Var { .. }
@ -144,6 +145,28 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
| IngestedFile(_, _)
| Crash => loc_expr,
Str(str_literal) => match str_literal {
StrLiteral::PlainLine(_) => loc_expr,
StrLiteral::Line(segments) => {
let region = loc_expr.region;
let value = Str(StrLiteral::Line(desugar_str_segments(arena, segments)));
arena.alloc(Loc { region, value })
}
StrLiteral::Block(lines) => {
let region = loc_expr.region;
let new_lines = Vec::from_iter_in(
lines
.into_iter()
.map(|segments| desugar_str_segments(arena, segments)),
arena,
);
let value = Str(StrLiteral::Block(new_lines.into_bump_slice()));
arena.alloc(Loc { region, value })
}
},
TupleAccess(sub_expr, paths) => {
let region = loc_expr.region;
let loc_sub_expr = Loc {
@ -444,6 +467,34 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
}
}
fn desugar_str_segments<'a>(
arena: &'a Bump,
segments: &'a [StrSegment<'a>],
) -> &'a [StrSegment<'a>] {
Vec::from_iter_in(
segments.into_iter().map(|segment| match segment {
StrSegment::Plaintext(_) | StrSegment::Unicode(_) | StrSegment::EscapedChar(_) => {
*segment
}
StrSegment::Interpolated(loc_expr) => {
let loc_desugared = desugar_expr(
arena,
arena.alloc(Loc {
region: loc_expr.region,
value: *loc_expr.value,
}),
);
StrSegment::Interpolated(Loc {
region: loc_desugared.region,
value: arena.alloc(loc_desugared.value),
})
}
}),
arena,
)
.into_bump_slice()
}
fn desugar_field<'a>(
arena: &'a Bump,
field: &'a AssignedField<'a, Expr<'a>>,