summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/pragmas/tpragmas_misc.nim24
-rw-r--r--tests/pragmas/tvar_macro.nim128
-rw-r--r--tests/stdlib/tdecls.nim66
3 files changed, 155 insertions, 63 deletions
diff --git a/tests/pragmas/tpragmas_misc.nim b/tests/pragmas/tpragmas_misc.nim
index 8cab74053..6dc2e6b80 100644
--- a/tests/pragmas/tpragmas_misc.nim
+++ b/tests/pragmas/tpragmas_misc.nim
@@ -13,8 +13,8 @@ block:
 
 block: # (partial fix) bug #15920
   block: # var template pragmas don't work in templates
-    template foo(lhs, typ, expr) =
-      let lhs = expr
+    template foo(expr) =
+      expr
     proc fun1()=
       let a {.foo.} = 1
     template fun2()=
@@ -24,23 +24,22 @@ block: # (partial fix) bug #15920
 
   template foo2() = discard # distractor (template or other symbol kind)
   block:
-    template foo2(lhs, typ, expr) =
-      let lhs = expr
+    template foo2(expr) =
+      expr
     proc fun1()=
       let a {.foo2.} = 1
     template fun2()=
       let a {.foo2.} = 1
     fun1() # ok
-    when false: # bug: Error: invalid pragma: foo2
-      fun2()
+    fun2() # bug: Error: invalid pragma: foo2
 
-  block: # proc template pragmas don't work in templates
+  block: # template pragmas don't work for templates, #18212
     # adapted from $nim/lib/std/private/since.nim
     # case without overload
     template since3(version: (int, int), body: untyped) {.dirty.} =
       when (NimMajor, NimMinor) >= version:
         body
-    when false: # bug
+    when true: # bug
       template fun3(): int {.since3: (1, 3).} = 12
 
   block: # ditto, w
@@ -51,7 +50,7 @@ block: # (partial fix) bug #15920
     template since2(version: (int, int, int), body: untyped) {.dirty.} =
       when (NimMajor, NimMinor, NimPatch) >= version:
         body
-    when false: # bug
+    when true: # bug
       template fun3(): int {.since2: (1, 3).} = 12
 
 when true: # D20210801T100514:here
@@ -62,3 +61,10 @@ when true: # D20210801T100514:here
       discard ret
     fn()
     static: discard genSym()
+
+block: # issue #10994
+  macro foo(x): untyped = x
+  template bar {.pragma.}
+
+  proc a {.bar.} = discard # works
+  proc b {.bar, foo.} = discard # doesn't
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
diff --git a/tests/stdlib/tdecls.nim b/tests/stdlib/tdecls.nim
index c0d6f8a08..4e7407045 100644
--- a/tests/stdlib/tdecls.nim
+++ b/tests/stdlib/tdecls.nim
@@ -13,15 +13,18 @@ template fun() =
   var b {.byaddr.}: int = s[0]
   doAssert a.addr == b.addr
 
-  doAssert not compiles(block:
-    # redeclaration not allowed
-    var foo = 0
-    var foo {.byaddr.} = s[0])
-
-  doAssert not compiles(block:
-    # ditto
-    var foo {.byaddr.} = s[0]
-    var foo {.byaddr.} = s[0])
+  when false:
+    # template specific redeclaration issue
+    # see https://github.com/nim-lang/Nim/issues/8275
+    doAssert not compiles(block:
+      # redeclaration not allowed
+      var foo = 0
+      var foo {.byaddr.} = s[0])
+
+    doAssert not compiles(block:
+      # ditto
+      var foo {.byaddr.} = s[0]
+      var foo {.byaddr.} = s[0])
 
   block:
     var b {.byaddr.} = s[1] # redeclaration ok in sub scope
@@ -44,48 +47,3 @@ fun2()
 static: fun2()
 when false: # pending bug #13887
   static: fun()
-
-## We can define custom pragmas in user code
-template byUnsafeAddr(lhs, typ, expr) =
-  when typ is type(nil):
-    let tmp = addr(expr)
-  else:
-    let tmp: ptr typ = addr(expr)
-  template lhs: untyped = tmp[]
-
-block:
-  let s = @["foo", "bar"]
-  let a {.byUnsafeAddr.} = s[0]
-  doAssert a == "foo"
-  doAssert a[0].addr == s[0][0].addr
-
-block: # nkAccQuoted
-  # shows using a keyword, which requires nkAccQuoted
-  template `cast`(lhs, typ, expr) =
-    when typ is type(nil):
-      let tmp = addr(expr)
-    else:
-      let tmp: ptr typ = addr(expr)
-    template lhs: untyped = tmp[]
-
-  block:
-    let s = @["foo", "bar"]
-    let a {.`byUnsafeAddr`.} = s[0]
-    doAssert a == "foo"
-    doAssert a[0].addr == s[0][0].addr
-
-  block:
-    let s = @["foo", "bar"]
-    let a {.`cast`.} = s[0]
-    doAssert a == "foo"
-    doAssert a[0].addr == s[0][0].addr
-
-block: # bug #15920
-  template foo(lhs, typ, expr) =
-    let lhs = expr
-  proc fun1()=
-    let a {.foo.} = 1
-  template fun2()=
-    let a {.foo.} = 1
-  fun1() # ok
-  fun2() # BUG