summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-09-26 07:45:33 +0200
committerAraq <rumpf_a@web.de>2011-09-26 07:45:33 +0200
commit7c34357856f0922fb265d81f1d215008b2dd8c14 (patch)
tree63bf05691c6f5c0f6da96ef03116b5895d016cda
parent14968fba46a0c1128f38859b339c7384f9f96cd4 (diff)
downloadNim-7c34357856f0922fb265d81f1d215008b2dd8c14.tar.gz
bugfix: $ escaping in interpolatedFragments
-rwxr-xr-xlib/pure/parseutils.nim18
-rw-r--r--tests/accept/run/tstringinterp.nim16
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)