Nested with blocks (#22042)

* Implemented with-nesting in underscoredCalls()

* Add tests for nested with
This commit is contained in:
awr1
2023-06-07 23:02:57 -07:00
committed by GitHub
parent 7ee00d86b1
commit 6514eaa8e0
3 changed files with 40 additions and 6 deletions

View File

@@ -12,6 +12,8 @@
import macros
proc underscoredCalls*(result, calls, arg0: NimNode)
proc underscoredCall(n, arg0: NimNode): NimNode =
proc underscorePos(n: NimNode): int =
for i in 1 ..< n.len:
@@ -19,13 +21,19 @@ proc underscoredCall(n, arg0: NimNode): NimNode =
return 0
if n.kind in nnkCallKinds:
result = copyNimNode(n)
result.add n[0]
if n[0].kind in {nnkIdent, nnkSym} and n[0].eqIdent("with"):
expectKind n[1], {nnkIdent, nnkSym}
let u = underscorePos(n)
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]
result = newStmtList()
underscoredCalls(result, n[2 .. ^1].newStmtList, newDotExpr(arg0, n[1]))
else:
result = copyNimNode(n)
result.add n[0]
let u = underscorePos(n)
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]
elif n.kind in {nnkAsgn, nnkExprEqExpr}:
var field = n[0]
if n[0].kind == nnkDotExpr and n[0][0].eqIdent("_"):

View File

@@ -35,5 +35,15 @@ macro with*(arg: typed; calls: varargs[untyped]): untyped =
-= 5
doAssert a == 43
# Nesting works for object types too!
var foo = (bar: 1, qux: (baz: 2))
with foo:
bar = 2
with qux:
baz = 3
doAssert foo.bar == 2
doAssert foo.qux.baz == 3
result = newNimNode(nnkStmtList, arg)
underscoredCalls(result, calls, arg)
echo result.astGenRepr

View File

@@ -26,3 +26,19 @@ with f:
doAssert f.col == "(2, 3, 4)"
doAssert f.pos == "(0.0, 1.0)"
doAssert f.name == "bar"
type
Baz* = object
a*, b*: int
Bar* = object
x*: int
baz*: Baz
var bar: Bar
with bar:
x = 1
with baz:
a = 2
doAssert bar.x == 1
doAssert bar.baz.a == 2