diff options
author | hlaaftana <10591326+hlaaftana@users.noreply.github.com> | 2021-11-22 12:41:35 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-22 10:41:35 +0100 |
commit | 1b143f5e79c940ba7f70e0512f36b5c61a6bc24d (patch) | |
tree | 2cf04bcca507673256480db062e7dcd404ef3908 /tests/pragmas | |
parent | eb5358dcdb1b650db658def14cc8c60b4bb7c203 (diff) | |
download | Nim-1b143f5e79c940ba7f70e0512f36b5c61a6bc24d.tar.gz |
Accept nnkTypeSection from typedef macro pragmas (#19168)
Diffstat (limited to 'tests/pragmas')
-rw-r--r-- | tests/pragmas/ttypedef_macro.nim | 66 |
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 |