diff options
-rwxr-xr-x | lib/pure/parseutils.nim | 18 | ||||
-rw-r--r-- | tests/accept/run/tstringinterp.nim | 16 |
2 files changed, 22 insertions, 12 deletions
diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index 001872db2..0e1619cdd 100755 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -269,8 +269,9 @@ proc parseFloat*(s: string, number: var float, start = 0): int {. type TInterpolatedKind* = enum ## describes for `interpolatedFragments` ## which part of the interpolated string is - ## yielded; for example in "str$var${expr}" - ikStr, ## ``str`` part of the interpolated string + ## yielded; for example in "str$$$var${expr}" + ikStr, ## ``str`` part of the interpolated string + ikDollar, ## escaped ``$`` part of the interpolated string ikVar, ## ``var`` part of the interpolated string ikExpr ## ``expr`` part of the interpolated string @@ -281,7 +282,7 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, ## Example: ## ## .. code-block:: nimrod - ## for k, v in interpolatedFragments(" $this is ${an example} "): + ## for k, v in interpolatedFragments(" $this is ${an example} $$"): ## echo "(", k, ", \"", v, "\")" ## ## Results in: @@ -291,12 +292,13 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, ## (ikExpr, "this") ## (ikString, " is ") ## (ikExpr, "an example") - ## (ikString, " ") + ## (ikString, " ") + ## (ikDollar, "$") var i = 0 var kind: TInterpolatedKind while true: var j = i - if s[j] == '$' and s[j+1] != '$': + if s[j] == '$': if s[j+1] == '{': inc j, 2 var nesting = 0 @@ -320,11 +322,15 @@ iterator interpolatedFragments*(s: string): tuple[kind: TInterpolatedKind, while s[j] in IdentChars: inc(j) inc i # skip $ kind = ikVar + elif s[j+1] == '$': + inc j, 2 + inc i # skip $ + kind = ikDollar else: raise newException(EInvalidValue, "Unable to parse a varible name at " & s[i..s.len]) else: - while j < s.len and (s[j] != '$' or s[j+1] == '$'): inc j + while j < s.len and s[j] != '$': inc j kind = ikStr if j > i: # do not copy the trailing } for ikExpr: diff --git a/tests/accept/run/tstringinterp.nim b/tests/accept/run/tstringinterp.nim index 0d402edc3..e1a55c94b 100644 --- a/tests/accept/run/tstringinterp.nim +++ b/tests/accept/run/tstringinterp.nim @@ -1,6 +1,6 @@ discard """ file: "tstringinterp.nim" - output: "Hello Alice, 64 | Hello Bob, 10" + output: "Hello Alice, 64 | Hello Bob, 10$" """ import macros, parseutils, strutils @@ -12,10 +12,10 @@ proc concat(strings: openarray[string]): string = template ProcessInterpolations(e: expr) = var s = e[1].strVal for f in interpolatedFragments(s): - if f.kind == ikStr: - addString(f.value) - else: - addExpr(newCall("$", parseExpr(f.value))) + case f.kind + of ikStr: addString(f.value) + of ikDollar: addDollar() + of ikVar, ikExpr: addExpr(newCall("$", parseExpr(f.value))) macro formatStyleInterpolation(e: expr): expr = var @@ -30,6 +30,9 @@ macro formatStyleInterpolation(e: expr): expr = arrayNode.add(e) formatString.add("$" & $(idx)) inc idx + + proc addDollar() = + formatString.add("$$") ProcessInterpolations(e) @@ -43,6 +46,7 @@ macro concatStyleInterpolation(e: expr): expr = proc addString(s: string) = args.add(newStrLitNode(s)) proc addExpr(e: expr) = args.add(e) + proc addDollar() = args.add(newStrLitNode"$") ProcessInterpolations(e) @@ -62,7 +66,7 @@ var var s1 = concatStyleInterpolation"Hello ${alice}, ${sum(a, b, c)}" - s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}" + s2 = formatStyleInterpolation"Hello ${bob}, ${sum(alice.len, bob.len, 2)}$$" write(stdout, s1 & " | " & s2) |