Skip to content

Commit c2977d9

Browse files
committed
add examples showing mixin; add examples showing passing types, macros, templates
1 parent d9fdf7b commit c2977d9

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

lib/core/macros.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,9 +1411,9 @@ macro genAstOpt*(options: static set[GenAstOpt], args: varargs[untyped]): untype
14111411
newEmptyNode()
14121412

14131413
template newLitMaybe(a): untyped =
1414-
when type(a) is NimNode: a
1415-
elif compiles(newLit(a)): newLit(a)
1416-
else: a
1414+
when (a is type) or (typeof(a) is (proc | iterator | func | NimNode)):
1415+
a # `proc` actually also covers template, macro
1416+
else: newLit(a)
14171417

14181418
# using `_` as workaround, see https://github.com/nim-lang/Nim/issues/2465#issuecomment-511076669
14191419
let name = genSym(nskTemplate, "_fun")

tests/macros/mgenast.nim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,12 @@ macro bindme6UseExposeFalse*(): untyped =
4141
var ss = newStringStream("anothertext")
4242
writeData(ss, tst[0].addr, 2)
4343
discard readData(ss, tst[0].addr, 2)
44+
45+
46+
proc locafun1(): auto = "in locafun1"
47+
proc locafun2(): auto = "in locafun2"
48+
# locafun3 in caller scope only
49+
macro mixinExample*(): untyped =
50+
genAst:
51+
mixin locafun1
52+
(locafun1(), locafun2(), locafun3())

tests/macros/tgenast.nim

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,25 @@ block: # also from #11986
235235
let t = s
236236
$typeof(t)
237237
doAssert foo() == "set[char]"
238+
239+
block:
240+
macro foo(): untyped =
241+
type Foo = object
242+
template baz2(a: int): untyped = a*10
243+
macro baz3(a: int): untyped = newLit 13
244+
result = newStmtList()
245+
246+
result.add genAst(Foo, baz2, baz3) do: # shows you can pass types, templates etc
247+
var x: Foo
248+
$($typeof(x), baz2(3), baz3(4))
249+
250+
let ret = genAst() do: # shows you don't have to, since they're inject'd
251+
var x: Foo
252+
$($typeof(x), baz2(3), baz3(4))
253+
doAssert foo() == """("Foo", 30, 13)"""
254+
255+
block: # illustrates how symbol visiblity can be controlled precisely using `mixin`
256+
proc locafun1(): auto = "in locafun1 (caller scope)" # this will be used because of `mixin locafun1` => explicit hijacking is ok
257+
proc locafun2(): auto = "in locafun2 (caller scope)" # this won't be used => no hijacking
258+
proc locafun3(): auto = "in locafun3 (caller scope)"
259+
doAssert mixinExample() == ("in locafun1 (caller scope)", "in locafun2", "in locafun3 (caller scope)")

0 commit comments

Comments
 (0)