Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Jul 12, 2019
1 parent 65d96eb commit 8fa8b42
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/core/macros.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,7 @@ macro genAst*(args: varargs[untyped]): untyped =
let s1 = "not captured!" ## does not override `s1=2`
let xignoredLocal = kfoo4
let x3 = newLit kfoo4
## use `result = genAst do` if there are 0 captures
result = genAst(s1=2, s2="asdf", x0=newLit x0, x1=x1, x2, x3) do:
## only captures variables from `genAst` argument list
## uncaptured variables will be set from caller scope (Eg `s0`)
Expand Down
9 changes: 9 additions & 0 deletions tests/macros/mgenast.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from std/streams import newStringStream, readData, writeData
import std/macros

macro bindme*(): untyped =
genAst(newStringStream, writeData, readData) do:
var tst = "sometext"
var ss = newStringStream("anothertext")
writeData(ss, tst[0].addr, 2)
discard readData(ss, tst[0].addr, 2)
89 changes: 89 additions & 0 deletions tests/macros/tgenast.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import std/macros

block:
type Foo = enum kfoo0, kfoo1, kfoo2, kfoo3, kfoo4

macro bar(x0: static Foo, x1: Foo, x2: Foo, xignored: Foo): untyped =
let s0 = "not captured!"
let s1 = "not captured!"
let xignoredLocal = kfoo4
let x3 = newLit kfoo4
result = genAst(s1=2, s2="asdf", x0=newLit x0, x1=x1, x2, x3) do:
doAssert not declared(xignored)
doAssert not declared(xignoredLocal)
(s1, s2, s0, x0, x1, x2, x3)

let s0 = "caller scope!"

doAssert bar(kfoo1, kfoo2, kfoo3, kfoo4) ==
(2, "asdf", "caller scope!", kfoo1, kfoo2, kfoo3, kfoo4)

block:
# doesn't have limitation mentioned in https://github.com/nim-lang/RFCs/issues/122#issue-401636535
macro abc(name: untyped): untyped =
result = genAst(name):
type name = object

abc(Bar)
doAssert Bar.default == Bar()

import std/strformat

block:
# fix https://github.com/nim-lang/Nim/issues/8220
macro foo(): untyped =
result = genAst do:
let bar = "Hello, World"
&"Let's interpolate {bar} in the string"
doAssert foo() == "Let's interpolate Hello, World in the string"

block:
# backticks parser limitations / ambiguities not an issue with `genAst`:
# fix https://github.com/nim-lang/Nim/issues/10326
# fix https://github.com/nim-lang/Nim/issues/9745
type Foo = object
a: int

macro m1(): untyped =
# result = quote do: # Error: undeclared identifier: 'a1'
result = genAst do:
template `a1=`(x: var Foo, val: int) =
x.a = val

m1()
var x0: Foo
x0.a1 = 10
doAssert x0 == Foo(a: 10)

block:
# fix https://github.com/nim-lang/Nim/issues/7375
macro fun(b: static[bool], b2: bool): untyped =
result = newStmtList()
macro foo(c: bool): untyped =
var b = false
result = genAst(b = newLit b, c) do:
fun(b, c)

foo(true)

when true:
# fix https://github.com/nim-lang/Nim/issues/7889
from mgenast import bindme
bindme()

block:
# fix https://github.com/nim-lang/Nim/issues/7589
# since `==` works with genAst, the problem goes away
macro foo2(): untyped =
# result = quote do: # Error: '==' cannot be passed to a procvar
result = genAst do:
`==`(3,4)
doAssert not foo2()

block:
# fix https://github.com/nim-lang/Nim/issues/7726
macro foo(): untyped =
let a = @[1, 2, 3, 4, 5]
result = genAst(a, b = a.len) do: # shows 2 ways to get a.len
(a.len, b)
doAssert foo() == (5, 5)

0 comments on commit 8fa8b42

Please sign in to comment.