mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-30 01:44:37 +00:00
* Add a test case for #10202 * Fix asgn for object tyVars; fixes #10202 * Check the variant kind before accessing the sym field
472 lines
9.5 KiB
Nim
472 lines
9.5 KiB
Nim
template tests =
|
|
block:
|
|
var i = 0
|
|
i = 2
|
|
|
|
var y: ptr int
|
|
doAssert y == nil
|
|
doAssert isNil(y)
|
|
y = i.addr
|
|
y[] = 3
|
|
doAssert i == 3
|
|
doAssert i == y[]
|
|
|
|
let z = i.addr
|
|
z[] = 4
|
|
doAssert i == 4
|
|
doAssert i == y[] and y[] == z[]
|
|
|
|
var hmm = (a: (b: z))
|
|
var hmmptr = hmm.a.b.addr
|
|
hmmptr[][] = 5
|
|
|
|
doAssert i == 5
|
|
doAssert y == z
|
|
doAssert z == hmmptr[]
|
|
doAssert 5 == y[] and 5 == z[] and 5 == hmmptr[][]
|
|
|
|
block:
|
|
var someint = 500
|
|
|
|
let p: ptr int = someint.addr
|
|
let tup = (f: p)
|
|
let tcopy = tup
|
|
var vtcopy = tcopy
|
|
p[] = 654
|
|
doAssert p[] == 654
|
|
doAssert tup.f[] == 654
|
|
doAssert tcopy.f[] == 654
|
|
doAssert vtcopy.f[] == 654
|
|
|
|
block:
|
|
var someint = 500
|
|
|
|
var p: ptr int = someint.addr
|
|
let arr = [p]
|
|
let arrc = arr
|
|
p[] = 256
|
|
doAssert someint == 256
|
|
doAssert p[] == 256
|
|
doAssert arr[0][] == 256
|
|
doAssert arrc[0][] == 256
|
|
|
|
block:
|
|
var someref: ref int
|
|
new(someref)
|
|
var someref2 = someref
|
|
|
|
var tup1 = (f: someref)
|
|
tup1.f = someref
|
|
let tup2 = tup1
|
|
|
|
someref[] = 543
|
|
|
|
proc passref(r: var ref int): var ref int = r
|
|
new(passref(someref))
|
|
|
|
doAssert someref[] == 0
|
|
doAssert tup1.f[] == 543
|
|
doAssert tup2.f[] == 543
|
|
doAssert someref2[] == 543
|
|
|
|
block:
|
|
type Whatever = object
|
|
i: ref int
|
|
|
|
var someref: ref int
|
|
new(someref)
|
|
someref[] = 10
|
|
|
|
let w = Whatever(i: someref)
|
|
var wcopy = w
|
|
|
|
someref[] = 20
|
|
|
|
doAssert w.i[] == 20
|
|
doAssert someref[] == 20
|
|
doAssert wcopy.i[] == 20
|
|
doAssert w.i == wcopy.i
|
|
#echo w.i[], " ", someref[], " ", wcopy.i[]
|
|
|
|
block:
|
|
var oneseq: ref seq[ref int]
|
|
new(oneseq)
|
|
var aref: ref int
|
|
new(aref)
|
|
aref[] = 123
|
|
let arefs = [aref]
|
|
oneseq[] &= arefs[0]
|
|
oneseq[] &= aref
|
|
aref[] = 222
|
|
new(aref)
|
|
doAssert oneseq[0] == oneseq[1]
|
|
doAssert oneseq[0][] == 222
|
|
doAssert oneseq[1][] == 222
|
|
doAssert aref[] == 0
|
|
|
|
block:
|
|
var seqs: ref seq[ref seq[ref int]]
|
|
new(seqs)
|
|
seqs[] = newSeq[ref seq[ref int]](1)
|
|
new(seqs[0])
|
|
seqs[0][] = newSeq[ref int](0)
|
|
|
|
var aref: ref int
|
|
new aref
|
|
aref[] = 654
|
|
|
|
let arefs = [aref]
|
|
doAssert arefs[0] == aref
|
|
seqs[0][] &= arefs[0]
|
|
seqs[0][] &= aref
|
|
seqs[0][1][] = 456
|
|
let seqs2 = seqs
|
|
let same = seqs2[0][0] == seqs2[0][1]
|
|
doAssert arefs[0] == aref
|
|
doAssert aref[] == 456
|
|
doAssert seqs[].len == 1
|
|
doAssert seqs[0][].len == 2
|
|
doAssert seqs[0][0][] == 456
|
|
doAssert seqs[0][1][] == 456
|
|
doAssert same
|
|
|
|
block:
|
|
type Obj = object
|
|
x, y: int
|
|
|
|
var objrefs: seq[ref Obj] = @[(ref Obj)(nil), nil, nil]
|
|
objrefs[2].new
|
|
objrefs[2][] = Obj(x: 123, y: 321)
|
|
objrefs[1] = objrefs[2]
|
|
doAssert objrefs[0] == nil
|
|
doAssert objrefs[1].y == 321
|
|
doAssert objrefs[2].y == 321
|
|
doAssert objrefs[1] == objrefs[2]
|
|
|
|
block:
|
|
var refs: seq[ref string] = @[(ref string)(nil), nil, nil]
|
|
refs[1].new
|
|
refs[1][] = "it's a ref!"
|
|
refs[0] = refs[1]
|
|
refs[2] = refs[1]
|
|
new(refs[0])
|
|
doAssert refs[0][] == ""
|
|
doAssert refs[1][] == "it's a ref!"
|
|
doAssert refs[2][] == "it's a ref!"
|
|
doAssert refs[1] == refs[2]
|
|
|
|
block:
|
|
var retaddr_calls = 0
|
|
proc retaddr(p: var int): var int =
|
|
retaddr_calls += 1
|
|
p
|
|
|
|
var tfoo_calls = 0
|
|
proc tfoo(x: var int) =
|
|
tfoo_calls += 1
|
|
x += 10
|
|
var y = x.addr
|
|
y[] += 20
|
|
retaddr(x) += 30
|
|
let z = retaddr(x).addr
|
|
z[] += 40
|
|
|
|
var ints = @[1, 2, 3]
|
|
tfoo(ints[1])
|
|
doAssert retaddr_calls == 2
|
|
doAssert tfoo_calls == 1
|
|
doAssert ints[1] == 102
|
|
|
|
var tbar_calls = 0
|
|
proc tbar(x: var int): var int =
|
|
tbar_calls += 1
|
|
x
|
|
|
|
tbar(ints[2]) += 10
|
|
tbar(ints[2]) *= 2
|
|
doAssert tbar_calls == 2
|
|
|
|
var tqux_calls = 0
|
|
proc tqux(x: var int): ptr int =
|
|
tqux_calls += 1
|
|
x.addr
|
|
|
|
discard tqux(ints[2]) == tqux(ints[2])
|
|
doAssert tqux_calls == 2
|
|
doAssert isNil(tqux(ints[2])) == false
|
|
doAssert tqux_calls == 3
|
|
|
|
var tseq_calls = 0
|
|
proc tseq(x: var seq[int]): var seq[int] =
|
|
tseq_calls += 1
|
|
x
|
|
|
|
tseq(ints) &= 999
|
|
doAssert tseq_calls == 1
|
|
doAssert ints == @[1, 102, 26, 999]
|
|
|
|
var rawints = @[555]
|
|
rawints &= 666
|
|
doAssert rawints == @[555, 666]
|
|
|
|
var resetints_calls = 0
|
|
proc resetInts(): int =
|
|
resetints_calls += 1
|
|
ints = @[0, 0, 0]
|
|
1
|
|
|
|
proc incr(x: var int; b: int): var int =
|
|
x = x + b
|
|
x
|
|
|
|
var q = 0
|
|
var qp = q.addr
|
|
qp[] += 123
|
|
doAssert q == 123
|
|
# check order of evaluation
|
|
doAssert (resetInts() + incr(q, tqux(ints[2])[])) == 124
|
|
|
|
block: # reset
|
|
var calls = 0
|
|
proc passsomething(x: var int): var int =
|
|
calls += 1
|
|
x
|
|
|
|
var
|
|
a = 123
|
|
b = 500
|
|
c = a.addr
|
|
reset(passsomething(a))
|
|
doAssert calls == 1
|
|
reset(b)
|
|
doAssert a == b
|
|
reset(c)
|
|
doAssert c == nil
|
|
|
|
block: # strings
|
|
var calls = 0
|
|
proc stringtest(s: var string): var string =
|
|
calls += 1
|
|
s
|
|
|
|
var somestr: string
|
|
|
|
stringtest(somestr) &= 'a'
|
|
stringtest(somestr) &= 'b'
|
|
doAssert calls == 2
|
|
doAssert somestr == "ab"
|
|
stringtest(somestr) &= "woot!"
|
|
doAssert somestr == "abwoot!"
|
|
doAssert calls == 3
|
|
|
|
doAssert stringtest(somestr).len == 7
|
|
doAssert calls == 4
|
|
doAssert high(stringtest(somestr)) == 6
|
|
doAssert calls == 5
|
|
|
|
var somestr2: string
|
|
stringtest(somestr2).setLen(stringtest(somestr).len)
|
|
doAssert calls == 7
|
|
doAssert somestr2.len == somestr.len
|
|
|
|
var somestr3: string
|
|
doAssert (somestr3 & "foo") == "foo"
|
|
|
|
block:
|
|
var a, b, c, d: string
|
|
d = a & b & c
|
|
doAssert d == ""
|
|
d = stringtest(a) & stringtest(b) & stringtest(c)
|
|
doAssert calls == 10
|
|
doAssert d == ""
|
|
|
|
block: # seqs
|
|
var calls = 0
|
|
proc seqtest(s: var seq[int]): var seq[int] =
|
|
calls += 1
|
|
s
|
|
|
|
var someseq: seq[int]
|
|
|
|
seqtest(someseq) &= 1
|
|
seqtest(someseq) &= 2
|
|
doAssert calls == 2
|
|
doAssert someseq == @[1, 2]
|
|
seqtest(someseq) &= @[3, 4, 5]
|
|
doAssert someseq == @[1, 2, 3, 4, 5]
|
|
doAssert calls == 3
|
|
|
|
doAssert seqtest(someseq).len == 5
|
|
doAssert calls == 4
|
|
doAssert high(seqtest(someseq)) == 4
|
|
doAssert calls == 5
|
|
|
|
# genArrayAddr
|
|
doAssert seqtest(someseq)[2] == 3
|
|
doAssert calls == 6
|
|
|
|
seqtest(someseq).setLen(seqtest(someseq).len)
|
|
doAssert calls == 8
|
|
|
|
var somenilseq: seq[int]
|
|
seqtest(somenilseq).setLen(3)
|
|
doAssert calls == 9
|
|
doAssert somenilseq[1] == 0
|
|
|
|
someseq = @[1, 2, 3]
|
|
doAssert (seqtest(someseq) & seqtest(someseq)) == @[1, 2, 3, 1, 2, 3]
|
|
|
|
|
|
block: # mInc, mDec
|
|
var calls = 0
|
|
proc someint(x: var int): var int =
|
|
calls += 1
|
|
x
|
|
|
|
var x = 10
|
|
|
|
inc(someint(x))
|
|
doAssert x == 11
|
|
doAssert calls == 1
|
|
|
|
dec(someint(x))
|
|
doAssert x == 10
|
|
doAssert calls == 2
|
|
|
|
block: # uints
|
|
var calls = 0
|
|
proc passuint(x: var uint32): var uint32 =
|
|
calls += 1
|
|
x
|
|
|
|
var u: uint32 = 5
|
|
passuint(u) += 1
|
|
doAssert u == 6
|
|
doAssert calls == 1
|
|
|
|
passuint(u) -= 1
|
|
doAssert u == 5
|
|
doAssert calls == 2
|
|
|
|
passuint(u) *= 2
|
|
doAssert u == 10
|
|
doAssert calls == 3
|
|
|
|
block: # objs
|
|
type Thing = ref object
|
|
x, y: int
|
|
|
|
var a, b: Thing
|
|
a = Thing()
|
|
b = a
|
|
|
|
doAssert a == b
|
|
|
|
var calls = 0
|
|
proc passobj(o: var Thing): var Thing =
|
|
calls += 1
|
|
o
|
|
|
|
passobj(b) = Thing(x: 123)
|
|
doAssert calls == 1
|
|
doAssert a != b
|
|
doAssert b.x == 123
|
|
|
|
var passobjptr_calls = 0
|
|
proc passobjptr(o: var Thing): ptr Thing =
|
|
passobjptr_calls += 1
|
|
o.addr
|
|
|
|
passobjptr(b)[] = Thing(x: 234)
|
|
doAssert passobjptr_calls == 1
|
|
doAssert a != b
|
|
doAssert b.x == 234
|
|
passobjptr(b)[].x = 500
|
|
doAssert b.x == 500
|
|
|
|
var pptr = passobjptr(b)
|
|
pptr.x += 100
|
|
doAssert b.x == 600
|
|
|
|
proc getuninitptr(): ptr int =
|
|
return
|
|
|
|
doAssert getuninitptr() == nil
|
|
|
|
block: # pointer casting
|
|
var obj = (x: 321, y: 543)
|
|
var x = 500
|
|
|
|
var objptr = obj.addr
|
|
var xptr = x.addr
|
|
|
|
var p1, p2: pointer
|
|
p1 = cast[pointer](objptr)
|
|
p2 = cast[pointer](xptr)
|
|
doAssert p1 != p2
|
|
|
|
p1 = cast[pointer](objptr)
|
|
p2 = cast[pointer](objptr)
|
|
doAssert p1 == p2
|
|
|
|
let objptr2 = cast[type(objptr)](p2)
|
|
doAssert objptr == objptr2
|
|
|
|
p1 = cast[pointer](xptr)
|
|
p2 = cast[pointer](xptr)
|
|
doAssert p1 == p2
|
|
|
|
let xptr2 = cast[type(xptr)](p2)
|
|
doAssert xptr == xptr2
|
|
|
|
block: # var types
|
|
block t10202:
|
|
type Point = object
|
|
x: float
|
|
y: float
|
|
|
|
var points: seq[Point]
|
|
|
|
points.add(Point(x:1, y:2))
|
|
|
|
for i, p in points.mpairs:
|
|
p.x += 1
|
|
|
|
doAssert points[0].x == 2
|
|
|
|
block:
|
|
var ints = @[1, 2, 3]
|
|
for i, val in mpairs ints:
|
|
val *= 10
|
|
doAssert ints == @[10, 20, 30]
|
|
|
|
block:
|
|
var seqOfSeqs = @[@[1, 2], @[3, 4]]
|
|
for i, val in mpairs seqOfSeqs:
|
|
val[0] *= 10
|
|
doAssert seqOfSeqs == @[@[10, 2], @[30, 4]]
|
|
|
|
when false:
|
|
block: # openarray
|
|
# Error: internal error: genAddr: nkStmtListExpr
|
|
var calls = 0
|
|
proc getvarint(x: var openarray[int]): var int =
|
|
calls += 1
|
|
if true:
|
|
x[1]
|
|
else:
|
|
x[0]
|
|
|
|
var arr = [1, 2, 3]
|
|
getvarint(arr) += 5
|
|
doAssert calls == 1
|
|
doAssert arr[1] == 7
|
|
|
|
proc tests_in_proc =
|
|
tests
|
|
|
|
# since pointers are handled differently in global/local contexts
|
|
# let's just run all of them twice
|
|
tests_in_proc()
|
|
tests
|