From 8fa8b42d8ddec0111ce48a324f21d76b6bad4356 Mon Sep 17 00:00:00 2001 From: Timothee Cour Date: Fri, 12 Jul 2019 15:38:48 -0700 Subject: [PATCH] add tests --- lib/core/macros.nim | 1 + tests/macros/mgenast.nim | 9 ++++ tests/macros/tgenast.nim | 89 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 tests/macros/mgenast.nim create mode 100644 tests/macros/tgenast.nim diff --git a/lib/core/macros.nim b/lib/core/macros.nim index b0919f50b4ad8..634489edcc5af 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -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`) diff --git a/tests/macros/mgenast.nim b/tests/macros/mgenast.nim new file mode 100644 index 0000000000000..3aadbdbc18d53 --- /dev/null +++ b/tests/macros/mgenast.nim @@ -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) diff --git a/tests/macros/tgenast.nim b/tests/macros/tgenast.nim new file mode 100644 index 0000000000000..a593ba0b84f03 --- /dev/null +++ b/tests/macros/tgenast.nim @@ -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)