summary refs log tree commit diff stats
path: root/tests/destructor
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-02-28 22:39:15 +0100
committerAndreas Rumpf <rumpf_a@web.de>2019-02-28 22:39:24 +0100
commit728ff1004a60835c18c44b64830ea08dc805485e (patch)
treedf7c9be34196e4a8c47596ccb6a88fe4c43f84f7 /tests/destructor
parent9563be37d3dfed1e4bc9e3ee8955497de48b89a1 (diff)
downloadNim-728ff1004a60835c18c44b64830ea08dc805485e.tar.gz
gc:destructors: progress
Diffstat (limited to 'tests/destructor')
-rw-r--r--tests/destructor/tgcdestructors.nim65
1 files changed, 64 insertions, 1 deletions
diff --git a/tests/destructor/tgcdestructors.nim b/tests/destructor/tgcdestructors.nim
index 1ae2b2549..f83007470 100644
--- a/tests/destructor/tgcdestructors.nim
+++ b/tests/destructor/tgcdestructors.nim
@@ -3,7 +3,7 @@ discard """
   output: '''hi
 ho
 ha
-1 1'''
+7 7'''
 """
 
 import allocators
@@ -21,6 +21,69 @@ const
 for t in test:
   echo t
 
+type
+  InterpolatedKind* = enum
+    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
+
+iterator interpolatedFragments*(s: string): tuple[kind: InterpolatedKind,
+                                                  value: string] =
+  var i = 0
+  var kind: InterpolatedKind
+  while true:
+    var j = i
+    if j < s.len and s[j] == '$':
+      if j+1 < s.len and s[j+1] == '{':
+        inc j, 2
+        var nesting = 0
+        block curlies:
+          while j < s.len:
+            case s[j]
+            of '{': inc nesting
+            of '}':
+              if nesting == 0:
+                inc j
+                break curlies
+              dec nesting
+            else: discard
+            inc j
+          raise newException(ValueError,
+            "Expected closing '}': " & substr(s, i, s.high))
+        inc i, 2 # skip ${
+        kind = ikExpr
+      elif j+1 < s.len and s[j+1] in {'A'..'Z', 'a'..'z', '_'}:
+        inc j, 2
+        while j < s.len and s[j] in {'A'..'Z', 'a'..'z', '0'..'9', '_'}: inc(j)
+        inc i # skip $
+        kind = ikVar
+      elif j+1 < s.len and s[j+1] == '$':
+        inc j, 2
+        inc i # skip $
+        kind = ikDollar
+      else:
+        raise newException(ValueError,
+          "Unable to parse a varible name at " & substr(s, i, s.high))
+    else:
+      while j < s.len and s[j] != '$': inc j
+      kind = ikStr
+    if j > i:
+      # do not copy the trailing } for ikExpr:
+      yield (kind, substr(s, i, j-1-ord(kind == ikExpr)))
+    else:
+      break
+    i = j
+
+let input = "$test{}  $this is ${an{  example}}  "
+let expected = @[(ikVar, "test"), (ikStr, "{}  "), (ikVar, "this"),
+                (ikStr, " is "), (ikExpr, "an{  example}"), (ikStr, "  ")]
+var i = 0
+for s in interpolatedFragments(input):
+  doAssert s == expected[i]
+  inc i
+
+
 #echo s
 let (a, d) = allocCounters()
 cprintf("%ld %ld\n", a, d)