diff options
Diffstat (limited to 'tests/pragmas/tvar_macro.nim')
-rw-r--r-- | tests/pragmas/tvar_macro.nim | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/tests/pragmas/tvar_macro.nim b/tests/pragmas/tvar_macro.nim new file mode 100644 index 000000000..d6a4ff983 --- /dev/null +++ b/tests/pragmas/tvar_macro.nim @@ -0,0 +1,128 @@ +import macros + +block: # test usage + macro modify(sec) = + result = copy sec + result[0][0] = ident(repr(result[0][0]) & "Modified") + + block: + let foo {.modify.} = 3 + doAssert fooModified == 3 + + block: # in section + let + a = 1 + b {.modify.} = 2 + c = 3 + doAssert (a, bModified, c) == (1, 2, 3) + +block: # with single argument + macro appendToName(name: static string, sec) = + result = sec + result[0][0] = ident(repr(result[0][0]) & name) + + block: + let foo {.appendToName: "Bar".} = 3 + doAssert fooBar == 3 + + block: + let + a = 1 + b {.appendToName("").} = 2 + c = 3 + doAssert (a, b, c) == (1, 2, 3) + +macro appendToNameAndAdd(name: static string, incr: static int, sec) = + result = sec + result[0][0] = ident(repr(result[0][0]) & name) + result[0][2] = infix(result[0][2], "+", newLit(incr)) + +block: # with multiple arguments + block: + let foo {.appendToNameAndAdd("Bar", 5).} = 3 + doAssert fooBar == 8 + + block: + let + a = 1 + b {.appendToNameAndAdd("", 15).} = 2 + c = 3 + doAssert (a, b, c) == (1, 17, 3) + +block: # in other kinds of sections + block: + const + a = 1 + b {.appendToNameAndAdd("", 15).} = 2 + c = 3 + doAssert (a, b, c) == (1, 17, 3) + doAssert static(b) == b + + block: + var + a = 1 + b {.appendToNameAndAdd("", 15).} = 2 + c = 3 + doAssert (a, b, c) == (1, 17, 3) + b += a + c += b + doAssert (a, b, c) == (1, 18, 21) + +block: # with other pragmas + macro appendToNameAndAdd(name: static string, incr, sec) = + result = sec + result[0][0][0] = ident(repr(result[0][0][0]) & name) + result[0][0][1].add(ident"deprecated") + result[0][2] = infix(result[0][2], "+", incr) + + var + a = 1 + foo {.exportc: "exportedFooBar", appendToNameAndAdd("Bar", {'0'..'9'}), used.} = {'a'..'z', 'A'..'Z'} + b = 2 + + doAssert (a, b) == (1, 2) + + let importedFooBar {.importc: "exportedFooBar", nodecl.}: set[char] + + doAssert importedFooBar == fooBar #[tt.Warning + ^ fooBar is deprecated + ]# + + +block: # with stropping + macro `cast`(def) = + let def = def[0] + let + lhs = def[0] + typ = def[1] + ex = def[2] + addrTyp = if typ.kind == nnkEmpty: typ else: newTree(nnkPtrTy, typ) + result = quote do: + let tmp: `addrTyp` = unsafeAddr(`ex`) + template `lhs`: untyped = tmp[] + + macro assign(def) = + result = getAst(`cast`(def)) + + block: + let s = @["foo", "bar"] + let a {.`assign`.} = s[0] + doAssert a == "foo" + doAssert a[0].addr == s[0][0].addr + + block: + let + s = @["foo", "bar"] + a {.`cast`.} = s[0] + doAssert a == "foo" + doAssert a[0].addr == s[0][0].addr + +block: # bug #15920 + macro foo(def) = + result = def + proc fun1()= + let a {.foo.} = 1 + template fun2()= + let a {.foo.} = 1 + fun1() # ok + fun2() # BUG |