summary refs log tree commit diff stats
path: root/tests/pragmas
diff options
context:
space:
mode:
authorhlaaftana <10591326+hlaaftana@users.noreply.github.com>2021-11-22 12:41:35 +0300
committerGitHub <noreply@github.com>2021-11-22 10:41:35 +0100
commit1b143f5e79c940ba7f70e0512f36b5c61a6bc24d (patch)
tree2cf04bcca507673256480db062e7dcd404ef3908 /tests/pragmas
parenteb5358dcdb1b650db658def14cc8c60b4bb7c203 (diff)
downloadNim-1b143f5e79c940ba7f70e0512f36b5c61a6bc24d.tar.gz
Accept nnkTypeSection from typedef macro pragmas (#19168)
Diffstat (limited to 'tests/pragmas')
-rw-r--r--tests/pragmas/ttypedef_macro.nim66
1 files changed, 66 insertions, 0 deletions
diff --git a/tests/pragmas/ttypedef_macro.nim b/tests/pragmas/ttypedef_macro.nim
new file mode 100644
index 000000000..dd4c87757
--- /dev/null
+++ b/tests/pragmas/ttypedef_macro.nim
@@ -0,0 +1,66 @@
+import macros
+
+macro makeref(s): untyped =
+  expectKind s, nnkTypeDef
+  result = newTree(nnkTypeDef, s[0], s[1], newTree(nnkRefTy, s[2]))
+
+type
+  Obj {.makeref.} = object
+    a: int
+
+doAssert Obj is ref
+doAssert Obj(a: 3)[].a == 3
+
+macro multiply(amount: static int, s): untyped =
+  let name = $s[0].basename
+  result = newNimNode(nnkTypeSection)
+  for i in 1 .. amount:
+    result.add(newTree(nnkTypeDef, ident(name & $i), s[1], s[2]))
+
+type
+  Foo = object
+  Bar {.multiply: 2.} = object
+    x, y, z: int
+  Baz = object
+
+let bar1 = Bar1(x: 1, y: 2, z: 3)
+let bar2 = Bar2(x: bar1.x, y: bar1.y, z: bar1.z)
+doAssert Bar1 isnot Bar2
+doAssert not declared(Bar)
+doAssert not declared(Bar3)
+
+# https://github.com/nim-lang/RFCs/issues/219
+
+macro inferKind(td): untyped =
+  let name = $td[0].basename
+  var rhs = td[2]
+  while rhs.kind in {nnkPtrTy, nnkRefTy}: rhs = rhs[0]
+  if rhs.kind != nnkObjectTy:
+    result = td
+  else:
+    for n in rhs[^1]:
+      if n.kind == nnkRecCase and n[0][^2].eqIdent"_":
+        let kindTypeName = ident(name & "Kind")
+        let en = newTree(nnkEnumTy, newEmptyNode())
+        for i in 1 ..< n.len:
+          let branch = n[i]
+          if branch.kind == nnkOfBranch:
+            for j in 0 ..< branch.len - 1:
+              en.add(branch[j])
+        n[0][^2] = kindTypeName
+        return newTree(nnkTypeSection,
+          newTree(nnkTypeDef, kindTypeName, newEmptyNode(), en),
+          td)
+
+type Node {.inferKind.} = ref object
+  case kind: _
+  of opValue: value: int
+  of opAdd, opSub, opMul, opCall: kids: seq[Node]
+
+doAssert opValue is NodeKind
+let node = Node(kind: opMul, kids: @[
+  Node(kind: opValue, value: 3),
+  Node(kind: opValue, value: 5)
+])
+doAssert node.kind == opMul
+doAssert node.kids[0].value * node.kids[1].value == 15