File tree Expand file tree Collapse file tree 4 files changed +30
-2
lines changed
tests/FScript.Language.Tests Expand file tree Collapse file tree 4 files changed +30
-2
lines changed Original file line number Diff line number Diff line change @@ -4,6 +4,8 @@ All notable changes to FScript are documented in this file.
44
55## [ Unreleased]
66
7+ - Escaped pretty-printed string values (including map string keys) so interpolated strings with embedded quotes render unambiguously in CLI/REPL output.
8+
79## [ 0.54.2]
810
911
Original file line number Diff line number Diff line change @@ -10,13 +10,21 @@ module Pretty =
1010 | _ -> acc
1111 loop [ firstArg ] body
1212
13+ let private escapeStringLiteral ( value : string ) =
14+ value
15+ .Replace( " \\ " , " \\\\ " )
16+ .Replace( " \" " , " \\\" " )
17+ .Replace( " \r " , " \\ r" )
18+ .Replace( " \n " , " \\ n" )
19+ .Replace( " \t " , " \\ t" )
20+
1321 let rec valueToString v =
1422 match v with
1523 | VUnit -> " ()"
1624 | VInt i -> string i
1725 | VFloat f -> string f
1826 | VBool b -> if b then " true" else " false"
19- | VString s -> sprintf " \" %s \" " s
27+ | VString s -> sprintf " \" %s \" " ( escapeStringLiteral s )
2028 | VList xs ->
2129 xs |> List.map valueToString |> String.concat " ;" |> sprintf " [%s ]"
2230 | VTuple xs ->
@@ -30,7 +38,7 @@ module Pretty =
3038 | VMap fields ->
3139 let mapKeyToString key =
3240 match key with
33- | MKString s -> $" \" {s}\" "
41+ | MKString s -> $" \" {escapeStringLiteral s}\" "
3442 | MKInt i -> string i
3543 fields
3644 |> Map.toList
Original file line number Diff line number Diff line change @@ -508,6 +508,12 @@ type EvalTests () =
508508 | VString " missing" -> ()
509509 | _ -> Assert.Fail( " Expected interpolation with string-literal placeholder expression" )
510510
511+ [<Test>]
512+ member _. ``Evaluates interpolation containing escaped quotes around placeholder`` () =
513+ match Helpers.eval " let value = \" '\"\n $\" Path=\\\" {value}\\\"\" " with
514+ | VString " Path=\" '\" " -> ()
515+ | _ -> Assert.Fail( " Expected interpolation value with quoted placeholder content" )
516+
511517 [<Test>]
512518 member _. ``Evaluates typeof for explicit recursive type`` () =
513519 match Helpers.eval " type rec Node = { Value: int; Next: Node option }\n typeof Node" with
Original file line number Diff line number Diff line change @@ -27,3 +27,15 @@ type PrettyTests () =
2727 [<Test>]
2828 member _. ``Formats extern values with name and application progress`` () =
2929 Helpers.evalToString " print" |> should equal " <extern print>"
30+
31+ [<Test>]
32+ member _. ``Escapes quoted interpolation output in strings`` () =
33+ Helpers.evalToString " let value = \" '\"\n $\" Path=\\\" {value}\\\"\" " |> should equal " \" Path=\\\" '\\\"\" "
34+
35+ [<Test>]
36+ member _. ``Escapes special characters in rendered strings`` () =
37+ Helpers.evalToString " \" a\\\" b\\\\ c\\ n\\ t\" " |> should equal " \" a\\\" b\\\\ c\\ n\\ t\" "
38+
39+ [<Test>]
40+ member _. ``Escapes quoted map string keys`` () =
41+ Helpers.evalToString " { [\" a\\\" b\" ] = 1 }" |> should equal " map { \" a\\\" b\" => 1 }"
You can’t perform that action at this time.
0 commit comments