t9410.nim 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. template tests =
  2. block:
  3. var i = 0
  4. i = 2
  5. var y: ptr int
  6. doAssert y == nil
  7. doAssert isNil(y)
  8. y = i.addr
  9. y[] = 3
  10. doAssert i == 3
  11. doAssert i == y[]
  12. let z = i.addr
  13. z[] = 4
  14. doAssert i == 4
  15. doAssert i == y[] and y[] == z[]
  16. var hmm = (a: (b: z))
  17. var hmmptr = hmm.a.b.addr
  18. hmmptr[][] = 5
  19. doAssert i == 5
  20. doAssert y == z
  21. doAssert z == hmmptr[]
  22. doAssert 5 == y[] and 5 == z[] and 5 == hmmptr[][]
  23. block:
  24. var someint = 500
  25. let p: ptr int = someint.addr
  26. let tup = (f: p)
  27. let tcopy = tup
  28. var vtcopy = tcopy
  29. p[] = 654
  30. doAssert p[] == 654
  31. doAssert tup.f[] == 654
  32. doAssert tcopy.f[] == 654
  33. doAssert vtcopy.f[] == 654
  34. block:
  35. var someint = 500
  36. var p: ptr int = someint.addr
  37. let arr = [p]
  38. let arrc = arr
  39. p[] = 256
  40. doAssert someint == 256
  41. doAssert p[] == 256
  42. doAssert arr[0][] == 256
  43. doAssert arrc[0][] == 256
  44. block:
  45. var someref: ref int
  46. new(someref)
  47. var someref2 = someref
  48. var tup1 = (f: someref)
  49. tup1.f = someref
  50. let tup2 = tup1
  51. someref[] = 543
  52. proc passref(r: var ref int): var ref int = r
  53. new(passref(someref))
  54. doAssert someref[] == 0
  55. doAssert tup1.f[] == 543
  56. doAssert tup2.f[] == 543
  57. doAssert someref2[] == 543
  58. block:
  59. type Whatever = object
  60. i: ref int
  61. var someref: ref int
  62. new(someref)
  63. someref[] = 10
  64. let w = Whatever(i: someref)
  65. var wcopy = w
  66. someref[] = 20
  67. doAssert w.i[] == 20
  68. doAssert someref[] == 20
  69. doAssert wcopy.i[] == 20
  70. doAssert w.i == wcopy.i
  71. #echo w.i[], " ", someref[], " ", wcopy.i[]
  72. block:
  73. var oneseq: ref seq[ref int]
  74. new(oneseq)
  75. var aref: ref int
  76. new(aref)
  77. aref[] = 123
  78. let arefs = [aref]
  79. oneseq[] &= arefs[0]
  80. oneseq[] &= aref
  81. aref[] = 222
  82. new(aref)
  83. doAssert oneseq[0] == oneseq[1]
  84. doAssert oneseq[0][] == 222
  85. doAssert oneseq[1][] == 222
  86. doAssert aref[] == 0
  87. block:
  88. var seqs: ref seq[ref seq[ref int]]
  89. new(seqs)
  90. seqs[] = newSeq[ref seq[ref int]](1)
  91. new(seqs[0])
  92. seqs[0][] = newSeq[ref int](0)
  93. var aref: ref int
  94. new aref
  95. aref[] = 654
  96. let arefs = [aref]
  97. doAssert arefs[0] == aref
  98. seqs[0][] &= arefs[0]
  99. seqs[0][] &= aref
  100. seqs[0][1][] = 456
  101. let seqs2 = seqs
  102. let same = seqs2[0][0] == seqs2[0][1]
  103. doAssert arefs[0] == aref
  104. doAssert aref[] == 456
  105. doAssert seqs[].len == 1
  106. doAssert seqs[0][].len == 2
  107. doAssert seqs[0][0][] == 456
  108. doAssert seqs[0][1][] == 456
  109. doAssert same
  110. block:
  111. type Obj = object
  112. x, y: int
  113. var objrefs: seq[ref Obj] = @[(ref Obj)(nil), nil, nil]
  114. objrefs[2].new
  115. objrefs[2][] = Obj(x: 123, y: 321)
  116. objrefs[1] = objrefs[2]
  117. doAssert objrefs[0] == nil
  118. doAssert objrefs[1].y == 321
  119. doAssert objrefs[2].y == 321
  120. doAssert objrefs[1] == objrefs[2]
  121. block:
  122. var refs: seq[ref string] = @[(ref string)(nil), nil, nil]
  123. refs[1].new
  124. refs[1][] = "it's a ref!"
  125. refs[0] = refs[1]
  126. refs[2] = refs[1]
  127. new(refs[0])
  128. doAssert refs[0][] == ""
  129. doAssert refs[1][] == "it's a ref!"
  130. doAssert refs[2][] == "it's a ref!"
  131. doAssert refs[1] == refs[2]
  132. block:
  133. var retaddr_calls = 0
  134. proc retaddr(p: var int): var int =
  135. retaddr_calls += 1
  136. p
  137. var tfoo_calls = 0
  138. proc tfoo(x: var int) =
  139. tfoo_calls += 1
  140. x += 10
  141. var y = x.addr
  142. y[] += 20
  143. retaddr(x) += 30
  144. let z = retaddr(x).addr
  145. z[] += 40
  146. var ints = @[1, 2, 3]
  147. tfoo(ints[1])
  148. doAssert retaddr_calls == 2
  149. doAssert tfoo_calls == 1
  150. doAssert ints[1] == 102
  151. var tbar_calls = 0
  152. proc tbar(x: var int): var int =
  153. tbar_calls += 1
  154. x
  155. tbar(ints[2]) += 10
  156. tbar(ints[2]) *= 2
  157. doAssert tbar_calls == 2
  158. var tqux_calls = 0
  159. proc tqux(x: var int): ptr int =
  160. tqux_calls += 1
  161. x.addr
  162. discard tqux(ints[2]) == tqux(ints[2])
  163. doAssert tqux_calls == 2
  164. doAssert isNil(tqux(ints[2])) == false
  165. doAssert tqux_calls == 3
  166. var tseq_calls = 0
  167. proc tseq(x: var seq[int]): var seq[int] =
  168. tseq_calls += 1
  169. x
  170. tseq(ints) &= 999
  171. doAssert tseq_calls == 1
  172. doAssert ints == @[1, 102, 26, 999]
  173. var rawints = @[555]
  174. rawints &= 666
  175. doAssert rawints == @[555, 666]
  176. var resetints_calls = 0
  177. proc resetInts(): int =
  178. resetints_calls += 1
  179. ints = @[0, 0, 0]
  180. 1
  181. proc incr(x: var int; b: int): var int =
  182. x = x + b
  183. x
  184. var q = 0
  185. var qp = q.addr
  186. qp[] += 123
  187. doAssert q == 123
  188. # check order of evaluation
  189. doAssert (resetInts() + incr(q, tqux(ints[2])[])) == 124
  190. block: # reset
  191. var calls = 0
  192. proc passsomething(x: var int): var int =
  193. calls += 1
  194. x
  195. var
  196. a = 123
  197. b = 500
  198. c = a.addr
  199. reset(passsomething(a))
  200. doAssert calls == 1
  201. reset(b)
  202. doAssert a == b
  203. reset(c)
  204. doAssert c == nil
  205. block: # strings
  206. var calls = 0
  207. proc stringtest(s: var string): var string =
  208. calls += 1
  209. s
  210. var somestr: string
  211. stringtest(somestr) &= 'a'
  212. stringtest(somestr) &= 'b'
  213. doAssert calls == 2
  214. doAssert somestr == "ab"
  215. stringtest(somestr) &= "woot!"
  216. doAssert somestr == "abwoot!"
  217. doAssert calls == 3
  218. doAssert stringtest(somestr).len == 7
  219. doAssert calls == 4
  220. doAssert high(stringtest(somestr)) == 6
  221. doAssert calls == 5
  222. var somestr2: string
  223. stringtest(somestr2).setLen(stringtest(somestr).len)
  224. doAssert calls == 7
  225. doAssert somestr2.len == somestr.len
  226. var somestr3: string
  227. doAssert (somestr3 & "foo") == "foo"
  228. block:
  229. var a, b, c, d: string
  230. d = a & b & c
  231. doAssert d == ""
  232. d = stringtest(a) & stringtest(b) & stringtest(c)
  233. doAssert calls == 10
  234. doAssert d == ""
  235. block: # seqs
  236. var calls = 0
  237. proc seqtest(s: var seq[int]): var seq[int] =
  238. calls += 1
  239. s
  240. var someseq: seq[int]
  241. seqtest(someseq) &= 1
  242. seqtest(someseq) &= 2
  243. doAssert calls == 2
  244. doAssert someseq == @[1, 2]
  245. seqtest(someseq) &= @[3, 4, 5]
  246. doAssert someseq == @[1, 2, 3, 4, 5]
  247. doAssert calls == 3
  248. doAssert seqtest(someseq).len == 5
  249. doAssert calls == 4
  250. doAssert high(seqtest(someseq)) == 4
  251. doAssert calls == 5
  252. # genArrayAddr
  253. doAssert seqtest(someseq)[2] == 3
  254. doAssert calls == 6
  255. seqtest(someseq).setLen(seqtest(someseq).len)
  256. doAssert calls == 8
  257. var somenilseq: seq[int]
  258. seqtest(somenilseq).setLen(3)
  259. doAssert calls == 9
  260. doAssert somenilseq[1] == 0
  261. someseq = @[1, 2, 3]
  262. doAssert (seqtest(someseq) & seqtest(someseq)) == @[1, 2, 3, 1, 2, 3]
  263. block: # mInc, mDec
  264. var calls = 0
  265. proc someint(x: var int): var int =
  266. calls += 1
  267. x
  268. var x = 10
  269. inc(someint(x))
  270. doAssert x == 11
  271. doAssert calls == 1
  272. dec(someint(x))
  273. doAssert x == 10
  274. doAssert calls == 2
  275. block: # uints
  276. var calls = 0
  277. proc passuint(x: var uint32): var uint32 =
  278. calls += 1
  279. x
  280. var u: uint32 = 5
  281. passuint(u) += 1
  282. doAssert u == 6
  283. doAssert calls == 1
  284. passuint(u) -= 1
  285. doAssert u == 5
  286. doAssert calls == 2
  287. passuint(u) *= 2
  288. doAssert u == 10
  289. doAssert calls == 3
  290. block: # objs
  291. type Thing = ref object
  292. x, y: int
  293. var a, b: Thing
  294. a = Thing()
  295. b = a
  296. doAssert a == b
  297. var calls = 0
  298. proc passobj(o: var Thing): var Thing =
  299. calls += 1
  300. o
  301. passobj(b) = Thing(x: 123)
  302. doAssert calls == 1
  303. doAssert a != b
  304. doAssert b.x == 123
  305. var passobjptr_calls = 0
  306. proc passobjptr(o: var Thing): ptr Thing =
  307. passobjptr_calls += 1
  308. o.addr
  309. passobjptr(b)[] = Thing(x: 234)
  310. doAssert passobjptr_calls == 1
  311. doAssert a != b
  312. doAssert b.x == 234
  313. passobjptr(b)[].x = 500
  314. doAssert b.x == 500
  315. var pptr = passobjptr(b)
  316. pptr.x += 100
  317. doAssert b.x == 600
  318. proc getuninitptr(): ptr int =
  319. return
  320. doAssert getuninitptr() == nil
  321. block: # pointer casting
  322. var obj = (x: 321, y: 543)
  323. var x = 500
  324. var objptr = obj.addr
  325. var xptr = x.addr
  326. var p1, p2: pointer
  327. p1 = cast[pointer](objptr)
  328. p2 = cast[pointer](xptr)
  329. doAssert p1 != p2
  330. p1 = cast[pointer](objptr)
  331. p2 = cast[pointer](objptr)
  332. doAssert p1 == p2
  333. let objptr2 = cast[type(objptr)](p2)
  334. doAssert objptr == objptr2
  335. p1 = cast[pointer](xptr)
  336. p2 = cast[pointer](xptr)
  337. doAssert p1 == p2
  338. let xptr2 = cast[type(xptr)](p2)
  339. doAssert xptr == xptr2
  340. block: # var types
  341. block t10202:
  342. type Point = object
  343. x: float
  344. y: float
  345. var points: seq[Point]
  346. points.add(Point(x:1, y:2))
  347. for i, p in points.mpairs:
  348. p.x += 1
  349. doAssert points[0].x == 2
  350. block:
  351. var ints = @[1, 2, 3]
  352. for i, val in mpairs ints:
  353. val *= 10
  354. doAssert ints == @[10, 20, 30]
  355. block:
  356. var seqOfSeqs = @[@[1, 2], @[3, 4]]
  357. for i, val in mpairs seqOfSeqs:
  358. val[0] *= 10
  359. doAssert seqOfSeqs == @[@[10, 2], @[30, 4]]
  360. when false:
  361. block: # openArray
  362. # Error: internal error: genAddr: nkStmtListExpr
  363. var calls = 0
  364. proc getvarint(x: var openArray[int]): var int =
  365. calls += 1
  366. if true:
  367. x[1]
  368. else:
  369. x[0]
  370. var arr = [1, 2, 3]
  371. getvarint(arr) += 5
  372. doAssert calls == 1
  373. doAssert arr[1] == 7
  374. proc tests_in_proc =
  375. tests
  376. # since pointers are handled differently in global/local contexts
  377. # let's just run all of them twice
  378. tests_in_proc()
  379. tests