diff options
author | Miran <narimiran@users.noreply.github.com> | 2018-10-12 17:02:46 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-10-12 17:02:46 +0200 |
commit | 7f18d7cbc1fc8ad87c389b8d4d873e1d1169f794 (patch) | |
tree | 8c4839495fd6fc10376dc44cc8f9c7e3c625d18f /tests/array/tarray.nim | |
parent | d2b04a8bc7a78845d25e8b789184ae54e98073ec (diff) | |
download | Nim-7f18d7cbc1fc8ad87c389b8d4d873e1d1169f794.tar.gz |
Merge tests into a larger file (part 1 of ∞) (#9318)
* merge actiontable tests * merge arithm tests * merge array tests * merge assign tests * merge bind tests * merge casestmt tests * merge closure tests * merge cnt seq tests * merge collections tests * merge concept issues tests * merge concept tests * fix failing tests * smaller outputs Use `doAssert` where possible. * fix wrong output * split `tcomputedgoto` * revert merging concepts * fix failing test
Diffstat (limited to 'tests/array/tarray.nim')
-rw-r--r-- | tests/array/tarray.nim | 576 |
1 files changed, 529 insertions, 47 deletions
diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim index 5e947e745..948e63a89 100644 --- a/tests/array/tarray.nim +++ b/tests/array/tarray.nim @@ -1,52 +1,534 @@ discard """ file: "tarray.nim" - output: "100124" + output: +''' +[4, 5, 6] + +[16, 25, 36] + +[16, 25, 36] + +apple +banana +Fruit +2 +4 +3 +none +skin +paper +@[2, 3, 4]321 +9.0 4.0 +3 +@[(Field0: 1, Field1: 2), (Field0: 3, Field1: 5)] +2 +@["a", "new one", "c"] +@[1, 2, 3] +3 +dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajs +dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdf +kgdchlfniambejop +fjpmholcibdgeakn +''' """ -# simple check for one dimensional arrays + +block tarray: + type + TMyArray = array[0..2, int] + TMyRecord = tuple[x, y: int] + TObj = object + arr: TMyarray + + + proc sum(a: openarray[int]): int = + result = 0 + var i = 0 + while i < len(a): + inc(result, a[i]) + inc(i) + + proc getPos(r: TMyRecord): int = + result = r.x + r.y + + doAssert sum([1, 2, 3, 4]) == 10 + doAssert sum([]) == 0 + doAssert getPos( (x: 5, y: 7) ) == 12 + + # bug #1669 + let filesToCreate = ["tempdir/fl1.a", "tempdir/fl2.b", + "tempdir/tempdir2/fl3.e", "tempdir/tempdir2/tempdir3/fl4.f"] + + var found: array[0..filesToCreate.high, bool] + + doAssert found.len == 4 + + # make sure empty arrays are assignable (bug #6853) + const arr1: array[0, int] = [] + const arr2 = [] + let arr3: array[0, string] = [] + + doAssert(arr1.len == 0) + doAssert(arr2.len == 0) + doAssert(arr3.len == 0) + + # Negative array length is not allowed (#6852) + doAssert(not compiles(block: + var arr: array[-1, int])) + + + proc mul(a, b: TMyarray): TMyArray = + result = a + for i in 0..len(a)-1: + result[i] = a[i] * b[i] + + var + x, y: TMyArray + o: TObj + + proc varArr1(x: var TMyArray): var TMyArray = x + proc varArr2(x: var TObj): var TMyArray = x.arr + + x = [4, 5, 6] + echo repr(varArr1(x)) + + y = x + echo repr(mul(x, y)) + + o.arr = mul(x, y) + echo repr(varArr2(o)) + + + const + myData = [[1,2,3], [4, 5, 6]] + + doAssert myData[0][2] == 3 + + + +block tarraycons: + type + TEnum = enum + eA, eB, eC, eD, eE, eF + + const + myMapping: array[TEnum, array[0..1, int]] = [ + eA: [1, 2], + eB: [3, 4], + [5, 6], + eD: [0: 8, 1: 9], + eE: [0: 8, 9], + eF: [2, 1: 9] + ] + + doAssert myMapping[eC][1] == 6 + + + +block tarraycons_ptr_generic: + type + Fruit = object of RootObj + name: string + Apple = object of Fruit + Banana = object of Fruit + + var + ir = Fruit(name: "Fruit") + ia = Apple(name: "apple") + ib = Banana(name: "banana") + + let x = [ia.addr, ib.addr, ir.addr] + for c in x: echo c.name + + type + Vehicle[T] = object of RootObj + tire: T + Car[T] = object of Vehicle[T] + Bike[T] = object of Vehicle[T] + + var v = Vehicle[int](tire: 3) + var c = Car[int](tire: 4) + var b = Bike[int](tire: 2) + + let y = [b.addr, c.addr, v.addr] + for c in y: echo c.tire + + type + Book[T] = ref object of RootObj + cover: T + Hard[T] = ref object of Book[T] + Soft[T] = ref object of Book[T] + + var bn = Book[string](cover: "none") + var hs = Hard[string](cover: "skin") + var bp = Soft[string](cover: "paper") + + let z = [bn, hs, bp] + for c in z: echo c.cover + + + +block tarraylen: + var a: array[0, int] + doAssert a.len == 0 + doAssert array[0..0, int].len == 1 + doAssert array[0..0, int]([1]).len == 1 + doAssert array[1..1, int].len == 1 + doAssert array[1..1, int]([1]).len == 1 + doAssert array[2, int].len == 2 + doAssert array[2, int]([1, 2]).len == 2 + doAssert array[1..3, int].len == 3 + doAssert array[1..3, int]([1, 2, 3]).len == 3 + doAssert array[0..2, int].len == 3 + doAssert array[0..2, int]([1, 2, 3]).len == 3 + doAssert array[-2 .. -2, int].len == 1 + doAssert([1, 2, 3].len == 3) + doAssert([42].len == 1) + + + + +type ustring = distinct string +converter toUString(s: string): ustring = ustring(s) + +block tarrayindx: + proc putEnv(key, val: string) = + # XXX: we have to leak memory here, as we cannot + # free it before the program ends (says Borland's + # documentation) + var + env: ptr array[0..500000, char] + env = cast[ptr array[0..500000, char]](alloc(len(key) + len(val) + 2)) + for i in 0..len(key)-1: env[i] = key[i] + env[len(key)] = '=' + for i in 0..len(val)-1: + env[len(key)+1+i] = val[i] + + # bug #7153 + const + UnsignedConst = 1024'u + type + SomeObject = object + s1: array[UnsignedConst, uint32] + + var + obj: SomeObject + + doAssert obj.s1[0] == 0 + doAssert obj.s1[0u] == 0 + + # bug #8049 + proc `[]`(s: ustring, i: int): ustring = s + doAssert "abcdefgh"[1..2] == "bc" + doAssert "abcdefgh"[1..^2] == "bcdefg" + + + +block troof: + proc foo[T](x, y: T): T = x + + var a = @[1, 2, 3, 4] + var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]] + echo a[1.. ^1], a[^2], a[^3], a[^4] + echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1] + + b[^1] = [8.8, 8.9] + + var c: seq[(int, int)] = @[(1,2), (3,4)] + + proc takeA(x: ptr int) = echo x[] + + takeA(addr c[^1][0]) + c[^1][1] = 5 + echo c + + proc useOpenarray(x: openArray[int]) = + echo x[^2] + + proc mutOpenarray(x: var openArray[string]) = + x[^2] = "new one" + + useOpenarray([1, 2, 3]) + + var z = @["a", "b", "c"] + mutOpenarray(z) + echo z + + # bug #6675 + var y: array[1..5, int] = [1,2,3,4,5] + y[3..5] = [1, 2, 3] + echo y[3..5] + + + var d: array['a'..'c', string] = ["a", "b", "c"] + doAssert d[^1] == "c" + + + + +import strutils, sequtils, typetraits, os type - TMyArray = array[0..2, int] - TMyRecord = tuple[x, y: int] - -proc sum(a: TMyarray): int = - result = 0 - var i = 0 - while i < len(a): - inc(result, a[i]) - inc(i) - -proc sum(a: openarray[int]): int = - result = 0 - var i = 0 - while i < len(a): - inc(result, a[i]) - inc(i) - -proc getPos(r: TMyRecord): int = - result = r.x + r.y - -write(stdout, sum([1, 2, 3, 4])) -write(stdout, sum([])) -write(stdout, getPos( (x: 5, y: 7) )) -#OUT 10012 - -# bug #1669 -let filesToCreate = ["tempdir/fl1.a", "tempdir/fl2.b", - "tempdir/tempdir2/fl3.e", "tempdir/tempdir2/tempdir3/fl4.f"] - -var found: array[0..filesToCreate.high, bool] - -echo found.len - -# make sure empty arrays are assignable (bug #6853) -const arr1: array[0, int] = [] -const arr2 = [] -let arr3: array[0, string] = [] - -doAssert(arr1.len == 0) -doAssert(arr2.len == 0) -doAssert(arr3.len == 0) - -# Negative array length is not allowed (#6852) -doAssert(not compiles(block: - var arr: array[-1, int])) \ No newline at end of file + MetadataArray* = object + data*: array[8, int] + len*: int + +# Commenting the converter removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" +converter toMetadataArray*(se: varargs[int]): MetadataArray {.inline.} = + result.len = se.len + for i in 0..<se.len: + result.data[i] = se[i] + + +block troofregression: + when NimVersion >= "0.17.3": + type Index = int or BackwardsIndex + template `^^`(s, i: untyped): untyped = + when i is BackwardsIndex: + s.len - int(i) + else: i + else: + type Index = int + template `^^`(s, i: untyped): untyped = + i + + ## With Nim devel from the start of the week (~Oct30) I managed to trigger "lib/system.nim(3536, 4) Error: expression has no address" + ## but I can't anymore after updating Nim (Nov5) + ## Now commenting this plain compiles and removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" + proc `[]`(a: var MetadataArray, idx: Index): var int {.inline.} = + a.data[a ^^ idx] + + + ############################## + ### Completely unrelated lib that triggers the issue + + type + MySeq[T] = ref object + data: seq[T] + + proc test[T](sx: MySeq[T]) = + # Removing the backward index removes the error "lib/system.nim(3536, 3) Error: for a 'var' type a variable needs to be passed" + echo sx.data[^1] # error here + + let s = MySeq[int](data: @[1, 2, 3]) + s.test() + + + # bug #6989 + + type Dist = distinct int + + proc mypred[T: Ordinal](x: T): T = T(int(x)-1) + proc cons(x: int): Dist = Dist(x) + + var d: Dist + + template `^+`(s, i: untyped): untyped = + (when i is BackwardsIndex: s.len - int(i) else: int(i)) + + proc `...`[T, U](a: T, b: U): HSlice[T, U] = + result.a = a + result.b = b + + proc `...`[T](b: T): HSlice[int, T] = + result.b = b + + template `...<`(a, b: untyped): untyped = + ## a shortcut for 'a..pred(b)'. + a ... pred(b) + + template check(a, b) = + if $a != b: + echo "Failure ", a, " != ", b + + check type(4 ...< 1), "HSlice[system.int, system.int]" + check type(4 ...< ^1), "HSlice[system.int, system.BackwardsIndex]" + check type(4 ... pred(^1)), "HSlice[system.int, system.BackwardsIndex]" + check type(4 ... mypred(8)), "HSlice[system.int, system.int]" + check type(4 ... mypred(^1)), "HSlice[system.int, system.BackwardsIndex]" + + var rot = 8 + + proc bug(s: string): string = + result = s + result = result[result.len - rot .. ^1] & "__" & result[0 ..< ^rot] + + const testStr = "abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdflfdjkl" + + echo bug(testStr) + echo testStr[testStr.len - 8 .. testStr.len - 1] & "__" & testStr[0 .. testStr.len - pred(rot)] + + var + instructions = readFile(getAppDir() / "troofregression2.txt").split(',') + programs = "abcdefghijklmnop" + + proc dance(dancers: string): string = + result = dancers + for instr in instructions: + let rem = instr[1 .. instr.high] + case instr[0] + of 's': + let rot = rem.parseInt + result = result[result.len - rot .. ^1] & result[0 ..< ^rot] + of 'x': + let + x = rem.split('/') + a = x[0].parseInt + b = x[1].parseInt + swap(result[a], result[b]) + of 'p': + let + a = result.find(rem[0]) + b = result.find(rem[^1]) + result[a] = rem[^1] + result[b] = rem[0] + else: discard + + proc longDance(dancers: string, iterations = 1_000_000_000): string = + var + dancers = dancers + seen = @[dancers] + for i in 1 .. iterations: + dancers = dancers.dance() + if dancers in seen: + return seen[iterations mod i] + seen.add(dancers) + + echo dance(programs) + echo longDance(programs) + + + +block tunchecked: + {.boundchecks: on.} + type Unchecked {.unchecked.} = array[0, char] + + var x = cast[ptr Unchecked](alloc(100)) + x[5] = 'x' + + + +import macros +block t7818: + # bug #7818 + # this is not a macro bug, but array construction bug + # I use macro to avoid object slicing + # see #7712 and #7637 + + type + Vehicle[T] = object of RootObj + tire: T + Car[T] = object of Vehicle[T] + Bike[T] = object of Vehicle[T] + + macro peek(n: typed): untyped = + let val = getTypeImpl(n).treeRepr + newLit(val) + + block test_t7818: + var v = Vehicle[int](tire: 3) + var c = Car[int](tire: 4) + var b = Bike[int](tire: 2) + + let y = peek([c, b, v]) + let z = peek([v, c, b]) + doAssert(y == z) + + block test_t7906_1: + proc init(x: typedesc, y: int): ref x = + result = new(ref x) + result.tire = y + + var v = init(Vehicle[int], 3) + var c = init(Car[int], 4) + var b = init(Bike[int], 2) + + let y = peek([c, b, v]) + let z = peek([v, c, b]) + doAssert(y == z) + + block test_t7906_2: + var v = Vehicle[int](tire: 3) + var c = Car[int](tire: 4) + var b = Bike[int](tire: 2) + + let y = peek([c.addr, b.addr, v.addr]) + let z = peek([v.addr, c.addr, b.addr]) + doAssert(y == z) + + block test_t7906_3: + type + Animal[T] = object of RootObj + hair: T + Mammal[T] = object of Animal[T] + Monkey[T] = object of Mammal[T] + + var v = Animal[int](hair: 3) + var c = Mammal[int](hair: 4) + var b = Monkey[int](hair: 2) + + let z = peek([c.addr, b.addr, v.addr]) + let y = peek([v.addr, c.addr, b.addr]) + doAssert(y == z) + + type + Fruit[T] = ref object of RootObj + color: T + Apple[T] = ref object of Fruit[T] + Banana[T] = ref object of Fruit[T] + + proc testArray[T](x: array[3, Fruit[T]]): string = + result = "" + for c in x: + result.add $c.color + + proc testOpenArray[T](x: openArray[Fruit[T]]): string = + result = "" + for c in x: + result.add $c.color + + block test_t7906_4: + var v = Fruit[int](color: 3) + var c = Apple[int](color: 4) + var b = Banana[int](color: 2) + + let y = peek([c, b, v]) + let z = peek([v, c, b]) + doAssert(y == z) + + block test_t7906_5: + var a = Fruit[int](color: 1) + var b = Apple[int](color: 2) + var c = Banana[int](color: 3) + + doAssert(testArray([a, b, c]) == "123") + doAssert(testArray([b, c, a]) == "231") + + doAssert(testOpenArray([a, b, c]) == "123") + doAssert(testOpenArray([b, c, a]) == "231") + + doAssert(testOpenArray(@[a, b, c]) == "123") + doAssert(testOpenArray(@[b, c, a]) == "231") + + proc testArray[T](x: array[3, ptr Vehicle[T]]): string = + result = "" + for c in x: + result.add $c.tire + + proc testOpenArray[T](x: openArray[ptr Vehicle[T]]): string = + result = "" + for c in x: + result.add $c.tire + + block test_t7906_6: + var u = Vehicle[int](tire: 1) + var v = Bike[int](tire: 2) + var w = Car[int](tire: 3) + + doAssert(testArray([u.addr, v.addr, w.addr]) == "123") + doAssert(testArray([w.addr, u.addr, v.addr]) == "312") + + doAssert(testOpenArray([u.addr, v.addr, w.addr]) == "123") + doAssert(testOpenArray([w.addr, u.addr, v.addr]) == "312") + + doAssert(testOpenArray(@[u.addr, v.addr, w.addr]) == "123") + doAssert(testOpenArray(@[w.addr, u.addr, v.addr]) == "312") |