template_various.nim 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. discard """
  2. output: '''
  3. i2416
  4. 33
  5. foo55
  6. foo8.0
  7. fooaha
  8. bar7
  9. immediate
  10. 10
  11. 4true
  12. 132
  13. '''
  14. """
  15. import macros
  16. import i2416
  17. i2416()
  18. import mcan_access_hidden_field
  19. var myfoo = createFoo(33, 44)
  20. echo myfoo.geta
  21. import mgensym_generic_cross_module
  22. foo(55)
  23. foo 8.0
  24. foo "aha"
  25. bar 7
  26. block generic_templates:
  27. type
  28. SomeObj = object of RootObj
  29. Foo[T, U] = object
  30. x: T
  31. y: U
  32. template someTemplate[T](): tuple[id: int32, obj: T] =
  33. var result: tuple[id: int32, obj: T] = (0'i32, T())
  34. result
  35. let ret = someTemplate[SomeObj]()
  36. # https://github.com/nim-lang/Nim/issues/7829
  37. proc inner[T](): int =
  38. discard
  39. template outer[A](): untyped =
  40. inner[A]()
  41. template outer[B](x: int): untyped =
  42. inner[B]()
  43. var i1 = outer[int]()
  44. var i2 = outer[int](i1)
  45. # https://github.com/nim-lang/Nim/issues/7883
  46. template t1[T: int|int64](s: string): T =
  47. var t: T
  48. t
  49. template t1[T: int|int64](x: int, s: string): T =
  50. var t: T
  51. t
  52. var i3: int = t1[int]("xx")
  53. block tgetast_typeliar:
  54. proc error(s: string) = quit s
  55. macro assertOrReturn(condition: bool; message: string): typed =
  56. var line = condition.lineInfo()
  57. result = quote do:
  58. block:
  59. if not likely(`condition`):
  60. error("Assertion failed: " & $(`message`) & "\n" & `line`)
  61. return
  62. macro assertOrReturn(condition: bool): typed =
  63. var message = condition.toStrLit()
  64. result = getAst assertOrReturn(condition, message)
  65. proc point(size: int16): tuple[x, y: int16] =
  66. # returns random point in square area with given `size`
  67. assertOrReturn size > 0
  68. type
  69. MyFloat = object
  70. val: float
  71. converter to_myfloat(x: float): MyFloat {.inline.} =
  72. MyFloat(val: x)
  73. block pattern_with_converter:
  74. proc `+`(x1, x2: MyFloat): MyFloat =
  75. MyFloat(val: x1.val + x2.val)
  76. proc `*`(x1, x2: MyFloat): MyFloat =
  77. MyFloat(val: x1.val * x2.val)
  78. template optMul{`*`(a, 2.0)}(a: MyFloat): MyFloat =
  79. a + a
  80. func floatMyFloat(x: MyFloat): MyFloat =
  81. result = x * 2.0
  82. func floatDouble(x: float): float =
  83. result = x * 2.0
  84. doAssert floatDouble(5) == 10.0
  85. block prefer_immediate:
  86. # Test that immediate templates are preferred over non-immediate templates
  87. template foo(a, b: untyped) = echo "foo expr"
  88. template foo(a, b: int) = echo "foo int"
  89. template foo(a, b: float) = echo "foo float"
  90. template foo(a, b: string) = echo "foo string"
  91. template foo(a, b: untyped) {.immediate.} = echo "immediate"
  92. template foo(a, b: bool) = echo "foo bool"
  93. template foo(a, b: char) = echo "foo char"
  94. foo(undeclaredIdentifier, undeclaredIdentifier2)
  95. block procparshadow:
  96. template something(name: untyped) =
  97. proc name(x: int) =
  98. var x = x # this one should not be rejected by the compiler (#5225)
  99. echo x
  100. something(what)
  101. what(10)
  102. # bug #4750
  103. type
  104. O = object
  105. i: int
  106. OP = ptr O
  107. template alf(p: pointer): untyped =
  108. cast[OP](p)
  109. proc t1(al: pointer) =
  110. var o = alf(al)
  111. proc t2(alf: pointer) =
  112. var x = alf
  113. var o = alf(x)
  114. block symchoicefield:
  115. type Foo = object
  116. len: int
  117. var f = Foo(len: 40)
  118. template getLen(f: Foo): int = f.len
  119. doAssert f.getLen == 40
  120. # This fails, because `len` gets the nkOpenSymChoice
  121. # treatment inside the template early pass and then
  122. # it can't be recognized as a field anymore
  123. import os, times
  124. include "sunset.nimf"
  125. block ttempl:
  126. const
  127. tabs = [["home", "index"],
  128. ["news", "news"],
  129. ["documentation", "documentation"],
  130. ["download", "download"],
  131. ["FAQ", "question"],
  132. ["links", "links"]]
  133. var i = 0
  134. for item in items(tabs):
  135. var content = $i
  136. var file: File
  137. if open(file, changeFileExt(item[1], "html"), fmWrite):
  138. write(file, sunsetTemplate(current=item[1], ticker="", content=content,
  139. tabs=tabs))
  140. close(file)
  141. else:
  142. write(stdout, "cannot open file for writing")
  143. inc(i)
  144. block ttempl4:
  145. template `:=`(name, val: untyped): typed =
  146. var name = val
  147. ha := 1 * 4
  148. hu := "ta-da" == "ta-da"
  149. echo ha, hu
  150. import mtempl5
  151. block ttempl5:
  152. echo templ()
  153. #bug #892
  154. proc parse_to_close(value: string, index: int, open='(', close=')'): int =
  155. discard
  156. # Call parse_to_close
  157. template get_next_ident: typed =
  158. discard "{something}".parse_to_close(0, open = '{', close = '}')
  159. get_next_ident()
  160. #identifier expected, but found '(open|open|open)'
  161. #bug #880 (also example in the manual!)
  162. template typedef(name: untyped, typ: typedesc) =
  163. type
  164. `T name` {.inject.} = typ
  165. `P name` {.inject.} = ref `T name`
  166. typedef(myint, int)
  167. var x: PMyInt
  168. block templreturntype:
  169. template `=~` (a: int, b: int): bool = false
  170. var foo = 2 =~ 3