enable,document,test getImplTransformed, very useful for understanding how nim transforms code (#14924)

* enable,document,test getImplTransformed, very useful for understanding how nim transforms code
This commit is contained in:
Timothee Cour
2020-07-18 01:49:36 -07:00
committed by GitHub
parent c983466c15
commit 169ca37d26
2 changed files with 25 additions and 2 deletions

View File

@@ -277,9 +277,12 @@ else: # bootstrapping substitute
{.pop.}
when defined(nimSymImplTransform):
when (NimMajor, NimMinor, NimPatch) >= (1, 3, 5) or defined(nimSymImplTransform):
proc getImplTransformed*(symbol: NimNode): NimNode {.magic: "GetImplTransf", noSideEffect.}
## For a typed proc returns the AST after transformation pass.
## For a typed proc returns the AST after transformation pass; this is useful
## for debugging how the compiler transforms code (eg: `defer`, `for`) but
## note that code transformations are implementation dependent and subject to change.
## See an example in `tests/macros/tmacros_various.nim`.
when defined(nimHasSymOwnerInMacro):
proc owner*(sym: NimNode): NimNode {.magic: "SymOwner", noSideEffect.}

View File

@@ -202,3 +202,23 @@ block tupleNewLitTests:
# this `$` test is needed because tuple equality doesn't distinguish
# between named vs unnamed tuples
doAssert t() == (1, "foo", (), (1, ), (a1: 'x', a2: @["ba"]))
from strutils import contains
block getImplTransformed:
macro bar(a: typed): string =
# newLit a.getImpl.repr # this would be before code transformation
let b = a.getImplTransformed
newLit b.repr
template toExpand() =
for ai in 0..2: echo ai
proc baz(a=1): int =
defer: discard
toExpand()
12
const code = bar(baz)
# sanity check:
doAssert "finally" in code # `defer` is lowered to try/finally
doAssert "while" in code # `for` is lowered to `while`
doAssert "toExpand" notin code
# template is expanded (but that would already be the case with
# `a.getImpl.repr`, unlike the other transformations mentioned above