Skip to content

Commit

Permalink
add examples showing mixin; add examples showing passing types, macro…
Browse files Browse the repository at this point in the history
…s, templates
  • Loading branch information
timotheecour committed Aug 25, 2019
1 parent 23e6b9d commit 5dc9f40
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
6 changes: 3 additions & 3 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1380,9 +1380,9 @@ macro genAstOpt*(options: static set[GenAstOpt], args: varargs[untyped]): untype
newEmptyNode()

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

# using `_` as workaround, see https://github.com/nim-lang/Nim/issues/2465#issuecomment-511076669
let name = genSym(nskTemplate, "_fun")
Expand Down
9 changes: 9 additions & 0 deletions tests/macros/mgenast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,12 @@ macro bindme6UseExposeFalse*(): untyped =
var ss = newStringStream("anothertext")
writeData(ss, tst[0].addr, 2)
discard readData(ss, tst[0].addr, 2)


proc locafun1(): auto = "in locafun1"
proc locafun2(): auto = "in locafun2"
# locafun3 in caller scope only
macro mixinExample*(): untyped =
genAst:
mixin locafun1
(locafun1(), locafun2(), locafun3())
22 changes: 22 additions & 0 deletions tests/macros/tgenast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,25 @@ block: # also from #11986
let t = s
$typeof(t)
doAssert foo() == "set[char]"

block:
macro foo(): untyped =
type Foo = object
template baz2(a: int): untyped = a*10
macro baz3(a: int): untyped = newLit 13
result = newStmtList()

result.add genAst(Foo, baz2, baz3) do: # shows you can pass types, templates etc
var x: Foo
$($typeof(x), baz2(3), baz3(4))

let ret = genAst() do: # shows you don't have to, since they're inject'd
var x: Foo
$($typeof(x), baz2(3), baz3(4))
doAssert foo() == """("Foo", 30, 13)"""

block: # illustrates how symbol visiblity can be controlled precisely using `mixin`
proc locafun1(): auto = "in locafun1 (caller scope)" # this will be used because of `mixin locafun1` => explicit hijacking is ok
proc locafun2(): auto = "in locafun2 (caller scope)" # this won't be used => no hijacking
proc locafun3(): auto = "in locafun3 (caller scope)"
doAssert mixinExample() == ("in locafun1 (caller scope)", "in locafun2", "in locafun3 (caller scope)")

0 comments on commit 5dc9f40

Please sign in to comment.