summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2020-03-17 11:22:20 +0100
committerAraq <rumpf_a@web.de>2020-03-17 18:00:11 +0100
commitb737bb4be0956f8dce69ec8b7ccfe624890abaa5 (patch)
tree059ab5a992c4fb2341473b35c9f55121eed42a17
parent35d14095edcb530535a3f2b7e7e759c0f993e2c9 (diff)
downloadNim-b737bb4be0956f8dce69ec8b7ccfe624890abaa5.tar.gz
fixes a bug for 'dup' and 'with'; they can now handle nested statement lists that can result from macros
-rw-r--r--lib/pure/sugar.nim9
-rw-r--r--lib/std/private/underscored_calls.nim29
-rw-r--r--lib/std/with.nim9
3 files changed, 22 insertions, 25 deletions
diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim
index 047280049..e9e7eb455 100644
--- a/lib/pure/sugar.nim
+++ b/lib/pure/sugar.nim
@@ -216,14 +216,7 @@ when (NimMajor, NimMinor) >= (1, 1):
     result = newNimNode(nnkStmtListExpr, arg)
     let tmp = genSym(nskVar, "dupResult")
     result.add newVarStmt(tmp, arg)
-    expectKind calls, nnkArgList
-    let body =
-      if calls.len == 1 and calls[0].kind in {nnkStmtList, nnkStmtListExpr}:
-        calls[0]
-      else:
-        calls
-    for call in body:
-      result.add underscoredCall(call, tmp)
+    underscoredCalls(result, calls, tmp)
     result.add tmp
 
 
diff --git a/lib/std/private/underscored_calls.nim b/lib/std/private/underscored_calls.nim
index 7db25c410..c7aeb6ae2 100644
--- a/lib/std/private/underscored_calls.nim
+++ b/lib/std/private/underscored_calls.nim
@@ -12,27 +12,38 @@
 
 import macros
 
-proc underscoredCall*(n, arg0: NimNode): NimNode =
+proc underscoredCall(n, arg0: NimNode): NimNode =
   proc underscorePos(n: NimNode): int =
     for i in 1 ..< n.len:
       if n[i].eqIdent("_"): return i
-    return -1
+    return 0
 
   if n.kind in nnkCallKinds:
     result = copyNimNode(n)
     result.add n[0]
 
     let u = underscorePos(n)
-    if u < 0:
-      result.add arg0
-      for i in 1..n.len-1: result.add n[i]
-    else:
-      for i in 1..u-1: result.add n[i]
-      result.add arg0
-      for i in u+1..n.len-1: result.add n[i]
+    for i in 1..u-1: result.add n[i]
+    result.add arg0
+    for i in u+1..n.len-1: result.add n[i]
   else:
     # handle e.g. 'x.dup(sort)'
     result = newNimNode(nnkCall, n)
     result.add n
     result.add arg0
 
+proc underscoredCalls*(result, calls, arg0: NimNode) =
+  proc handleStmtList(result, n, arg0: NimNode) =
+    for a in n:
+      if a.kind in {nnkStmtList, nnkStmtListExpr}:
+        handleStmtList(result, a, arg0)
+      else:
+        result.add underscoredCall(a, arg0)
+
+  expectKind calls, nnkArgList
+  if calls.len == 1 and calls[0].kind in {nnkStmtList, nnkStmtListExpr}:
+    # the 'macro: body' syntax is used:
+    handleStmtList(result, calls[0], arg0)
+  else:
+    for call in calls:
+      result.add underscoredCall(call, arg0)
diff --git a/lib/std/with.nim b/lib/std/with.nim
index 1dfb67c2e..c1ac96fcb 100644
--- a/lib/std/with.nim
+++ b/lib/std/with.nim
@@ -35,14 +35,7 @@ macro with*(arg: typed; calls: varargs[untyped]): untyped =
     doAssert a == 43
 
   result = newNimNode(nnkStmtList, arg)
-  expectKind calls, nnkArgList
-  let body =
-    if calls.len == 1 and calls[0].kind in {nnkStmtList, nnkStmtListExpr}:
-      calls[0]
-    else:
-      calls
-  for call in body:
-    result.add underscoredCall(call, arg)
+  underscoredCalls(result, calls, arg)
 
 when isMainModule:
   type