diff options
author | Araq <rumpf_a@web.de> | 2020-03-17 11:22:20 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2020-03-17 18:00:11 +0100 |
commit | b737bb4be0956f8dce69ec8b7ccfe624890abaa5 (patch) | |
tree | 059ab5a992c4fb2341473b35c9f55121eed42a17 | |
parent | 35d14095edcb530535a3f2b7e7e759c0f993e2c9 (diff) | |
download | Nim-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.nim | 9 | ||||
-rw-r--r-- | lib/std/private/underscored_calls.nim | 29 | ||||
-rw-r--r-- | lib/std/with.nim | 9 |
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 |