mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-30 18:41:45 +00:00
bugfix: $ escaping in interpolatedFragments
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user