tmacros_various.nim 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. discard """
  2. nimout: '''
  3. Infix
  4. Ident "=>"
  5. Call
  6. Ident "name"
  7. Ident "a"
  8. ExprColonExpr
  9. Ident "b"
  10. Ident "cint"
  11. NilLit
  12. macrocache ok
  13. '''
  14. output: '''
  15. x = 10
  16. x + y = 30
  17. proc foo[T, N: static[int]]()
  18. proc foo[T; N: static[int]]()
  19. a[0]: 42
  20. a[1]: 45
  21. x: some string
  22. ([("key", "val"), ("keyB", "2")], [("val", "key"), ("2", "keyB")])
  23. ([("key", "val"), ("keyB", "2")], [("val", "key"), ("2", "keyB")])
  24. '''
  25. """
  26. import macros, sugar, macrocache
  27. block tdump:
  28. let
  29. x = 10
  30. y = 20
  31. dump x
  32. dump(x + y)
  33. block texprcolonexpr:
  34. macro def(x): untyped =
  35. echo treeRepr(x)
  36. def name(a, b:cint) => nil
  37. block tgenericparams:
  38. macro test():string =
  39. let expr0 = "proc foo[T, N: static[int]]()"
  40. let expr1 = "proc foo[T; N: static[int]]()"
  41. newLit($toStrLit(parseExpr(expr0)) & "\n" & $toStrLit(parseExpr(expr1)))
  42. echo test()
  43. block tidgen:
  44. # Test compile-time state in same module
  45. var gid {.compileTime.} = 3
  46. macro genId(): int =
  47. result = newIntLitNode(gid)
  48. inc gid
  49. proc Id1(): int {.compileTime.} = return genId()
  50. proc Id2(): int {.compileTime.} = return genId()
  51. doAssert Id1() == 3
  52. doAssert Id2() == 4
  53. block tlexerex:
  54. macro match(s: cstring|string; pos: int; sections: varargs[untyped]): untyped =
  55. for sec in sections:
  56. expectKind sec, nnkOfBranch
  57. expectLen sec, 2
  58. result = newStmtList()
  59. var input = "the input"
  60. var pos = 0
  61. match input, pos:
  62. of r"[a-zA-Z_]\w+": echo "an identifier"
  63. of r"\d+": echo "an integer"
  64. of r".": echo "something else"
  65. block tlineinfo:
  66. # issue #5617, feature request
  67. type Test = object
  68. macro mixer(n: typed): untyped =
  69. let x = newIdentNode("echo")
  70. x.copyLineInfo(n)
  71. result = newLit(x.lineInfo == n.lineInfo)
  72. var z = mixer(Test)
  73. doAssert z
  74. block tdebugstmt:
  75. macro debug(n: varargs[untyped]): untyped =
  76. result = newNimNode(nnkStmtList, n)
  77. for i in 0..n.len-1:
  78. add(result, newCall("write", newIdentNode("stdout"), toStrLit(n[i])))
  79. add(result, newCall("write", newIdentNode("stdout"), newStrLitNode(": ")))
  80. add(result, newCall("writeLine", newIdentNode("stdout"), n[i]))
  81. var
  82. a: array[0..10, int]
  83. x = "some string"
  84. a[0] = 42
  85. a[1] = 45
  86. debug(a[0], a[1], x)
  87. const
  88. pairs = {"key": "val", "keyB": "2"}
  89. macro bilookups(arg: static[openArray[(string, string)]]): untyped =
  90. var a = newTree(nnkBracket)
  91. var b = newTree(nnkBracket)
  92. for (k, v) in items(arg):
  93. a.add(newTree(nnkTupleConstr, newLit k, newLit v))
  94. b.add(newTree(nnkTupleConstr, newLit v, newLit k))
  95. result = newTree(nnkTupleConstr, a, b)
  96. macro bilookups2(arg: untyped): untyped =
  97. var a = newTree(nnkBracket)
  98. var b = newTree(nnkBracket)
  99. arg.expectKind(nnkTableConstr)
  100. for x in items(arg):
  101. x.expectKind(nnkExprColonExpr)
  102. a.add(newTree(nnkTupleConstr, x[0], x[1]))
  103. b.add(newTree(nnkTupleConstr, x[1], x[0]))
  104. result = newTree(nnkTupleConstr, a, b)
  105. const cnst1 = bilookups(pairs)
  106. echo cnst1
  107. const cnst2 = bilookups2({"key": "val", "keyB": "2"})
  108. echo cnst2
  109. # macrocache #11404
  110. const
  111. mcTable = CacheTable"nimTest"
  112. mcSeq = CacheSeq"nimTest"
  113. mcCounter = CacheCounter"nimTest"
  114. static:
  115. doAssert(mcCounter.value == 0) # CacheCounter.value
  116. mcCounter.inc # CacheCounter.inc
  117. doAssert(mcCounter.value == 1) # CacheCounter.value
  118. let a = newLit(1)
  119. let b = newLit(2)
  120. let c = newLit(3)
  121. let d = newLit(4)
  122. mcSeq.add a # CacheSeq.add
  123. mcSeq.add b # CacheSeq.add
  124. mcSeq.add c # CacheSeq.add
  125. doAssert(mcSeq.len == 3) # CacheSeq.len
  126. #doAssert(c in mcSeq) # CacheSeq.contains
  127. #doAssert(d notin mcSeq) # CacheSeq.contains
  128. mcSeq.incl d # CacheSeq.incl
  129. doAssert(mcSeq.len == 4) # CacheSeq.len
  130. mcSeq.incl c # CacheSeq.incl
  131. doAssert(mcSeq.len == 4) # CacheSeq.len
  132. doAssert(mcSeq[3] == d) # CacheSeq.[]
  133. #doAssert(mcSeq.pop() == d)# CacheSeq.pop
  134. #doAssert(mcSeq.len == 3) # CacheSeq.len
  135. doAssert(mcTable.len == 0) # CacheTable.len
  136. mcTable["a"] = a # CacheTable.[]=
  137. doAssert(mcTable.len == 1) # CacheTable.len
  138. doAssert(mcTable["a"] == a) # CacheTable.[]
  139. #doAssert("a" in mcTable) # CacheTable.contains
  140. #doAssert(mcTable.hasKey("a"))# CacheTable.hasKey
  141. for k, v in mcTable: # CacheTable.items
  142. doAssert(k == "a")
  143. doAssert(v == a)
  144. echo "macrocache ok"
  145. block tupleNewLitTests:
  146. macro t(): untyped =
  147. result = newLit (1, "foo", (), (1,), (a1: 'x', a2: @["ba"]))
  148. doAssert $t() == """(1, "foo", (), (1,), (a1: 'x', a2: @["ba"]))"""
  149. # this `$` test is needed because tuple equality doesn't distinguish
  150. # between named vs unnamed tuples
  151. doAssert t() == (1, "foo", (), (1, ), (a1: 'x', a2: @["ba"]))