mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Merge pull request #7497 from smores56/new-interpolation-syntax
Move to new interpolation syntax
This commit is contained in:
commit
528d1d2b69
66 changed files with 630 additions and 596 deletions
|
@ -887,7 +887,7 @@ increase_size = \@Dict({ data, max_bucket_capacity, max_load_factor, shifts }) -
|
|||
},
|
||||
)
|
||||
else
|
||||
crash("Dict hit limit of $(Num.to_str(max_bucket_count)) elements. Unable to grow more.")
|
||||
crash("Dict hit limit of ${Num.to_str(max_bucket_count)} elements. Unable to grow more.")
|
||||
|
||||
alloc_buckets_from_shift : U8, F32 -> (List Bucket, U64)
|
||||
alloc_buckets_from_shift = \shifts, max_load_factor ->
|
||||
|
|
|
@ -1485,7 +1485,7 @@ for_each! = \list, func! ->
|
|||
## List.for_each_try!(files_to_delete, \path ->
|
||||
## File.delete!(path)?
|
||||
##
|
||||
## Stdout.line!("$(path) deleted")
|
||||
## Stdout.line!("${path} deleted")
|
||||
## )
|
||||
## ```
|
||||
for_each_try! : List a, (a => Result {} err) => Result {} err
|
||||
|
@ -1527,14 +1527,15 @@ walk! = \list, state, func! ->
|
|||
## If the function returns `Err`, the iteration stops and the error is returned.
|
||||
##
|
||||
## ```
|
||||
## names = try List.walk_try!(
|
||||
## names =
|
||||
## List.walk_try!(
|
||||
## ["First", "Middle", "Last"],
|
||||
## [],
|
||||
## \accumulator, which ->
|
||||
## try Stdout.write! ("$(which) name: ")
|
||||
## name = try Stdin.line! ({})
|
||||
## Ok (List.append accumulator name),
|
||||
## )
|
||||
## Stdout.write!("${which} name: ")?
|
||||
## name = Stdin.line!({})?
|
||||
## Ok(List.append(accumulator, name)),
|
||||
## )?
|
||||
## ```
|
||||
##
|
||||
## This is the same as [walk_try], except that the step function can have effects.
|
||||
|
|
|
@ -124,11 +124,12 @@ on_err = \result, transform ->
|
|||
## Like [on_err], but it allows the transformation function to produce effects.
|
||||
##
|
||||
## ```roc
|
||||
## Result.on_err(Err("missing user"), (\msg ->
|
||||
## Stdout.line!("ERROR: $(msg)")?
|
||||
##
|
||||
## Err(msg)
|
||||
## ))
|
||||
## Result.on_err(
|
||||
## Err("missing user"),
|
||||
## \msg ->
|
||||
## Stdout.line!("ERROR: ${msg}")?
|
||||
## Err(msg),
|
||||
## )
|
||||
## ```
|
||||
on_err! : Result a err, (err => Result a other_err) => Result a other_err
|
||||
on_err! = \result, transform! ->
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
## ```
|
||||
## name = "Sam"
|
||||
##
|
||||
## "Hi, my name is $(name)!"
|
||||
## "Hi, my name is ${name}!"
|
||||
## ```
|
||||
##
|
||||
## This will evaluate to the string `"Hi, my name is Sam!"`
|
||||
|
@ -44,7 +44,7 @@
|
|||
## ```
|
||||
## colors = ["red", "green", "blue"]
|
||||
##
|
||||
## "The colors are $(colors |> Str.join_with(", "))!"
|
||||
## "The colors are ${colors |> Str.join_with(", ")}!"
|
||||
## ```
|
||||
##
|
||||
## Interpolation can be used in multiline strings, but the part inside the parentheses must still be on one line.
|
||||
|
@ -800,7 +800,7 @@ replace_first : Str, Str, Str -> Str
|
|||
replace_first = \haystack, needle, flower ->
|
||||
when split_first(haystack, needle) is
|
||||
Ok({ before, after }) ->
|
||||
"$(before)$(flower)$(after)"
|
||||
"${before}${flower}${after}"
|
||||
|
||||
Err(NotFound) -> haystack
|
||||
|
||||
|
@ -818,7 +818,7 @@ replace_last : Str, Str, Str -> Str
|
|||
replace_last = \haystack, needle, flower ->
|
||||
when split_last(haystack, needle) is
|
||||
Ok({ before, after }) ->
|
||||
"$(before)$(flower)$(after)"
|
||||
"${before}${flower}${after}"
|
||||
|
||||
Err(NotFound) -> haystack
|
||||
|
||||
|
|
|
@ -2157,10 +2157,10 @@ mod test_can {
|
|||
// // This should NOT be string interpolation, because of the \\
|
||||
// indoc!(
|
||||
// r#"
|
||||
// "abcd\$(efg)hij"
|
||||
// "abcd\${efg}hij"
|
||||
// "#
|
||||
// ),
|
||||
// Str(r"abcd$(efg)hij".into()),
|
||||
// Str(r"abcd${efg}hij".into()),
|
||||
// );
|
||||
// }
|
||||
|
||||
|
|
|
@ -911,8 +911,8 @@ fn format_str_segment(seg: &StrSegment, buf: &mut Buf) {
|
|||
buf.push(escaped.to_parsed_char());
|
||||
}
|
||||
Interpolated(loc_expr) => {
|
||||
buf.push_str("$(");
|
||||
// e.g. (name) in "Hi, $(name)!"
|
||||
buf.push_str("${");
|
||||
// e.g. {name} in "Hi, ${name}!"
|
||||
let min_indent = buf.cur_line_indent() + INDENT;
|
||||
loc_expr.value.format_with_options(
|
||||
buf,
|
||||
|
@ -921,7 +921,7 @@ fn format_str_segment(seg: &StrSegment, buf: &mut Buf) {
|
|||
min_indent,
|
||||
);
|
||||
buf.indent(min_indent);
|
||||
buf.push(')');
|
||||
buf.push('}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5864,7 +5864,7 @@ mod test_reporting {
|
|||
r#"
|
||||
greeting = "Privet"
|
||||
|
||||
if Bool.true then 1 else "$(greeting), World!"
|
||||
if Bool.true then 1 else "${greeting}, World!"
|
||||
"#,
|
||||
),
|
||||
@r#"
|
||||
|
@ -5872,7 +5872,7 @@ mod test_reporting {
|
|||
|
||||
This `if` has an `else` branch with a different type from its `then` branch:
|
||||
|
||||
6│ if Bool.true then 1 else "$(greeting), World!"
|
||||
6│ if Bool.true then 1 else "${greeting}, World!"
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The `else` branch is a string of type:
|
||||
|
@ -15052,7 +15052,7 @@ All branches in an `if` must have the same type!
|
|||
u64_nums = parse_items_with Str.to_u64
|
||||
u8_nums = parse_items_with Str.to_u8
|
||||
|
||||
"$(Inspect.to_str u64_nums) $(Inspect.to_str u8_nums)"
|
||||
"${Inspect.to_str(u64_nums)} ${Inspect.to_str(u8_nums)}"
|
||||
"#
|
||||
),
|
||||
@"" // no errors
|
||||
|
@ -15304,7 +15304,7 @@ All branches in an `if` must have the same type!
|
|||
get_cheer = \msg ->
|
||||
name = Effect.get_line! {}
|
||||
|
||||
"$(msg), $(name)!"
|
||||
"${msg}, ${name}!"
|
||||
"#
|
||||
),
|
||||
@r"
|
||||
|
@ -15340,7 +15340,7 @@ All branches in an `if` must have the same type!
|
|||
|
||||
trim : Str -> Str
|
||||
trim = \msg ->
|
||||
Effect.put_line! "Trimming $(msg)"
|
||||
Effect.put_line!("Trimming ${msg}")
|
||||
Str.trim msg
|
||||
"#
|
||||
),
|
||||
|
@ -15349,7 +15349,7 @@ All branches in an `if` must have the same type!
|
|||
|
||||
This call to `Effect.put_line!` might produce an effect:
|
||||
|
||||
10│ Effect.put_line! "Trimming $(msg)"
|
||||
10│ Effect.put_line!("Trimming ${msg}")
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
However, the type of the enclosing function requires that it's pure:
|
||||
|
@ -15736,7 +15736,7 @@ All branches in an `if` must have the same type!
|
|||
(get, put) = (Effect.get_line!, Effect.put_line!)
|
||||
|
||||
name = get {}
|
||||
put "Hi, $(name)"
|
||||
put "Hi, ${name}"
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
|
@ -15808,7 +15808,7 @@ All branches in an `if` must have the same type!
|
|||
Tag get put = Tag Effect.get_line! Effect.put_line!
|
||||
|
||||
name = get {}
|
||||
put "Hi, $(name)"
|
||||
put "Hi, ${name}"
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
|
|
|
@ -1574,7 +1574,7 @@ fn module_params_checks() {
|
|||
r#"
|
||||
module { key } -> [url]
|
||||
|
||||
url = "example.com/$(key)"
|
||||
url = "example.com/${key}"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
@ -1605,7 +1605,7 @@ fn module_params_optional() {
|
|||
r#"
|
||||
module { key, exp ? "default" } -> [url]
|
||||
|
||||
url = "example.com/$(key)?exp=$(exp)"
|
||||
url = "example.com/${key}?exp=${exp}"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
@ -1636,7 +1636,7 @@ fn module_params_typecheck_fail() {
|
|||
r#"
|
||||
module { key } -> [url]
|
||||
|
||||
url = "example.com/$(key)"
|
||||
url = "example.com/${key}"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
@ -1687,7 +1687,7 @@ fn module_params_missing_fields() {
|
|||
r#"
|
||||
module { key } -> [url]
|
||||
|
||||
url = "example.com/$(key)"
|
||||
url = "example.com/${key}"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
@ -1740,7 +1740,7 @@ fn module_params_extra_fields() {
|
|||
r#"
|
||||
module { key } -> [url]
|
||||
|
||||
url = "example.com/$(key)"
|
||||
url = "example.com/${key}"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
@ -1839,7 +1839,7 @@ fn module_params_missing() {
|
|||
r#"
|
||||
module { key, exp } -> [url]
|
||||
|
||||
url = "example.com/$(key)?exp=$(Num.to_str exp)"
|
||||
url = "example.com/${key}?exp=${Num.to_str(exp)}"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
@ -2169,7 +2169,7 @@ fn roc_package_depends_on_other_package() {
|
|||
r#"
|
||||
module [say]
|
||||
|
||||
say = \msg -> "$(msg), world!"
|
||||
say = \msg -> "${msg}, world!"
|
||||
"#
|
||||
),
|
||||
),
|
||||
|
|
|
@ -75,7 +75,7 @@ pub enum CalledVia {
|
|||
UnaryOp(UnaryOp),
|
||||
|
||||
/// This call is the result of desugaring string interpolation,
|
||||
/// e.g. "$(first) $(last)" is transformed into Str.concat (Str.concat first " ") last.
|
||||
/// e.g. "${first} ${last}" is transformed into `Str.concat(Str.concat(first, " "))` last.
|
||||
StringInterpolation,
|
||||
|
||||
/// This call is the result of desugaring a map2-based Record Builder field. e.g.
|
||||
|
|
|
@ -425,16 +425,18 @@ pub fn parse_str_like_literal<'a>() -> impl Parser<'a, StrLikeLiteral<'a>, EStri
|
|||
}
|
||||
}
|
||||
}
|
||||
b'(' if preceded_by_dollar && !is_single_quote => {
|
||||
b'(' | b'{' if preceded_by_dollar && !is_single_quote => {
|
||||
let old_style_interpolation_block = one_byte == b'(';
|
||||
|
||||
// We're about to begin string interpolation!
|
||||
//
|
||||
// End the previous segment so we can begin a new one.
|
||||
// Retroactively end it right before the `$` char we parsed.
|
||||
// (We can't use end_segment! here because it ends it right after
|
||||
// the just-parsed character, which here would be '(' rather than '$')
|
||||
// the just-parsed character, which here would be '{' rather than '$')
|
||||
// Don't push anything if the string would be empty.
|
||||
if segment_parsed_bytes > 2 {
|
||||
// exclude the 2 chars we just parsed, namely '$' and '('
|
||||
// exclude the 2 chars we just parsed, namely '$' and '{'
|
||||
let string_bytes = &state.bytes()[0..(segment_parsed_bytes - 2)];
|
||||
|
||||
match std::str::from_utf8(string_bytes) {
|
||||
|
@ -452,19 +454,27 @@ pub fn parse_str_like_literal<'a>() -> impl Parser<'a, StrLikeLiteral<'a>, EStri
|
|||
}
|
||||
}
|
||||
|
||||
// Advance past the `$(`
|
||||
// Advance past the `${`
|
||||
state.advance_mut(2);
|
||||
|
||||
let original_byte_count = state.bytes().len();
|
||||
|
||||
// Parse an arbitrary expression, followed by ')'
|
||||
// Parse an arbitrary expression, followed by '}' or ')'
|
||||
let terminating_char = if old_style_interpolation_block {
|
||||
b')'
|
||||
} else {
|
||||
b'}'
|
||||
};
|
||||
let (_progress, (mut loc_expr, sp), new_state) = and(
|
||||
specialize_err_ref(
|
||||
EString::Format,
|
||||
loc(allocated(reset_min_indent(expr::expr_help())))
|
||||
.trace("str_interpolation"),
|
||||
),
|
||||
skip_second(space0_e(EString::FormatEnd), byte(b')', EString::FormatEnd)),
|
||||
skip_second(
|
||||
space0_e(EString::FormatEnd),
|
||||
byte(terminating_char, EString::FormatEnd),
|
||||
),
|
||||
)
|
||||
.parse(arena, state, min_indent)?;
|
||||
|
||||
|
@ -488,8 +498,8 @@ pub fn parse_str_like_literal<'a>() -> impl Parser<'a, StrLikeLiteral<'a>, EStri
|
|||
}
|
||||
}
|
||||
|
||||
// iff the '$' is followed by '(', this is string interpolation.
|
||||
// We'll check for the '(' on the next iteration of the loop.
|
||||
// iff the '$' is followed by '{', this is string interpolation.
|
||||
// We'll check for the '{' on the next iteration of the loop.
|
||||
preceded_by_dollar = one_byte == b'$';
|
||||
}
|
||||
|
||||
|
|
|
@ -160,17 +160,17 @@ mod test_parse {
|
|||
|
||||
#[test]
|
||||
fn escaped_interpolation() {
|
||||
assert_segments(r#""Hi, \$(name)!""#, |arena| {
|
||||
assert_segments(r#""Hi, \${name}!""#, |arena| {
|
||||
bumpalo::vec![in arena;
|
||||
Plaintext("Hi, "),
|
||||
EscapedChar(EscapedChar::Dollar),
|
||||
Plaintext("(name)!"),
|
||||
Plaintext("{name}!"),
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_middle() {
|
||||
fn string_with_old_interpolation_still_works_for_now() {
|
||||
assert_segments(r#""Hi, $(name)!""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
|
@ -185,9 +185,31 @@ mod test_parse {
|
|||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_with_mixed_new_and_old_interpolation_braces_fails() {
|
||||
assert_parsing_fails(r#""${foo)""#, SyntaxError::Unexpected(Region::zero()));
|
||||
assert_parsing_fails(r#""$(foo}""#, SyntaxError::Unexpected(Region::zero()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_middle() {
|
||||
assert_segments(r#""Hi, ${name}!""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
});
|
||||
|
||||
bumpalo::vec![in arena;
|
||||
Plaintext("Hi, "),
|
||||
Interpolated(Loc::new(7, 11, expr)),
|
||||
Plaintext("!")
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_front() {
|
||||
assert_segments(r#""$(name), hi!""#, |arena| {
|
||||
assert_segments(r#""${name}, hi!""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
@ -232,7 +254,7 @@ mod test_parse {
|
|||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_back() {
|
||||
assert_segments(r#""Hello $(name)""#, |arena| {
|
||||
assert_segments(r#""Hello ${name}""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
@ -247,7 +269,7 @@ mod test_parse {
|
|||
|
||||
#[test]
|
||||
fn string_with_multiple_interpolations() {
|
||||
assert_segments(r#""Hi, $(name)! How is $(project) going?""#, |arena| {
|
||||
assert_segments(r#""Hi, ${name}! How is ${project} going?""#, |arena| {
|
||||
let expr1 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
@ -271,7 +293,7 @@ mod test_parse {
|
|||
#[test]
|
||||
fn string_with_non_interpolation_dollar_signs() {
|
||||
assert_segments(
|
||||
r#""$a Hi, $(name)! $b How is $(project) going? $c""#,
|
||||
r#""$a Hi, ${name}! $b How is ${project} going? $c""#,
|
||||
|arena| {
|
||||
let expr1 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
|
|
|
@ -324,7 +324,7 @@ mod solve_expr {
|
|||
r#"
|
||||
what_it_is = "great"
|
||||
|
||||
"type inference is $(what_it_is)!"
|
||||
"type inference is ${what_it_is}!"
|
||||
"#
|
||||
),
|
||||
"Str",
|
||||
|
@ -338,7 +338,7 @@ mod solve_expr {
|
|||
r#"
|
||||
what_it_is = "great"
|
||||
|
||||
str = "type inference is $(what_it_is)!"
|
||||
str = "type inference is ${what_it_is}!"
|
||||
|
||||
what_it_is
|
||||
"#
|
||||
|
@ -354,7 +354,7 @@ mod solve_expr {
|
|||
r#"
|
||||
rec = { what_it_is: "great" }
|
||||
|
||||
str = "type inference is $(rec.what_it_is)!"
|
||||
str = "type inference is ${rec.what_it_is}!"
|
||||
|
||||
rec
|
||||
"#
|
||||
|
@ -4751,7 +4751,7 @@ mod solve_expr {
|
|||
r#"
|
||||
set_roc_email : _ -> { name: Str, email: Str }_
|
||||
set_roc_email = \person ->
|
||||
{ person & email: "$(person.name)@roclang.com" }
|
||||
{ person & email: "${person.name}@roclang.com" }
|
||||
set_roc_email
|
||||
"#
|
||||
),
|
||||
|
|
|
@ -330,7 +330,7 @@ fn list_map_try_ok() {
|
|||
List.map_try [1, 2, 3] \num ->
|
||||
str = Num.to_str (num * 2)
|
||||
|
||||
Ok "$(str)!"
|
||||
Ok "${str}!"
|
||||
"#,
|
||||
// Result Str [] is unwrapped to just Str
|
||||
RocList::<RocStr>::from_slice(&[
|
||||
|
@ -3870,10 +3870,10 @@ fn issue_3571_lowlevel_call_function_with_bool_lambda_set() {
|
|||
List.concat state mapped_vals
|
||||
|
||||
add2 : Str -> Str
|
||||
add2 = \x -> "added $(x)"
|
||||
add2 = \x -> "added ${x}"
|
||||
|
||||
mul2 : Str -> Str
|
||||
mul2 = \x -> "multiplied $(x)"
|
||||
mul2 = \x -> "multiplied ${x}"
|
||||
|
||||
foo = [add2, mul2]
|
||||
bar = ["1", "2", "3", "4"]
|
||||
|
|
|
@ -3120,7 +3120,7 @@ fn recursively_build_effect() {
|
|||
hi = "Hello"
|
||||
name = "World"
|
||||
|
||||
"$(hi), $(name)!"
|
||||
"${hi}, ${name}!"
|
||||
|
||||
main =
|
||||
when nest_help 4 is
|
||||
|
@ -3876,8 +3876,8 @@ fn compose_recursive_lambda_set_productive_toplevel() {
|
|||
compose = \f, g -> \x -> g (f x)
|
||||
|
||||
identity = \x -> x
|
||||
exclaim = \s -> "$(s)!"
|
||||
whisper = \s -> "($(s))"
|
||||
exclaim = \s -> "${s}!"
|
||||
whisper = \s -> "(${s})"
|
||||
|
||||
main =
|
||||
res: Str -> Str
|
||||
|
@ -3899,8 +3899,8 @@ fn compose_recursive_lambda_set_productive_nested() {
|
|||
compose = \f, g -> \x -> g (f x)
|
||||
|
||||
identity = \x -> x
|
||||
exclaim = \s -> "$(s)!"
|
||||
whisper = \s -> "($(s))"
|
||||
exclaim = \s -> "${s}!"
|
||||
whisper = \s -> "(${s})"
|
||||
|
||||
res: Str -> Str
|
||||
res = List.walk [ exclaim, whisper ] identity compose
|
||||
|
@ -3921,8 +3921,8 @@ fn compose_recursive_lambda_set_productive_inferred() {
|
|||
compose = \f, g -> \x -> g (f x)
|
||||
|
||||
identity = \x -> x
|
||||
exclaim = \s -> "$(s)!"
|
||||
whisper = \s -> "($(s))"
|
||||
exclaim = \s -> "${s}!"
|
||||
whisper = \s -> "(${s})"
|
||||
|
||||
res = List.walk [ exclaim, whisper ] identity compose
|
||||
res "hello"
|
||||
|
@ -3947,8 +3947,8 @@ fn compose_recursive_lambda_set_productive_nullable_wrapped() {
|
|||
else \x -> f (g x)
|
||||
|
||||
identity = \x -> x
|
||||
exclame = \s -> "$(s)!"
|
||||
whisper = \s -> "($(s))"
|
||||
exclame = \s -> "${s}!"
|
||||
whisper = \s -> "(${s})"
|
||||
|
||||
main =
|
||||
res: Str -> Str
|
||||
|
@ -4475,7 +4475,7 @@ fn reset_recursive_type_wraps_in_named_type() {
|
|||
Cons x xs ->
|
||||
str_x = f x
|
||||
str_xs = print_linked_list xs f
|
||||
"Cons $(str_x) ($(str_xs))"
|
||||
"Cons ${str_x} (${str_xs})"
|
||||
"#
|
||||
),
|
||||
RocStr::from("Cons 2 (Cons 3 (Cons 4 (Nil)))"),
|
||||
|
|
|
@ -37,7 +37,7 @@ fn early_return_nested_ifs() {
|
|||
else
|
||||
third
|
||||
|
||||
"$(first), $(second)"
|
||||
"${first}, ${second}"
|
||||
|
||||
main : List Str
|
||||
main = List.map [1, 2, 3] display_n
|
||||
|
@ -76,7 +76,7 @@ fn early_return_nested_whens() {
|
|||
_ ->
|
||||
third
|
||||
|
||||
"$(first), $(second)"
|
||||
"${first}, ${second}"
|
||||
|
||||
main : List Str
|
||||
main = List.map [1, 2, 3] display_n
|
||||
|
|
|
@ -1759,7 +1759,7 @@ fn lambda_capture_niches_with_other_lambda_capture() {
|
|||
when val is
|
||||
_ -> ""
|
||||
|
||||
capture2 = \val -> \{} -> "$(val)"
|
||||
capture2 = \val -> \{} -> "${val}"
|
||||
|
||||
x : [A, B, C]
|
||||
x = A
|
||||
|
@ -2072,7 +2072,7 @@ fn polymorphic_expression_unification() {
|
|||
]
|
||||
parse_function : Str -> RenderTree
|
||||
parse_function = \name ->
|
||||
last = Indent [Text ".trace(\"$(name)\")" ]
|
||||
last = Indent [Text ".trace(\"${name}\")" ]
|
||||
Indent [last]
|
||||
|
||||
values = parse_function "interface_header"
|
||||
|
@ -2636,7 +2636,7 @@ fn recursively_build_effect() {
|
|||
hi = "Hello"
|
||||
name = "World"
|
||||
|
||||
"$(hi), $(name)!"
|
||||
"${hi}, ${name}!"
|
||||
|
||||
main =
|
||||
when nest_help 4 is
|
||||
|
@ -2956,8 +2956,8 @@ fn compose_recursive_lambda_set_productive_nullable_wrapped() {
|
|||
else \x -> f (g x)
|
||||
|
||||
identity = \x -> x
|
||||
exclaim = \s -> "$(s)!"
|
||||
whisper = \s -> "($(s))"
|
||||
exclaim = \s -> "${s}!"
|
||||
whisper = \s -> "(${s})"
|
||||
|
||||
main =
|
||||
res: Str -> Str
|
||||
|
@ -3291,7 +3291,7 @@ fn dbg_nested_expr() {
|
|||
fn dbg_inside_string() {
|
||||
indoc!(
|
||||
r#"
|
||||
"Hello $(dbg "world")!"
|
||||
"Hello ${dbg "world"}!"
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
@ -3690,7 +3690,7 @@ fn dec_refcount_for_usage_after_early_return_in_if() {
|
|||
else
|
||||
third
|
||||
|
||||
"$(first), $(second)"
|
||||
"${first}, ${second}"
|
||||
|
||||
display_n 3
|
||||
"#
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
"$(g)" : q
|
||||
"${g}" : q
|
||||
f
|
|
@ -1,2 +1,2 @@
|
|||
"""$(g)""":q
|
||||
"""${g}""":q
|
||||
f
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""
|
||||
"""
|
||||
"$(i
|
||||
"${i
|
||||
"""
|
||||
""")"
|
||||
"""}"
|
|
@ -1 +1 @@
|
|||
"""""""$(i"""""")"
|
||||
"""""""${i""""""}"
|
|
@ -1,8 +1,8 @@
|
|||
"""
|
||||
$({
|
||||
${{
|
||||
}
|
||||
i)
|
||||
$({
|
||||
i}
|
||||
${{
|
||||
}
|
||||
i)
|
||||
i}
|
||||
"""
|
|
@ -1,4 +1,4 @@
|
|||
"""$({
|
||||
}i)
|
||||
$({
|
||||
}i)"""
|
||||
"""${{
|
||||
}i}
|
||||
${{
|
||||
}i}"""
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
"$(S #
|
||||
)"
|
||||
"${S #
|
||||
}"
|
|
@ -1,2 +1,2 @@
|
|||
"$((S#
|
||||
))"
|
||||
"${(S#
|
||||
)}"
|
||||
|
|
|
@ -3,5 +3,5 @@ main =
|
|||
|> List.dropFirst 1
|
||||
|> List.mapTry? Str.toU8
|
||||
|> List.sum
|
||||
|> \total -> "Sum of numbers: $(Num.to_str total)"
|
||||
|> \total -> "Sum of numbers: ${Num.to_str total}"
|
||||
|> Str.toUpper
|
||||
|
|
|
@ -6575,13 +6575,13 @@ mod test_fmt {
|
|||
expr_formats_to(
|
||||
indoc!(
|
||||
"
|
||||
x = \"foo:\u{200B} $(bar).\"
|
||||
x = \"foo:\u{200B} ${bar}.\"
|
||||
x
|
||||
"
|
||||
),
|
||||
indoc!(
|
||||
r#"
|
||||
x = "foo:\u(200b) $(bar)."
|
||||
x = "foo:\u(200b) ${bar}."
|
||||
x
|
||||
"#
|
||||
),
|
||||
|
@ -6595,7 +6595,7 @@ mod test_fmt {
|
|||
"
|
||||
x =
|
||||
\"\"\"
|
||||
foo:\u{200B} $(bar).
|
||||
foo:\u{200B} ${bar}.
|
||||
\"\"\"
|
||||
x
|
||||
"
|
||||
|
@ -6604,7 +6604,7 @@ mod test_fmt {
|
|||
r#"
|
||||
x =
|
||||
"""
|
||||
foo:\u(200b) $(bar).
|
||||
foo:\u(200b) ${bar}.
|
||||
"""
|
||||
x
|
||||
"#
|
||||
|
|
|
@ -1036,7 +1036,7 @@ mod test_snapshots {
|
|||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_middle() {
|
||||
assert_segments(r#""Hi, $(name)!""#, |arena| {
|
||||
assert_segments(r#""Hi, ${name}!""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
@ -1052,7 +1052,7 @@ mod test_snapshots {
|
|||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_front() {
|
||||
assert_segments(r#""$(name), hi!""#, |arena| {
|
||||
assert_segments(r#""${name}, hi!""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
@ -1067,7 +1067,7 @@ mod test_snapshots {
|
|||
|
||||
#[test]
|
||||
fn string_with_interpolation_in_back() {
|
||||
assert_segments(r#""Hello $(name)""#, |arena| {
|
||||
assert_segments(r#""Hello ${name}""#, |arena| {
|
||||
let expr = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
@ -1082,7 +1082,7 @@ mod test_snapshots {
|
|||
|
||||
#[test]
|
||||
fn string_with_multiple_interpolations() {
|
||||
assert_segments(r#""Hi, $(name)! How is $(project) going?""#, |arena| {
|
||||
assert_segments(r#""Hi, ${name}! How is ${project} going?""#, |arena| {
|
||||
let expr1 = arena.alloc(Var {
|
||||
module_name: "",
|
||||
ident: "name",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue