tvmmisc.nim 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. # bug #4462
  2. import macros
  3. import os
  4. block:
  5. proc foo(t: typedesc) {.compileTime.} =
  6. assert sameType(getType(t), getType(int))
  7. static:
  8. foo(int)
  9. # #4412
  10. block:
  11. proc default[T](t: typedesc[T]): T {.inline.} = discard
  12. static:
  13. var x = default(type(0))
  14. # #6379
  15. import algorithm
  16. static:
  17. var numArray = [1, 2, 3, 4, -1]
  18. numArray.sort(cmp)
  19. assert numArray == [-1, 1, 2, 3, 4]
  20. var str = "cba"
  21. str.sort(cmp)
  22. assert str == "abc"
  23. # #6086
  24. import math, sequtils, sugar
  25. block:
  26. proc f: int =
  27. toSeq(10..<10_000).filter(
  28. a => a == ($a).map(
  29. d => (d.ord-'0'.ord).int^4
  30. ).sum
  31. ).sum
  32. var a = f()
  33. const b = f()
  34. assert a == b
  35. block:
  36. proc f(): seq[char] =
  37. result = "hello".map(proc(x: char): char = x)
  38. var runTime = f()
  39. const compTime = f()
  40. assert runTime == compTime
  41. # #6083
  42. block:
  43. proc abc(): seq[int] =
  44. result = @[0]
  45. result.setLen(2)
  46. var tmp: int
  47. for i in 0 ..< 2:
  48. inc tmp
  49. result[i] = tmp
  50. const fact1000 = abc()
  51. assert fact1000 == @[1, 2]
  52. # Tests for VM ops
  53. block:
  54. static:
  55. # for joint test, the project path is different, so I disabled it:
  56. when false:
  57. assert "vm" in getProjectPath()
  58. let b = getEnv("UNSETENVVAR")
  59. assert b == ""
  60. assert existsEnv("UNSERENVVAR") == false
  61. putEnv("UNSETENVVAR", "VALUE")
  62. assert getEnv("UNSETENVVAR") == "VALUE"
  63. assert existsEnv("UNSETENVVAR") == true
  64. assert fileExists("MISSINGFILE") == false
  65. assert dirExists("MISSINGDIR") == false
  66. # #7210
  67. block:
  68. static:
  69. proc f(size: int): int =
  70. var some = newStringOfCap(size)
  71. result = size
  72. doAssert f(4) == 4
  73. # #6689
  74. block:
  75. static:
  76. proc foo(): int = 0
  77. var f: proc(): int
  78. doAssert f.isNil
  79. f = foo
  80. doAssert(not f.isNil)
  81. block:
  82. static:
  83. var x: ref ref int
  84. new(x)
  85. doAssert(not x.isNil)
  86. # #7871
  87. static:
  88. type Obj = object
  89. field: int
  90. var s = newSeq[Obj](1)
  91. var o = Obj()
  92. s[0] = o
  93. o.field = 2
  94. doAssert s[0].field == 0
  95. # #8125
  96. static:
  97. let def_iter_var = ident("it")
  98. # #8142
  99. static:
  100. type Obj = object
  101. names: string
  102. proc pushName(o: var Obj) =
  103. var s = ""
  104. s.add("FOOBAR")
  105. o.names.add(s)
  106. var o = Obj()
  107. o.names = ""
  108. o.pushName()
  109. o.pushName()
  110. doAssert o.names == "FOOBARFOOBAR"
  111. # #8154
  112. import parseutils
  113. static:
  114. type Obj = object
  115. i: int
  116. proc foo(): Obj =
  117. discard parseInt("1", result.i, 0)
  118. static:
  119. doAssert foo().i == 1
  120. # #10333
  121. block:
  122. const
  123. encoding: auto = [
  124. ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"],
  125. ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],
  126. ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"],
  127. ["", "M", "MM", "MMM", "--", "-", "--", "---", "----", "--"],
  128. ]
  129. doAssert encoding.len == 4
  130. # #10886
  131. proc tor(): bool =
  132. result = true
  133. result = false or result
  134. proc tand(): bool =
  135. result = false
  136. result = true and result
  137. const
  138. ctor = tor()
  139. ctand = not tand()
  140. static:
  141. doAssert ctor
  142. doAssert ctand
  143. block: # bug #13081
  144. type Kind = enum
  145. k0, k1, k2, k3
  146. type Foo = object
  147. x0: float
  148. case kind: Kind
  149. of k0: discard
  150. of k1: x1: int
  151. of k2: x2: string
  152. of k3: x3: string
  153. const j1 = Foo(x0: 1.2, kind: k1, x1: 12)
  154. const j2 = Foo(x0: 1.3, kind: k2, x2: "abc")
  155. const j3 = Foo(x0: 1.3, kind: k3, x3: "abc2")
  156. static:
  157. doAssert $j1 == "(x0: 1.2, kind: k1, x1: 12)"
  158. doAssert $j2 == """(x0: 1.3, kind: k2, x2: "abc")"""
  159. doAssert $j3 == """(x0: 1.3, kind: k3, x3: "abc2")"""
  160. doAssert $j1 == "(x0: 1.2, kind: k1, x1: 12)"
  161. doAssert $j2 == """(x0: 1.3, kind: k2, x2: "abc")"""
  162. doAssert $j3 == """(x0: 1.3, kind: k3, x3: "abc2")"""
  163. doAssert j1.x1 == 12
  164. static:
  165. doAssert j1.x1 == 12
  166. block: # bug #15595
  167. proc fn0()=echo 0
  168. proc fn1()=discard
  169. proc main=
  170. var local = 0
  171. proc fn2()=echo local
  172. var a0 = fn0
  173. var a1 = fn1
  174. var a2 = fn2
  175. var a3: proc()
  176. var a4: proc()
  177. doAssert a0 == fn0 # bugfix
  178. doAssert a1 == fn1 # ditto
  179. doAssert a2 == fn2 # ditto
  180. doAssert fn0 != fn1
  181. doAssert a2 != nil
  182. doAssert a3 == nil # bugfix
  183. doAssert a3 == a4 # bugfix
  184. static: main()
  185. main()
  186. # bug #15363
  187. import sequtils
  188. block:
  189. func identity(a: bool): bool = a
  190. var a: seq[bool] = static:
  191. newSeq[bool](0).mapIt(it) # segfaults
  192. var b: seq[bool] = static:
  193. newSeq[bool](0).filterIt(it) # does not segfault
  194. var c: seq[bool] = static:
  195. newSeq[bool](0).map(identity) # does not segfault
  196. var d: seq[bool] = static:
  197. newSeq[bool](0).map(proc (a: bool): bool = false) # segfaults
  198. var e: seq[bool] = static:
  199. newSeq[bool](0).filter(identity) # does not segfault
  200. var f: seq[bool] = static:
  201. newSeq[bool](0).filter(proc (a: bool): bool = false) # segfaults
  202. doAssert a == @[]
  203. doAssert b == @[]
  204. doAssert c == @[]
  205. doAssert d == @[]
  206. doAssert e == @[]
  207. doAssert f == @[]
  208. import tables
  209. block: # bug #8007
  210. type
  211. CostKind = enum
  212. Fixed,
  213. Dynamic
  214. Cost = object
  215. case kind*: CostKind
  216. of Fixed:
  217. cost*: int
  218. of Dynamic:
  219. handler*: proc(value: int): int {.nimcall.}
  220. proc foo(value: int): int {.nimcall.} =
  221. sizeof(value)
  222. const a: array[2, Cost] =[
  223. Cost(kind: Fixed, cost: 999),
  224. Cost(kind: Dynamic, handler: foo)
  225. ]
  226. # OK with arrays & object variants
  227. doAssert $a == "[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
  228. const b: Table[int, Cost] = {
  229. 0: Cost(kind: Fixed, cost: 999),
  230. 1: Cost(kind: Dynamic, handler: foo)
  231. }.toTable
  232. # KO with Tables & object variants
  233. # echo b # {0: (kind: Fixed, cost: 0), 1: (kind: Dynamic, handler: ...)} # <----- wrong behaviour
  234. doAssert $b == "{0: (kind: Fixed, cost: 999), 1: (kind: Dynamic, handler: ...)}"
  235. const c: Table[int, int] = {
  236. 0: 100,
  237. 1: 999
  238. }.toTable
  239. # OK with Tables and primitive int
  240. doAssert $c == "{0: 100, 1: 999}"
  241. # For some reason the following gives
  242. # Error: invalid type for const: Cost
  243. const d0 = Cost(kind: Fixed, cost: 999)
  244. # OK with seq & object variants
  245. const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)]
  246. doAssert $d == "@[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
  247. block: # VM wrong register free causes errors in unrelated code
  248. block: # bug #15597
  249. #[
  250. Error: unhandled exception: 'sym' is not accessible using discriminant 'kind' of type 'TNode' [FieldDefect]
  251. in /Users/timothee/git_clone/nim/Nim_prs/compiler/vm.nim(1176) rawExecute
  252. in opcIndCall
  253. in let prc = if not isClosure: bb.sym else: bb[0].sym
  254. ]#
  255. proc bar2(head: string): string = "asdf"
  256. proc gook(u1: int) = discard
  257. type PathEntry = object
  258. kind: int
  259. path: string
  260. iterator globOpt(): int =
  261. var u1: int
  262. gook(u1)
  263. gook(u1)
  264. gook(u1)
  265. gook(u1)
  266. gook(u1)
  267. gook(u1)
  268. gook(u1)
  269. gook(u1)
  270. gook(u1)
  271. gook(u1)
  272. gook(u1)
  273. gook(u1)
  274. gook(u1)
  275. gook(u1)
  276. var entry = PathEntry()
  277. entry.path = bar2("")
  278. if false:
  279. echo "here2"
  280. proc processAux(a: float) = discard
  281. template bar(iter: untyped): untyped =
  282. var ret: float
  283. for x in iter: break
  284. ret
  285. proc main() =
  286. processAux(bar(globOpt()))
  287. static: main()
  288. block: # ditto
  289. # D20201024T133245
  290. type Deque = object
  291. proc initDeque2(initialSize: int = 4): Deque = Deque()
  292. proc len2(a: Deque): int = 2
  293. proc baz(dir: string): bool = true
  294. proc bar2(head: string): string = "asdf"
  295. proc bar3(path: var string) = path = path
  296. type PathEntry = object
  297. kind: int
  298. path: string
  299. proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string = dir
  300. iterator globOpt(dir: string): int =
  301. var stack = initDeque2()
  302. doAssert baz("")
  303. let z = stack.len2
  304. if stack.len2 >= 0:
  305. var entry = PathEntry()
  306. let current = if true: stack.len2 else: stack.len2
  307. entry.path = bar2("")
  308. bar3(entry.path)
  309. if false:
  310. echo "here2" # comment here => you get same error as https://github.com/nim-lang/Nim/issues/15704
  311. proc processAux(a: float) = discard
  312. template bar(iter: untyped): untyped =
  313. var ret: float
  314. for x in iter: break
  315. ret
  316. proc main() =
  317. processAux(bar(globOpt(initGlobOpt("."))))
  318. static: main()
  319. block: # bug #15704
  320. #[
  321. Error: attempt to access a nil address kind: rkFloat
  322. ]#
  323. type Deque = object
  324. proc initDeque2(initialSize: int = 4): Deque = Deque()
  325. proc len2(a: Deque): int = 2
  326. proc baz(dir: string): bool = true
  327. proc bar2(head: string): string = "asdf"
  328. proc bar3(path: var string) = path = path
  329. type PathEntry = object
  330. kind: int
  331. path: string
  332. depth: int
  333. proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string =
  334. dir
  335. iterator globOpt(dir: string): int =
  336. var stack = initDeque2()
  337. doAssert baz("")
  338. let z = stack.len2
  339. var a5: int
  340. if stack.len2 >= 0:
  341. var entry = PathEntry()
  342. if false:
  343. echo "here"
  344. let current = if true: stack.len2 else: stack.len2
  345. entry.depth = 1
  346. entry.path = bar2("")
  347. bar3(entry.path)
  348. proc processAux(a: float) = discard
  349. template bar(iter: untyped): untyped =
  350. var ret: float
  351. for x in iter:
  352. break
  353. ret
  354. const dir = "."
  355. proc main() =
  356. processAux(bar(globOpt(initGlobOpt(dir))))
  357. static: main()