summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/strformat.nim37
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/pure/strformat.nim b/lib/pure/strformat.nim
index 7ab359038..c232c8a46 100644
--- a/lib/pure/strformat.nim
+++ b/lib/pure/strformat.nim
@@ -74,6 +74,20 @@ runnableExamples:
   assert fmt"{123.456:13e}" == " 1.234560e+02"
 
 ##[
+# Expressions
+]##
+runnableExamples:
+  let x = 3.14
+  assert fmt"{(if x!=0: 1.0/x else: 0):.5}" == "0.31847"
+  assert fmt"""{(block:
+    var res: string
+    for i in 1..15:
+      res.add (if i mod 15 == 0: "FizzBuzz"
+        elif i mod 5 == 0: "Buzz"
+        elif i mod 3 == 0: "Fizz"
+        else: $i) & " "
+    res)}""" == "1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz "
+##[
 # Debugging strings
 
 `fmt"{expr=}"` expands to `fmt"expr={expr}"` namely the text of the expression,
@@ -557,7 +571,7 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
   # XXX: https://github.com/nim-lang/Nim/issues/8405
   # When compiling with -d:useNimRtl, certain procs such as `count` from the strutils
   # module are not accessible at compile-time:
-  let expectedGrowth = when defined(useNimRtl): 0 else: count(f, '{') * 10
+  let expectedGrowth = when defined(useNimRtl): 0 else: count(f, openChar) * 10
   result.add newVarStmt(res, newCall(bindSym"newStringOfCap",
                                      newLit(f.len + expectedGrowth)))
   var strlit = ""
@@ -573,8 +587,12 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
           strlit = ""
 
         var subexpr = ""
-        while i < f.len and f[i] != closeChar and f[i] != ':':
-          if f[i] == '=':
+        var inParens = 0
+        while i < f.len and f[i] != closeChar and (f[i] != ':' or inParens!=0):
+          case f[i]
+          of '(': inc inParens
+          of ')': dec inParens
+          of '=':
             let start = i
             inc i
             i += f.skipWhitespace(i)
@@ -582,10 +600,11 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
               result.add newCall(bindSym"add", res, newLit(subexpr & f[start ..< i]))
             else:
               subexpr.add f[start ..< i]
-          else:
-            subexpr.add f[i]
-            inc i
-
+            continue
+          else: discard
+          subexpr.add f[i]
+          inc i
+         
         var x: NimNode
         try:
           x = parseExpr(subexpr)
@@ -608,11 +627,11 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
           doAssert false, "invalid format string: missing '}'"
         result.add newCall(formatSym, res, x, newLit(options))
     elif f[i] == closeChar:
-      if f[i+1] == closeChar:
+      if i<f.len-1 and f[i+1] == closeChar:
         strlit.add closeChar
         inc i, 2
       else:
-        doAssert false, "invalid format string: '}' instead of '}}'"
+        doAssert false, "invalid format string: '$1' instead of '$1$1'" % $closeChar
         inc i
     else:
       strlit.add f[i]