1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
import
macros, algorithm, strutils
proc normalProc(x: int) =
echo x
template templateWithtouParams =
echo 10
proc overloadedProc(x: int) =
echo x
proc overloadedProc(x: string) =
echo x
proc overloadedProc[T](x: T) =
echo x
template normalTemplate(x: int) =
echo x
template overloadedTemplate(x: int) =
echo x
template overloadedTemplate(x: string) =
echo x
macro normalMacro(x: int): untyped =
discard
macro macroWithoutParams: untyped =
discard
macro inspectSymbol(sym: typed, expected: static[string]): untyped =
if sym.kind == nnkSym:
echo "Symbol node:"
let res = sym.getImpl.repr & "\n"
echo res
# echo "|", res, "|"
# echo "|", expected, "|"
if expected.len > 0: assert res == expected
elif sym.kind in {nnkClosedSymChoice, nnkOpenSymChoice}:
echo "Begin sym choice:"
var results = newSeq[string](0)
for innerSym in sym:
results.add innerSym.getImpl.repr
sort(results, cmp[string])
let res = results.join("\n") & "\n"
echo res
if expected.len > 0: assert res == expected
echo "End symchoice."
else:
echo "Non-symbol node: ", sym.kind
if expected.len > 0: assert $sym.kind == expected
macro inspectUntyped(sym: untyped, expected: static[string]): untyped =
let res = sym.repr
echo "Untyped node: ", res
assert res == expected
inspectSymbol templateWithtouParams, "nnkCommand"
# this template is expanded, because bindSym was not used
# the end result is the template body (nnkCommand)
inspectSymbol bindSym("templateWithtouParams"), """
template templateWithtouParams() =
echo 10
"""
inspectSymbol macroWithoutParams, "nnkEmpty"
# Just like the template above, the macro was expanded
inspectSymbol bindSym("macroWithoutParams"), """
macro macroWithoutParams(): untyped =
discard
"""
inspectSymbol normalMacro, """
macro normalMacro(x: int): untyped =
discard
"""
# Since the normalMacro has params, it's automatically
# treated as a symbol here (no need for `bindSym`)
inspectSymbol bindSym("normalMacro"), """
macro normalMacro(x: int): untyped =
discard
"""
inspectSymbol normalTemplate, """
template normalTemplate(x: int) =
echo x
"""
inspectSymbol bindSym("normalTemplate"), """
template normalTemplate(x: int) =
echo x
"""
inspectSymbol overloadedTemplate, """
template overloadedTemplate(x: int) =
echo x
template overloadedTemplate(x: string) =
echo x
"""
inspectSymbol bindSym("overloadedTemplate"), """
template overloadedTemplate(x: int) =
echo x
template overloadedTemplate(x: string) =
echo x
"""
inspectUntyped bindSym("overloadedTemplate"), """bindSym("overloadedTemplate")"""
# binSym is active only in the presence of `typed` params.
# `untyped` params still get the raw AST
inspectSymbol normalProc, """
proc normalProc(x: int) =
echo [x]
"""
inspectSymbol bindSym("normalProc"), """
proc normalProc(x: int) =
echo [x]
"""
inspectSymbol overloadedProc, """
proc overloadedProc(x: int) =
echo [x]
proc overloadedProc(x: string) =
echo [x]
proc overloadedProc[T](x: T) =
echo x
"""
inspectSymbol overloadedProc[float], """
proc overloadedProc(x: T) =
echo [x]
"""
# As expected, when we select a specific generic, the
# AST is no longer a symChoice
inspectSymbol bindSym("overloadedProc"), """
proc overloadedProc(x: int) =
echo [x]
proc overloadedProc(x: string) =
echo [x]
proc overloadedProc[T](x: T) =
echo x
"""
|