tmacrotypes.nim 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. discard """
  2. nimout: '''intProc; ntyProc; proc[int, int, float]; proc (a: int; b: float): int {.nimcall.}
  3. void; ntyVoid; void; void
  4. int; ntyInt; int; int
  5. proc () {.nimcall.}; ntyProc; proc[void]; proc () {.nimcall.}
  6. voidProc; ntyProc; proc[void]; proc () {.nimcall.}
  7. listing fields for ObjType
  8. a: string
  9. b: int
  10. listing fields for ObjRef
  11. skipping ref type
  12. a: string
  13. b: int
  14. listing fields for RefType
  15. skipping ref type
  16. a: int
  17. b: float
  18. listing fields for typeof(a)
  19. skipping ref type
  20. a: string
  21. b: int
  22. listing fields for typeof(b)
  23. skipping ref type
  24. a: string
  25. b: int
  26. listing fields for typeof(c)
  27. skipping ref type
  28. a: int
  29. b: float
  30. listing fields for typeof(x)
  31. a: string
  32. b: int
  33. listing fields for typeof(x)
  34. a: int
  35. b: float
  36. typeDesc[range[1 .. 5]]; ntyTypeDesc; typeDesc[range[1, 5]]; typeDesc[range[1 .. 5]]
  37. typeDesc[range]; ntyTypeDesc; typeDesc[range[T]]; typeDesc[range]'''
  38. """
  39. import macros, typetraits
  40. macro checkType(ex: typed): untyped =
  41. echo ex.getTypeInst.repr, "; ", ex.typeKind, "; ", ex.getType.repr, "; ", ex.getTypeImpl.repr
  42. macro checkProcType(fn: typed): untyped =
  43. if fn.kind == nnkProcDef:
  44. result = fn
  45. let fn_sym = if fn.kind == nnkProcDef: fn[0] else: fn
  46. echo fn_sym, "; ", fn_sym.typeKind, "; ", fn_sym.getType.repr, "; ", fn_sym.getTypeImpl.repr
  47. proc voidProc = echo "hello"
  48. proc intProc(a: int, b: float): int {.checkProcType.} = 10
  49. checkType(voidProc())
  50. checkType(intProc(10, 20.0))
  51. checkType(voidProc)
  52. checkProcType(voidProc)
  53. macro listFields(T: typed) =
  54. echo "listing fields for ", repr(T)
  55. let inputExprType = getType(T)
  56. var objType = inputExprType[1]
  57. if objType.kind == nnkBracketExpr and objType.len > 1:
  58. if ((objType[0].kind == nnkRefTy) or
  59. (objType[0].kind == nnkSym and eqIdent(objType[0], "ref"))):
  60. echo "skipping ref type"
  61. objType = objType[1]
  62. let typeAst = objType.getImpl
  63. var objectDef = typeAst[2]
  64. if objectDef.kind == nnkRefTy:
  65. objectDef = objectDef[0]
  66. let recList = objectDef[2]
  67. for rec in recList:
  68. echo $rec[0], ": ", $rec[1]
  69. type
  70. ObjType* = object of RootObj
  71. a: string
  72. b: int
  73. ObjRef = ref ObjType
  74. RefType* = ref object of RootObj
  75. a: int
  76. b: float
  77. listFields ObjType
  78. listFields ObjRef
  79. listFields RefType
  80. let
  81. a = new ObjType
  82. b = new ObjRef
  83. c = new RefType
  84. listFields typeOf(a)
  85. listFields typeOf(b)
  86. listFields typeOf(c)
  87. proc genericProc(x: object) =
  88. listFields typeOf(x)
  89. genericProc a[]
  90. genericProc b[]
  91. genericProc c[]
  92. # bug #10548
  93. block:
  94. var c {.compileTime.} = 0
  95. macro meshImpl(arg: typed): untyped =
  96. inc c
  97. result = arg
  98. type
  99. Blub = int32
  100. Mesh = meshImpl(Club)
  101. Club = Blub
  102. static: doAssert(c == 1)
  103. # bug #10702
  104. type
  105. VectorElementType = SomeNumber | bool
  106. Vec*[N : static[int], T: VectorElementType] = object
  107. arr*: array[N, T]
  108. type
  109. Vec4*[T: VectorElementType] = Vec[4,T]
  110. Vec3*[T: VectorElementType] = Vec[3,T]
  111. Vec2*[T: VectorElementType] = Vec[2,T]
  112. template vecGen(U:untyped,V:typed):typed=
  113. ## ``U`` suffix
  114. ## ``V`` valType
  115. ##
  116. type
  117. `Vec2 U`* {.inject.} = Vec2[V]
  118. `Vec3 U`* {.inject.} = Vec3[V]
  119. `Vec4 U`* {.inject.} = Vec4[V]
  120. vecGen(f, float32)
  121. macro foobar(arg: typed): untyped =
  122. let typ = arg.getTypeInst
  123. doAssert typ.getImpl[^1].kind == nnkCall
  124. var x: Vec2f
  125. foobar(x)
  126. checkType(range[1..5])
  127. checkType(range)