From 7f18d7cbc1fc8ad87c389b8d4d873e1d1169f794 Mon Sep 17 00:00:00 2001 From: Miran Date: Fri, 12 Oct 2018 17:02:46 +0200 Subject: [PATCH] =?UTF-8?q?Merge=20tests=20into=20a=20larger=20file=20(par?= =?UTF-8?q?t=201=20of=20=E2=88=9E)=20(#9318)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- tests/actiontable/tactiontable.nim | 17 +- tests/actiontable/tactiontable2.nim | 27 - tests/arithm/tand.nim | 20 - tests/arithm/tarithm.nim | 173 ++++++ tests/arithm/tcast.nim | 95 ---- tests/arithm/tnot.nim | 58 -- tests/arithm/tshl.nim | 34 -- tests/arithm/tshr.nim | 20 - tests/arithm/tsubrange.nim | 13 - tests/array/t7818.nim | 132 ----- tests/array/tarray.nim | 576 +++++++++++++++++-- tests/array/tarray2.nim | 36 -- tests/array/tarray3.nim | 13 - tests/array/tarraycons2.nim | 23 - tests/array/tarraycons_ptr_generic.nim | 51 -- tests/array/tarraylen.nim | 18 - tests/array/tarrindx.nim | 43 -- tests/array/troof1.nim | 43 -- tests/array/troof3.nim | 7 - tests/array/troofregression.nim | 46 -- tests/array/troofregression2.nim | 102 ---- tests/array/tunchecked.nim | 5 - tests/assign/tassign.nim | 231 +++++++- tests/assign/tcopy.nim | 25 - tests/assign/tgenericassign.nim | 24 - tests/assign/tgenericassigntuples.nim | 16 - tests/assign/tobjasgn.nim | 44 -- tests/assign/toverload_asgn1.nim | 76 --- tests/bind/tbind.nim | 69 +++ tests/bind/tbind1.nim | 21 - tests/bind/tbind3.nim | 11 - tests/bind/tbindoverload.nim | 12 - tests/bind/tmixin.nim | 27 - tests/casestmt/t8333.nim | 10 - tests/casestmt/tcase_arrayconstr.nim | 19 - tests/casestmt/tcase_emptyset_when.nim | 24 - tests/casestmt/tcase_setconstr.nim | 15 - tests/casestmt/tcasestm.nim | 108 ---- tests/casestmt/tcasestmt.nim | 229 ++++++++ tests/casestmt/tcomputedgoto.nim | 6 +- tests/casestmt/tduplicates.nim | 50 -- tests/closure/tclosure.nim | 728 ++++++++++++++++++++++-- tests/closure/tclosure0.nim | 87 --- tests/closure/tclosure2.nim | 101 ---- tests/closure/tclosure3.nim | 21 - tests/closure/tclosure4.nim | 13 - tests/closure/tclosurebug2.nim | 194 ------- tests/closure/tclosureinference3304.nim | 15 - tests/closure/tcodegenerr1923.nim | 9 - tests/closure/tdeeplynested.nim | 20 - tests/closure/tdonotation.nim | 50 -- tests/closure/tfib50.nim | 22 - tests/closure/tflatmap.nim | 24 - tests/closure/tforum.nim | 44 -- tests/closure/tfutclosure2138.nim | 10 - tests/closure/tinterf.nim | 24 - tests/closure/tissue1502def.nim | 6 - tests/closure/tissue1642.nim | 3 - tests/closure/tissue1846.nim | 16 - tests/closure/tissue1911.nim | 7 - tests/closure/tissue600.nim | 4 - tests/closure/tissues.nim | 55 ++ tests/closure/tjester.nim | 32 -- tests/closure/tnamedparamanonproc.nim | 14 - tests/closure/tnested.nim | 180 ++++++ tests/closure/tnestedclosure.nim | 51 -- tests/closure/tnestedproc.nim | 12 - tests/closure/tnoclosure.nim | 25 - tests/cnstseq/t2656.nim | 35 -- tests/cnstseq/tcnstseq.nim | 62 +- tests/cnstseq/tcnstseq2.nim | 12 - tests/cnstseq/tcnstseq3.nim | 7 - tests/collections/tableadds.nim | 13 - tests/collections/tapply.nim | 11 - tests/collections/tcollections.nim | 56 ++ tests/collections/tcounttable.nim | 19 - tests/collections/tdeques.nim | 17 - tests/collections/thashes.nim | 90 --- tests/collections/tindexby.nim | 22 - tests/collections/tmapit.nim | 33 -- tests/collections/tsets.nim | 5 +- tests/collections/ttableconstr.nim | 16 - tests/collections/ttables.nim | 642 ++++++++++++--------- tests/collections/ttables2.nim | 30 - tests/collections/ttablesref.nim | 171 ------ tests/collections/ttablesref2.nim | 20 - tests/collections/ttablesthreads.nim | 275 +++++++++ tests/concepts/t1128.nim | 21 - tests/concepts/t3414.nim | 22 - tests/concepts/t5642.nim | 25 - tests/concepts/t5888.nim | 26 - tests/concepts/t5968.nim | 20 - tests/concepts/t5983.nim | 22 - tests/concepts/t6462.nim | 23 - tests/concepts/t6770.nim | 27 - tests/concepts/t7952.nim | 12 - tests/concepts/t8280.nim | 16 - tests/concepts/t976.nim | 54 -- tests/concepts/tconcepts.nim | 441 ++++++++++++++ tests/concepts/tgraph.nim | 34 -- tests/concepts/tinfrecursion.nim | 13 - tests/concepts/tissues.nim | 421 ++++++++++++++ tests/concepts/tmisc_issues.nim | 113 ---- 103 files changed, 3765 insertions(+), 3397 deletions(-) delete mode 100644 tests/actiontable/tactiontable2.nim delete mode 100644 tests/arithm/tand.nim create mode 100644 tests/arithm/tarithm.nim delete mode 100644 tests/arithm/tcast.nim delete mode 100644 tests/arithm/tnot.nim delete mode 100644 tests/arithm/tshl.nim delete mode 100644 tests/arithm/tshr.nim delete mode 100644 tests/arithm/tsubrange.nim delete mode 100644 tests/array/t7818.nim delete mode 100644 tests/array/tarray2.nim delete mode 100644 tests/array/tarray3.nim delete mode 100644 tests/array/tarraycons2.nim delete mode 100644 tests/array/tarraycons_ptr_generic.nim delete mode 100644 tests/array/tarraylen.nim delete mode 100644 tests/array/tarrindx.nim delete mode 100644 tests/array/troof1.nim delete mode 100644 tests/array/troof3.nim delete mode 100644 tests/array/troofregression.nim delete mode 100644 tests/array/troofregression2.nim delete mode 100644 tests/array/tunchecked.nim delete mode 100644 tests/assign/tcopy.nim delete mode 100644 tests/assign/tgenericassign.nim delete mode 100644 tests/assign/tgenericassigntuples.nim delete mode 100644 tests/assign/tobjasgn.nim delete mode 100644 tests/assign/toverload_asgn1.nim create mode 100644 tests/bind/tbind.nim delete mode 100644 tests/bind/tbind1.nim delete mode 100644 tests/bind/tbind3.nim delete mode 100644 tests/bind/tbindoverload.nim delete mode 100644 tests/bind/tmixin.nim delete mode 100644 tests/casestmt/t8333.nim delete mode 100644 tests/casestmt/tcase_arrayconstr.nim delete mode 100644 tests/casestmt/tcase_emptyset_when.nim delete mode 100644 tests/casestmt/tcase_setconstr.nim delete mode 100644 tests/casestmt/tcasestm.nim create mode 100644 tests/casestmt/tcasestmt.nim delete mode 100644 tests/casestmt/tduplicates.nim delete mode 100644 tests/closure/tclosure0.nim delete mode 100644 tests/closure/tclosure2.nim delete mode 100644 tests/closure/tclosure3.nim delete mode 100644 tests/closure/tclosure4.nim delete mode 100644 tests/closure/tclosurebug2.nim delete mode 100644 tests/closure/tclosureinference3304.nim delete mode 100644 tests/closure/tcodegenerr1923.nim delete mode 100644 tests/closure/tdeeplynested.nim delete mode 100644 tests/closure/tdonotation.nim delete mode 100644 tests/closure/tfib50.nim delete mode 100644 tests/closure/tflatmap.nim delete mode 100644 tests/closure/tforum.nim delete mode 100644 tests/closure/tfutclosure2138.nim delete mode 100644 tests/closure/tinterf.nim delete mode 100644 tests/closure/tissue1502def.nim delete mode 100644 tests/closure/tissue1642.nim delete mode 100644 tests/closure/tissue1846.nim delete mode 100644 tests/closure/tissue1911.nim delete mode 100644 tests/closure/tissue600.nim create mode 100644 tests/closure/tissues.nim delete mode 100644 tests/closure/tjester.nim delete mode 100644 tests/closure/tnamedparamanonproc.nim create mode 100644 tests/closure/tnested.nim delete mode 100644 tests/closure/tnestedclosure.nim delete mode 100644 tests/closure/tnestedproc.nim delete mode 100644 tests/closure/tnoclosure.nim delete mode 100644 tests/cnstseq/t2656.nim delete mode 100644 tests/cnstseq/tcnstseq2.nim delete mode 100644 tests/cnstseq/tcnstseq3.nim delete mode 100644 tests/collections/tableadds.nim delete mode 100644 tests/collections/tapply.nim create mode 100644 tests/collections/tcollections.nim delete mode 100644 tests/collections/tcounttable.nim delete mode 100644 tests/collections/tdeques.nim delete mode 100644 tests/collections/thashes.nim delete mode 100644 tests/collections/tindexby.nim delete mode 100644 tests/collections/tmapit.nim delete mode 100644 tests/collections/ttableconstr.nim delete mode 100644 tests/collections/ttables2.nim delete mode 100644 tests/collections/ttablesref.nim delete mode 100644 tests/collections/ttablesref2.nim create mode 100644 tests/collections/ttablesthreads.nim delete mode 100644 tests/concepts/t1128.nim delete mode 100644 tests/concepts/t3414.nim delete mode 100644 tests/concepts/t5642.nim delete mode 100644 tests/concepts/t5888.nim delete mode 100644 tests/concepts/t5968.nim delete mode 100644 tests/concepts/t5983.nim delete mode 100644 tests/concepts/t6462.nim delete mode 100644 tests/concepts/t6770.nim delete mode 100644 tests/concepts/t7952.nim delete mode 100644 tests/concepts/t8280.nim delete mode 100644 tests/concepts/t976.nim create mode 100644 tests/concepts/tconcepts.nim delete mode 100644 tests/concepts/tgraph.nim delete mode 100644 tests/concepts/tinfrecursion.nim create mode 100644 tests/concepts/tissues.nim delete mode 100644 tests/concepts/tmisc_issues.nim diff --git a/tests/actiontable/tactiontable.nim b/tests/actiontable/tactiontable.nim index 4560d0f7f6d4a..3f15a70bddedc 100644 --- a/tests/actiontable/tactiontable.nim +++ b/tests/actiontable/tactiontable.nim @@ -1,5 +1,8 @@ discard """ - output: "action 3 arg" + output: ''' +action 3 arg +action 3 arg +''' """ import tables @@ -17,10 +20,18 @@ proc action4(arg: string) = echo "action 4 ", arg var - actionTable = { + actionTable1 = { "A": action1, "B": action2, "C": action3, "D": action4}.toTable -actionTable["C"]("arg") +const + actionTable2 = { + "A": action1, + "B": action2, + "C": action3, + "D": action4}.toTable + +actionTable1["C"]("arg") +actionTable2["C"]("arg") diff --git a/tests/actiontable/tactiontable2.nim b/tests/actiontable/tactiontable2.nim deleted file mode 100644 index fbc65a67d7bc7..0000000000000 --- a/tests/actiontable/tactiontable2.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - output: "action 3 arg" -""" - -import tables - -proc action1(arg: string) = - echo "action 1 ", arg - -proc action2(arg: string) = - echo "action 2 ", arg - -proc action3(arg: string) = - echo "action 3 ", arg - -proc action4(arg: string) = - echo "action 4 ", arg - -const - actionTable = { - "A": action1, - "B": action2, - "C": action3, - "D": action4}.toTable - -actionTable["C"]("arg") - diff --git a/tests/arithm/tand.nim b/tests/arithm/tand.nim deleted file mode 100644 index fd0fa0dea581e..0000000000000 --- a/tests/arithm/tand.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: '''int32 -int32 -1280 -1280''' -""" - -# bug #5216 - -import typetraits - -echo(name type((0x0A'i8 and 0x7F'i32) shl 7'i32)) - -let i8 = 0x0A'i8 -echo(name type((i8 and 0x7F'i32) shl 7'i32)) - -echo((0x0A'i8 and 0x7F'i32) shl 7'i32) - -let ii8 = 0x0A'i8 -echo((ii8 and 0x7F'i32) shl 7'i32) diff --git a/tests/arithm/tarithm.nim b/tests/arithm/tarithm.nim new file mode 100644 index 0000000000000..6d857a7880f61 --- /dev/null +++ b/tests/arithm/tarithm.nim @@ -0,0 +1,173 @@ +discard """ + output: ''' +int32 +int32 +1280 +1280 +''' +""" + +import typetraits + + +block tand: + # bug #5216 + echo(name type((0x0A'i8 and 0x7F'i32) shl 7'i32)) + + let i8 = 0x0A'i8 + echo(name type((i8 and 0x7F'i32) shl 7'i32)) + + echo((0x0A'i8 and 0x7F'i32) shl 7'i32) + + let ii8 = 0x0A'i8 + echo((ii8 and 0x7F'i32) shl 7'i32) + + + +block tcast: + template crossCheck(ty: untyped, exp: untyped) = + let rt = ty(exp) + const ct = ty(exp) + if $rt != $ct: + echo "Got ", ct + echo "Expected ", rt + + template add1(x: uint8): untyped = x + 1 + template add1(x: uint16): untyped = x + 1 + template add1(x: uint32): untyped = x + 1 + + template sub1(x: uint8): untyped = x - 1 + template sub1(x: uint16): untyped = x - 1 + template sub1(x: uint32): untyped = x - 1 + + crossCheck(int8, 0'i16 - 5'i16) + crossCheck(int16, 0'i32 - 5'i32) + crossCheck(int32, 0'i64 - 5'i64) + + crossCheck(uint8, 0'u8 - 5'u8) + crossCheck(uint16, 0'u16 - 5'u16) + crossCheck(uint32, 0'u32 - 5'u32) + crossCheck(uint64, 0'u64 - 5'u64) + + crossCheck(uint8, uint8.high + 5'u8) + crossCheck(uint16, uint16.high + 5'u16) + crossCheck(uint32, uint32.high + 5'u32) + crossCheck(uint64, (-1).uint64 + 5'u64) + + doAssert $sub1(0'u8) == "255" + doAssert $sub1(0'u16) == "65535" + doAssert $sub1(0'u32) == "4294967295" + + doAssert $add1(255'u8) == "0" + doAssert $add1(65535'u16) == "0" + doAssert $add1(4294967295'u32) == "0" + + crossCheck(int32, high(int32)) + crossCheck(int32, high(int32).int32) + crossCheck(int32, low(int32)) + crossCheck(int32, low(int32).int32) + crossCheck(int64, high(int8).int16.int32.int64) + crossCheck(int64, low(int8).int16.int32.int64) + + crossCheck(int64, 0xFFFFFFFFFFFFFFFF'u64) + crossCheck(int32, 0xFFFFFFFFFFFFFFFF'u64) + crossCheck(int16, 0xFFFFFFFFFFFFFFFF'u64) + crossCheck(int8 , 0xFFFFFFFFFFFFFFFF'u64) + + + +block tnot: + # Signed types + block: + const t0: int8 = not 4 + const t1: int16 = not 4 + const t2: int32 = not 4 + const t3: int64 = not 4 + const t4: int8 = not -5 + const t5: int16 = not -5 + const t6: int32 = not -5 + const t7: int64 = not -5 + doAssert t0 == -5 + doAssert t1 == -5 + doAssert t2 == -5 + doAssert t3 == -5 + doAssert t4 == 4 + doAssert t5 == 4 + doAssert t6 == 4 + doAssert t7 == 4 + + # Unsigned types + block: + const t0: uint8 = not 4'u8 + const t1: uint16 = not 4'u16 + const t2: uint32 = not 4'u32 + const t3: uint64 = not 4'u64 + const t4: uint8 = not 251'u8 + const t5: uint16 = not 65531'u16 + const t6: uint32 = not 4294967291'u32 + const t7: uint64 = not 18446744073709551611'u64 + doAssert t0 == 251 + doAssert t1 == 65531 + doAssert t2 == 4294967291'u32 + doAssert t3 == 18446744073709551611'u64 + doAssert t4 == 4 + doAssert t5 == 4 + doAssert t6 == 4 + doAssert t7 == 4 + + + +block tshl: + # Signed types + block: + const t0: int8 = 1'i8 shl 8 + const t1: int16 = 1'i16 shl 16 + const t2: int32 = 1'i32 shl 32 + const t3: int64 = 1'i64 shl 64 + doAssert t0 == 0 + doAssert t1 == 0 + doAssert t2 == 1 + doAssert t3 == 1 + + # Unsigned types + block: + const t0: uint8 = 1'u8 shl 8 + const t1: uint16 = 1'u16 shl 16 + const t2: uint32 = 1'u32 shl 32 + const t3: uint64 = 1'u64 shl 64 + doAssert t0 == 0 + doAssert t1 == 0 + doAssert t2 == 0 + doAssert t3 == 1 + + + +block tshr: + proc T() = + # let VI = -8 + let VI64 = -8'i64 + let VI32 = -8'i32 + let VI16 = -8'i16 + let VI8 = -8'i8 + # doAssert( (VI shr 1) == 9_223_372_036_854_775_804, "Actual: " & $(VI shr 1)) + doAssert( (VI64 shr 1) == 9_223_372_036_854_775_804, "Actual: " & $(VI64 shr 1)) + doAssert( (VI32 shr 1) == 2_147_483_644, "Actual: " & $(VI32 shr 1)) + doAssert( (VI16 shr 1) == 32_764, "Actual: " & $(VI16 shr 1)) + doAssert( (VI8 shr 1) == 124, "Actual: " & $(VI8 shr 1)) + + T() + static: + T() + + + +block tsubrange: + # bug #5854 + type + n16 = range[0'i16..high(int16)] + + var level: n16 = 1 + let maxLevel: n16 = 1 + + level = min(level + 2, maxLevel) + doAssert level == 1 diff --git a/tests/arithm/tcast.nim b/tests/arithm/tcast.nim deleted file mode 100644 index 4017ed1c5d191..0000000000000 --- a/tests/arithm/tcast.nim +++ /dev/null @@ -1,95 +0,0 @@ -discard """ - output: ''' -B0 -B1 -B2 -B3 -B4 -B5 -B6 -''' -""" - -template crossCheck(ty: untyped, exp: untyped) = - let rt = ty(exp) - const ct = ty(exp) - if $rt != $ct: - echo "Got ", ct - echo "Expected ", rt - -template add1(x: uint8): untyped = x + 1 -template add1(x: uint16): untyped = x + 1 -template add1(x: uint32): untyped = x + 1 - -template sub1(x: uint8): untyped = x - 1 -template sub1(x: uint16): untyped = x - 1 -template sub1(x: uint32): untyped = x - 1 - -block: - when true: - echo "B0" - crossCheck(int8, 0'i16 - 5'i16) - crossCheck(int16, 0'i32 - 5'i32) - crossCheck(int32, 0'i64 - 5'i64) - - echo "B1" - crossCheck(uint8, 0'u8 - 5'u8) - crossCheck(uint16, 0'u16 - 5'u16) - crossCheck(uint32, 0'u32 - 5'u32) - crossCheck(uint64, 0'u64 - 5'u64) - - echo "B2" - crossCheck(uint8, uint8.high + 5'u8) - crossCheck(uint16, uint16.high + 5'u16) - crossCheck(uint32, uint32.high + 5'u32) - crossCheck(uint64, (-1).uint64 + 5'u64) - - echo "B3" - doAssert $sub1(0'u8) == "255" - doAssert $sub1(0'u16) == "65535" - doAssert $sub1(0'u32) == "4294967295" - - echo "B4" - doAssert $add1(255'u8) == "0" - doAssert $add1(65535'u16) == "0" - doAssert $add1(4294967295'u32) == "0" - - echo "B5" - crossCheck(int32, high(int32)) - crossCheck(int32, high(int32).int32) - crossCheck(int32, low(int32)) - crossCheck(int32, low(int32).int32) - crossCheck(int64, high(int8).int16.int32.int64) - crossCheck(int64, low(int8).int16.int32.int64) - - echo "B6" - crossCheck(int64, 0xFFFFFFFFFFFFFFFF'u64) - crossCheck(int32, 0xFFFFFFFFFFFFFFFF'u64) - crossCheck(int16, 0xFFFFFFFFFFFFFFFF'u64) - crossCheck(int8 , 0xFFFFFFFFFFFFFFFF'u64) - - # Out of range conversion, caught for `let`s only - # crossCheck(int8, 0'u8 - 5'u8) - # crossCheck(int16, 0'u16 - 5'u16) - # crossCheck(int32, 0'u32 - 5'u32) - # crossCheck(int64, 0'u64 - 5'u64) - - # crossCheck(int8, 0'u16 - 129'u16) - # crossCheck(uint8, 0'i16 + 257'i16) - - # Signed integer {under,over}flow is guarded against - - # crossCheck(int8, int8.high + 5'i8) - # crossCheck(int16, int16.high + 5'i16) - # crossCheck(int32, int32.high + 5'i32) - # crossCheck(int64, int64.high + 5'i64) - - # crossCheck(int8, int8.low - 5'i8) - # crossCheck(int16, int16.low - 5'i16) - # crossCheck(int32, int32.low - 5'i32) - # crossCheck(int64, int64.low - 5'i64) - - # crossCheck(uint8, 0'i8 - 5'i8) - # crossCheck(uint16, 0'i16 - 5'i16) - # crossCheck(uint32, 0'i32 - 5'i32) - # crossCheck(uint64, 0'i64 - 5'i64) diff --git a/tests/arithm/tnot.nim b/tests/arithm/tnot.nim deleted file mode 100644 index 6a4877b2c6480..0000000000000 --- a/tests/arithm/tnot.nim +++ /dev/null @@ -1,58 +0,0 @@ -discard """ - output: ''' --5 --5 --5 --5 -4 -4 -4 -4 -251 -65531 -4294967291 -18446744073709551611 -4 -4 -4 -4 -''' -""" - -# Signed types -block: - const t0: int8 = not 4 - const t1: int16 = not 4 - const t2: int32 = not 4 - const t3: int64 = not 4 - const t4: int8 = not -5 - const t5: int16 = not -5 - const t6: int32 = not -5 - const t7: int64 = not -5 - echo t0 - echo t1 - echo t2 - echo t3 - echo t4 - echo t5 - echo t6 - echo t7 - -# Unsigned types -block: - const t0: uint8 = not 4'u8 - const t1: uint16 = not 4'u16 - const t2: uint32 = not 4'u32 - const t3: uint64 = not 4'u64 - const t4: uint8 = not 251'u8 - const t5: uint16 = not 65531'u16 - const t6: uint32 = not 4294967291'u32 - const t7: uint64 = not 18446744073709551611'u64 - echo t0 - echo t1 - echo t2 - echo t3 - echo t4 - echo t5 - echo t6 - echo t7 diff --git a/tests/arithm/tshl.nim b/tests/arithm/tshl.nim deleted file mode 100644 index 0aa46d021cf07..0000000000000 --- a/tests/arithm/tshl.nim +++ /dev/null @@ -1,34 +0,0 @@ -discard """ - output: ''' -0 -0 -1 -1 -0 -0 -0 -1 -''' -""" - -# Signed types -block: - const t0: int8 = 1'i8 shl 8 - const t1: int16 = 1'i16 shl 16 - const t2: int32 = 1'i32 shl 32 - const t3: int64 = 1'i64 shl 64 - echo t0 - echo t1 - echo t2 - echo t3 - -# Unsigned types -block: - const t0: uint8 = 1'u8 shl 8 - const t1: uint16 = 1'u16 shl 16 - const t2: uint32 = 1'u32 shl 32 - const t3: uint64 = 1'u64 shl 64 - echo t0 - echo t1 - echo t2 - echo t3 diff --git a/tests/arithm/tshr.nim b/tests/arithm/tshr.nim deleted file mode 100644 index 4ba34aed97344..0000000000000 --- a/tests/arithm/tshr.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: '''''' -""" - -proc T() = - # let VI = -8 - let VI64 = -8'i64 - let VI32 = -8'i32 - let VI16 = -8'i16 - let VI8 = -8'i8 - # doAssert( (VI shr 1) == 9_223_372_036_854_775_804, "Actual: " & $(VI shr 1)) - doAssert( (VI64 shr 1) == 9_223_372_036_854_775_804, "Actual: " & $(VI64 shr 1)) - doAssert( (VI32 shr 1) == 2_147_483_644, "Actual: " & $(VI32 shr 1)) - doAssert( (VI16 shr 1) == 32_764, "Actual: " & $(VI16 shr 1)) - doAssert( (VI8 shr 1) == 124, "Actual: " & $(VI8 shr 1)) - - -T() -static: - T() diff --git a/tests/arithm/tsubrange.nim b/tests/arithm/tsubrange.nim deleted file mode 100644 index 9d60dbd1aa3c0..0000000000000 --- a/tests/arithm/tsubrange.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - output: '''1''' -""" - -# bug #5854 -type - n16* = range[0'i16..high(int16)] - -var level: n16 = 1 -let maxLevel: n16 = 1 - -level = min(level + 2, maxLevel) -echo level diff --git a/tests/array/t7818.nim b/tests/array/t7818.nim deleted file mode 100644 index 4e43bff85a5c5..0000000000000 --- a/tests/array/t7818.nim +++ /dev/null @@ -1,132 +0,0 @@ -discard """ - output: "OK" -""" - -# bug #7818 -# this is not a macro bug, but array construction bug -# I use macro to avoid object slicing -# see #7712 and #7637 -import macros - -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") - -echo "OK" - - diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim index 5e947e74580b0..948e63a893515 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..= "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") diff --git a/tests/array/tarray2.nim b/tests/array/tarray2.nim deleted file mode 100644 index 1951e6e972013..0000000000000 --- a/tests/array/tarray2.nim +++ /dev/null @@ -1,36 +0,0 @@ -discard """ - file: "tarray2.nim" - output: "[4, 5, 6]\n\n[16, 25, 36]\n\n[16, 25, 36]" -""" -# simple check for one dimensional arrays - -type - TMyArray = array[0..2, int] - - TObj = object - arr: TMyarray - -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)) - -#OUT [16, 25, 36] - - diff --git a/tests/array/tarray3.nim b/tests/array/tarray3.nim deleted file mode 100644 index 24bf26fda3dfa..0000000000000 --- a/tests/array/tarray3.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - file: "tarray3.nim" - output: "3" -""" -# simple check for two dimensional arrays - -const - myData = [[1,2,3], [4, 5, 6]] - -echo myData[0][2] #OUT 3 - - - diff --git a/tests/array/tarraycons2.nim b/tests/array/tarraycons2.nim deleted file mode 100644 index 72d9e374eedc1..0000000000000 --- a/tests/array/tarraycons2.nim +++ /dev/null @@ -1,23 +0,0 @@ -discard """ - file: "tarraycons.nim" - output: "6" -""" - -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] - ] - -echo myMapping[eC][1] - - - diff --git a/tests/array/tarraycons_ptr_generic.nim b/tests/array/tarraycons_ptr_generic.nim deleted file mode 100644 index eb89a196fcb05..0000000000000 --- a/tests/array/tarraycons_ptr_generic.nim +++ /dev/null @@ -1,51 +0,0 @@ -discard """ - output: '''apple -banana -Fruit -2 -4 -3 -none -skin -paper -''' -""" -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 diff --git a/tests/array/tarraylen.nim b/tests/array/tarraylen.nim deleted file mode 100644 index e9612de58b1e8..0000000000000 --- a/tests/array/tarraylen.nim +++ /dev/null @@ -1,18 +0,0 @@ -discard """ - output: "" -""" -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) \ No newline at end of file diff --git a/tests/array/tarrindx.nim b/tests/array/tarrindx.nim deleted file mode 100644 index 9e8ec31b604b7..0000000000000 --- a/tests/array/tarrindx.nim +++ /dev/null @@ -1,43 +0,0 @@ -discard """ - output: '''0 -0 -bc -bcdefg''' -""" - -# test another strange bug ... (I hate this compiler; it is much too buggy!) - -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 - -echo obj.s1[0] -echo obj.s1[0u] - - -# bug #8049 - -when true: - type ustring* = distinct string - converter toUString*(s: string): ustring = ustring(s) - proc `[]`*(s: ustring, i: int): ustring = s - echo "abcdefgh"[1..2] - echo "abcdefgh"[1..^2] diff --git a/tests/array/troof1.nim b/tests/array/troof1.nim deleted file mode 100644 index b486c3448290f..0000000000000 --- a/tests/array/troof1.nim +++ /dev/null @@ -1,43 +0,0 @@ -discard """ - output: '''@[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]''' -""" - -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] diff --git a/tests/array/troof3.nim b/tests/array/troof3.nim deleted file mode 100644 index efe0eafb8cc21..0000000000000 --- a/tests/array/troof3.nim +++ /dev/null @@ -1,7 +0,0 @@ -discard """ - output: '''c''' -""" - -var a: array['a'..'c', string] = ["a", "b", "c"] - -echo a[^1] diff --git a/tests/array/troofregression.nim b/tests/array/troofregression.nim deleted file mode 100644 index 0b96123a4aa55..0000000000000 --- a/tests/array/troofregression.nim +++ /dev/null @@ -1,46 +0,0 @@ -############################### -#### part from Arraymancer - -type - 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..= "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() diff --git a/tests/array/troofregression2.nim b/tests/array/troofregression2.nim deleted file mode 100644 index a594d8a47f45f..0000000000000 --- a/tests/array/troofregression2.nim +++ /dev/null @@ -1,102 +0,0 @@ -discard """ - output: '''OK -OK -OK -OK -OK -dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajs -dflfdjkl__abcdefgasfsgdfgsgdfggsdfasdfsafewfkljdsfajsdf -kgdchlfniambejop -fjpmholcibdgeakn -''' -""" - -import strutils, sequtils, typetraits, os -# 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 "OK" - else: 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) diff --git a/tests/array/tunchecked.nim b/tests/array/tunchecked.nim deleted file mode 100644 index f5ac3642d5d49..0000000000000 --- a/tests/array/tunchecked.nim +++ /dev/null @@ -1,5 +0,0 @@ -{.boundchecks: on.} -type Unchecked {.unchecked.} = array[0, char] - -var x = cast[ptr Unchecked](alloc(100)) -x[5] = 'x' diff --git a/tests/assign/tassign.nim b/tests/assign/tassign.nim index 4c173d04f0256..afdf02f8ea33d 100644 --- a/tests/assign/tassign.nim +++ b/tests/assign/tassign.nim @@ -1,31 +1,208 @@ +discard """ + file: "tassign.nim" + output: +''' +TEMP=C:\Programs\xyz\bin +8 5 0 0 +pre test a:test b:1 c:2 haha:3 +assignment test a:test b:1 c:2 haha:3 +Concrete '=' +Concrete '=' +Concrete '=' +Concrete '=' +Concrete '=' +GenericT[T] '=' int +GenericT[T] '=' float +GenericT[T] '=' float +GenericT[T] '=' float +GenericT[T] '=' string +GenericT[T] '=' int8 +GenericT[T] '=' bool +GenericT[T] '=' bool +GenericT[T] '=' bool +GenericT[T] '=' bool +''' +""" + +block tassign: # Test the assignment operator for complex types which need RTTI + type + TRec = object + x, y: int + s: string + seq: seq[string] + arr: seq[seq[array[0..3, string]]] + TRecSeq = seq[TRec] + + proc test() = + var + a, b: TRec + a.x = 1 + a.y = 2 + a.s = "Hallo!" + a.seq = @["abc", "def", "ghi", "jkl"] + a.arr = @[] + setLen(a.arr, 4) + a.arr[0] = @[] + a.arr[1] = @[] + + b = a # perform a deep copy here! + b.seq = @["xyz", "huch", "was", "soll"] + doAssert len(a.seq) == 4 + doAssert a.seq[3] == "jkl" + doAssert len(b.seq) == 4 + doAssert b.seq[3] == "soll" + doAssert b.y == 2 + + test() + + + +import strutils +block tcopy: + proc main() = + const + example = r"TEMP=C:\Programs\xyz\bin" + var + a, b: string + p: int + p = find(example, "=") + a = substr(example, 0, p-1) + b = substr(example, p+1) + writeLine(stdout, a & '=' & b) + + main() + + + +block tgenericassign: + type + TAny = object {.pure.} + value: pointer + rawType: pointer + + proc newAny(value, rawType: pointer): TAny = + result.value = value + result.rawType = rawType + + var name: cstring = "example" + + var ret: seq[tuple[name: string, a: TAny]] = @[] + for i in 0 .. 8000: + var tup = ($name, newAny(nil, nil)) + assert(tup[0] == "example") + ret.add(tup) + assert(ret[ret.len()-1][0] == "example") + + + +block tgenericassign_tuples: + var t, s: tuple[x: string, c: int] + + proc ugh: seq[tuple[x: string, c: int]] = + result = @[("abc", 232)] + + t = ugh()[0] + s = t + s = ugh()[0] + + doAssert s[0] == "abc" + doAssert s[1] == 232 + + + +block tobjasgn: + type + TSomeObj = object of RootObj + a, b: int + PSomeObj = ref object + a, b: int -type - TRec = object - x, y: int - s: string - seq: seq[string] - arr: seq[seq[array[0..3, string]]] - TRecSeq = seq[TRec] + var a = TSomeObj(a: 8) + var b = PSomeObj(a: 5) + echo a.a, " ", b.a, " ", a.b, " ", b.b + + # bug #575 + + type + Something = object of RootObj + a: string + b, c: int32 + + type + Other = object of Something + haha: int + + proc `$`(x: Other): string = + result = "a:" & x.a & " b:" & $x.b & " c:" & $x.c & " haha:" & $x.haha -proc test() = var - a, b: TRec - a.x = 1 - a.y = 2 - a.s = "Hallo!" - a.seq = @["abc", "def", "ghi", "jkl"] - a.arr = @[] - setLen(a.arr, 4) - a.arr[0] = @[] - a.arr[1] = @[] - - b = a # perform a deep copy here! - b.seq = @["xyz", "huch", "was", "soll"] - writeLine(stdout, len(a.seq)) - writeLine(stdout, a.seq[3]) - writeLine(stdout, len(b.seq)) - writeLine(stdout, b.seq[3]) - writeLine(stdout, b.y) - -test() + t: Other + + t.a = "test" + t.b = 1 + t.c = 2 + t.haha = 3 + + echo "pre test ", $t + var x = t + echo "assignment test ", x + + +import typetraits +block toverload_asgn: + type + Concrete = object + a, b: string + + proc `=`(d: var Concrete; src: Concrete) = + shallowCopy(d.a, src.a) + shallowCopy(d.b, src.b) + echo "Concrete '='" + + var x, y: array[0..2, Concrete] + var cA, cB: Concrete + + var cATup, cBTup: tuple[x: int, ha: Concrete] + + x = y + cA = cB + cATup = cBTup + + type + GenericT[T] = object + a, b: T + + proc `=`[T](d: var GenericT[T]; src: GenericT[T]) = + shallowCopy(d.a, src.a) + shallowCopy(d.b, src.b) + echo "GenericT[T] '=' ", type(T).name + + var ag: GenericT[int] + var bg: GenericT[int] + + ag = bg + + var xg, yg: array[0..2, GenericT[float]] + var cAg, cBg: GenericT[string] + + var cATupg, cBTupg: tuple[x: int, ha: GenericT[int8]] + + xg = yg + cAg = cBg + cATupg = cBTupg + + var caSeqg, cbSeqg: seq[GenericT[bool]] + newSeq(cbSeqg, 4) + caSeqg = cbSeqg + + when false: + type + Foo = object + case b: bool + of false: xx: GenericT[int] + of true: yy: bool + + var + a, b: Foo + a = b diff --git a/tests/assign/tcopy.nim b/tests/assign/tcopy.nim deleted file mode 100644 index 1e5bc3cba0ea5..0000000000000 --- a/tests/assign/tcopy.nim +++ /dev/null @@ -1,25 +0,0 @@ -discard """ - file: "tcopy.nim" - output: "TEMP=C:\\Programs\\xyz\\bin" -""" -# tests the substr proc - -import - strutils - -proc main() = - const - example = r"TEMP=C:\Programs\xyz\bin" - var - a, b: string - p: int - p = find(example, "=") - a = substr(example, 0, p-1) - b = substr(example, p+1) - writeLine(stdout, a & '=' & b) - #writeLine(stdout, b) - -main() -#OUT TEMP=C:\Programs\xyz\bin - - diff --git a/tests/assign/tgenericassign.nim b/tests/assign/tgenericassign.nim deleted file mode 100644 index bd9c6c21b3e9e..0000000000000 --- a/tests/assign/tgenericassign.nim +++ /dev/null @@ -1,24 +0,0 @@ -discard """ - output: '''came here''' -""" - -type - TAny* = object {.pure.} - value*: pointer - rawType: pointer - -proc newAny(value, rawType: pointer): TAny = - result.value = value - result.rawType = rawType - -var name: cstring = "example" - -var ret: seq[tuple[name: string, a: TAny]] = @[] -for i in 0..8000: - var tup = ($name, newAny(nil, nil)) - assert(tup[0] == "example") - ret.add(tup) - assert(ret[ret.len()-1][0] == "example") - -echo "came here" - diff --git a/tests/assign/tgenericassigntuples.nim b/tests/assign/tgenericassigntuples.nim deleted file mode 100644 index cca244577a5a7..0000000000000 --- a/tests/assign/tgenericassigntuples.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - output: '''abc232''' -""" - -var t, s: tuple[x: string, c: int] - -proc ugh: seq[tuple[x: string, c: int]] = - result = @[("abc", 232)] - -t = ugh()[0] -s = t -s = ugh()[0] - -echo s[0], t[1] - - diff --git a/tests/assign/tobjasgn.nim b/tests/assign/tobjasgn.nim deleted file mode 100644 index adfcfb087a342..0000000000000 --- a/tests/assign/tobjasgn.nim +++ /dev/null @@ -1,44 +0,0 @@ -discard """ - output: '''8 5 0 0 -pre test a:test b:1 c:2 haha:3 -assignment test a:test b:1 c:2 haha:3 -''' -""" - -# bug #1005 - -type - TSomeObj = object of RootObj - a, b: int - PSomeObj = ref object - a, b: int - -var a = TSomeObj(a: 8) -var b = PSomeObj(a: 5) -echo a.a, " ", b.a, " ", a.b, " ", b.b - -# bug #575 - -type - Something = object of RootObj - a: string - b, c: int32 - -type - Other = object of Something - haha: int - -proc `$`(x: Other): string = - result = "a:" & x.a & " b:" & $x.b & " c:" & $x.c & " haha:" & $x.haha - -var - t: Other - -t.a = "test" -t.b = 1 -t.c = 2 -t.haha = 3 - -echo "pre test ", $t -var x = t -echo "assignment test ", x diff --git a/tests/assign/toverload_asgn1.nim b/tests/assign/toverload_asgn1.nim deleted file mode 100644 index 01e7e7aa7a863..0000000000000 --- a/tests/assign/toverload_asgn1.nim +++ /dev/null @@ -1,76 +0,0 @@ -discard """ - output: '''Concrete '=' -Concrete '=' -Concrete '=' -Concrete '=' -Concrete '=' -GenericT[T] '=' int -GenericT[T] '=' float -GenericT[T] '=' float -GenericT[T] '=' float -GenericT[T] '=' string -GenericT[T] '=' int8 -GenericT[T] '=' bool -GenericT[T] '=' bool -GenericT[T] '=' bool -GenericT[T] '=' bool''' - disabled: "true" -""" - -import typetraits - -type - Concrete = object - a, b: string - -proc `=`(d: var Concrete; src: Concrete) = - shallowCopy(d.a, src.a) - shallowCopy(d.b, src.b) - echo "Concrete '='" - -var x, y: array[0..2, Concrete] -var cA, cB: Concrete - -var cATup, cBTup: tuple[x: int, ha: Concrete] - -x = y -cA = cB -cATup = cBTup - -type - GenericT[T] = object - a, b: T - -proc `=`[T](d: var GenericT[T]; src: GenericT[T]) = - shallowCopy(d.a, src.a) - shallowCopy(d.b, src.b) - echo "GenericT[T] '=' ", type(T).name - -var ag: GenericT[int] -var bg: GenericT[int] - -ag = bg - -var xg, yg: array[0..2, GenericT[float]] -var cAg, cBg: GenericT[string] - -var cATupg, cBTupg: tuple[x: int, ha: GenericT[int8]] - -xg = yg -cAg = cBg -cATupg = cBTupg - -var caSeqg, cbSeqg: seq[GenericT[bool]] -newSeq(cbSeqg, 4) -caSeqg = cbSeqg - -when false: - type - Foo = object - case b: bool - of false: xx: GenericT[int] - of true: yy: bool - - var - a, b: Foo - a = b diff --git a/tests/bind/tbind.nim b/tests/bind/tbind.nim new file mode 100644 index 0000000000000..6fcf954330887 --- /dev/null +++ b/tests/bind/tbind.nim @@ -0,0 +1,69 @@ +discard """ + file: "tbind.nim" + output: +''' +3 +1 +1 +1 +''' +""" + + +block tbind: +# Test the new ``bind`` keyword for templates + + proc p1(x: int8, y: int): int = return x + y + + template tempBind(x, y): untyped = + bind p1 + p1(x, y) + + proc p1(x: int, y: int8): int = return x - y + + # This is tricky: the call to ``p1(1'i8, 2'i8)`` should not fail in line 6, + # because it is not ambiguous there. But it is ambiguous after line 8. + + echo tempBind(1'i8, 2'i8) #OUT 3 + + +import mbind3 +echo genId() #OUT 1 + + +import strtabs +block tbinoverload: + template t() = + block: + bind newStringTable + discard {"Content-Type": "text/html"}.newStringTable() + + discard {:}.newStringTable + #discard {"Content-Type": "text/html"}.newStringTable() + t() + + +block tmixin: + type + TFoo1 = object of RootObj + v: int + TFoo2 = object of TFoo1 + v2: int + + proc test(f: TFoo1) = + echo "1" + + proc Foo[T](f: T) = + mixin test + test(f) + + var + a: TFoo1 + b: TFoo2 + + + proc test(f: TFoo2) = + echo "2" + + Foo(a) + Foo(b) diff --git a/tests/bind/tbind1.nim b/tests/bind/tbind1.nim deleted file mode 100644 index 9b13a7d11c739..0000000000000 --- a/tests/bind/tbind1.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - file: "tbind1.nim" - output: "3" -""" -# Test the new ``bind`` keyword for templates - -proc p1(x: int8, y: int): int = return x + y - -template tempBind(x, y): untyped = - bind p1 - p1(x, y) - -proc p1(x: int, y: int8): int = return x - y - -# This is tricky: the call to ``p1(1'i8, 2'i8)`` should not fail in line 6, -# because it is not ambiguous there. But it is ambiguous after line 8. - -echo tempBind(1'i8, 2'i8) #OUT 3 - - - diff --git a/tests/bind/tbind3.nim b/tests/bind/tbind3.nim deleted file mode 100644 index 551acc10f5dc8..0000000000000 --- a/tests/bind/tbind3.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - file: "tbind3.nim" - output: "1" -""" -# Module B -import mbind3 - -echo genId() #OUT 1 - - - diff --git a/tests/bind/tbindoverload.nim b/tests/bind/tbindoverload.nim deleted file mode 100644 index 6f5bb339eae43..0000000000000 --- a/tests/bind/tbindoverload.nim +++ /dev/null @@ -1,12 +0,0 @@ -import strtabs - -template t*() = - block: - bind newStringTable - discard {"Content-Type": "text/html"}.newStringTable() - - discard {:}.newStringTable - -#discard {"Content-Type": "text/html"}.newStringTable() - -t() diff --git a/tests/bind/tmixin.nim b/tests/bind/tmixin.nim deleted file mode 100644 index 65c6502614ffe..0000000000000 --- a/tests/bind/tmixin.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - output: "1\n2" -""" - -type - TFoo1 = object of RootObj - v: int - TFoo2 = object of TFoo1 - v2: int - -proc test(f: TFoo1) = - echo "1" - -proc Foo[T](f: T) = - mixin test - test(f) - -var - a: TFoo1 - b: TFoo2 - - -proc test(f: TFoo2) = - echo "2" - -Foo(a) -Foo(b) diff --git a/tests/casestmt/t8333.nim b/tests/casestmt/t8333.nim deleted file mode 100644 index ca352335816ea..0000000000000 --- a/tests/casestmt/t8333.nim +++ /dev/null @@ -1,10 +0,0 @@ -discard """ - output: "1" -""" - -converter toInt*(x: char): int = - x.int - -case 0 -of 'a': echo 0 -else: echo 1 diff --git a/tests/casestmt/tcase_arrayconstr.nim b/tests/casestmt/tcase_arrayconstr.nim deleted file mode 100644 index cd7156600a421..0000000000000 --- a/tests/casestmt/tcase_arrayconstr.nim +++ /dev/null @@ -1,19 +0,0 @@ -discard """ - output: '''Not found! -Found!''' -""" - -const - md_extension = [".md", ".markdown"] - -proc test(ext: string) = - case ext - of ".txt", md_extension: - echo "Found!" - else: - echo "Not found!" - -test(".something") -# ensure it's not evaluated at compile-time: -var foo = ".markdown" -test(foo) diff --git a/tests/casestmt/tcase_emptyset_when.nim b/tests/casestmt/tcase_emptyset_when.nim deleted file mode 100644 index e9b1ec2dff4c7..0000000000000 --- a/tests/casestmt/tcase_emptyset_when.nim +++ /dev/null @@ -1,24 +0,0 @@ -discard """ - file: "tcaseofwhen.nim" - outputsub: "compiles for 1\ni am always two\ndefault for 3\nset is 4 not 5\narray is 6 not 7\ndefault for 8" - exitcode: "0" -""" - -proc whenCase(a: int) = - case a - of (when compiles(whenCase(1)): 1 else: {}): echo "compiles for 1" - of {}: echo "me not fail" - of 2: echo "i am always two" - of []: echo "me neither" - of {4,5}: echo "set is 4 not 5" - of [6,7]: echo "array is 6 not 7" - of (when compiles(neverCompilesIBet()): 3 else: {}): echo "compiles for 3" - #of {},[]: echo "me neither" - else: echo "default for ", a - -whenCase(1) -whenCase(2) -whenCase(3) -whenCase(4) -whenCase(6) -whenCase(8) diff --git a/tests/casestmt/tcase_setconstr.nim b/tests/casestmt/tcase_setconstr.nim deleted file mode 100644 index 21f657c2b0805..0000000000000 --- a/tests/casestmt/tcase_setconstr.nim +++ /dev/null @@ -1,15 +0,0 @@ -discard """ - output: "an identifier" -""" - -const - SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'} - -proc classify(s: string) = - case s[0] - of SymChars, '_': echo "an identifier" - of {'0'..'9'}: echo "a number" - else: echo "other" - -classify("Hurra") - diff --git a/tests/casestmt/tcasestm.nim b/tests/casestmt/tcasestm.nim deleted file mode 100644 index ff912ffab37b6..0000000000000 --- a/tests/casestmt/tcasestm.nim +++ /dev/null @@ -1,108 +0,0 @@ -discard """ - file: "tcasestm.nim" - output: "ayyydd" -""" -# Test the case statement - -type - Tenum = enum eA, eB, eC - -var - x: string = "yyy" - y: Tenum = eA - i: int - -case y -of eA: write(stdout, "a") -of eB, eC: write(stdout, "b or c") - -case x -of "Andreas", "Rumpf": write(stdout, "Hallo Meister!") -of "aa", "bb": write(stdout, "Du bist nicht mein Meister") -of "cc", "hash", "when": discard -of "will", "it", "finally", "be", "generated": discard - -var z = case i - of 1..5, 8, 9: "aa" - of 6, 7: "bb" - elif x == "Ha": - "cc" - elif x == "yyy": - write(stdout, x) - "dd" - else: - "zz" - -echo z -#OUT ayyy - -let str1 = "Y" -let str2 = "NN" -let a = case str1: - of "Y": true - of "N": false - else: - echo "no good" - quit("quiting") - -proc toBool(s: string): bool = - case s: - of "": raise newException(ValueError, "Invalid boolean") - elif s[0] == 'Y': true - elif s[0] == 'N': false - else: "error".quit(2) - - -let b = "NN".toBool() - -doAssert(a == true) -doAssert(b == false) - -static: - #bug #7407 - let bstatic = "N".toBool() - doAssert(bstatic == false) - -var bb: bool -doassert(not compiles( - bb = case str2: - of "": raise newException(ValueError, "Invalid boolean") - elif str.startsWith("Y"): true - elif str.startsWith("N"): false -)) - -doassert(not compiles( - bb = case str2: - of "Y": true - of "N": false -)) - -doassert(not compiles( - bb = case str2: - of "Y": true - of "N": raise newException(ValueError, "N not allowed") -)) - -doassert(not compiles( - bb = case str2: - of "Y": raise newException(ValueError, "Invalid Y") - else: raise newException(ValueError, "Invalid N") -)) - - -doassert(not compiles( - bb = case str2: - of "Y": - raise newException(ValueError, "Invalid Y") - true - else: raise newException(ValueError, "Invalid") -)) - - -doassert(not compiles( - bb = case str2: - of "Y": - "invalid Y".quit(3) - true - else: raise newException(ValueError, "Invalid") -)) \ No newline at end of file diff --git a/tests/casestmt/tcasestmt.nim b/tests/casestmt/tcasestmt.nim new file mode 100644 index 0000000000000..333700197fa4d --- /dev/null +++ b/tests/casestmt/tcasestmt.nim @@ -0,0 +1,229 @@ +discard """ + file: "tcasestmt.nim" + output: +''' +Not found! +Found! +1 +compiles for 1 +i am always two +default for 3 +set is 4 not 5 +array is 6 not 7 +default for 8 +an identifier +OK +OK +OK +ayyydd +''' +""" + + +block arrayconstr: + const md_extension = [".md", ".markdown"] + + proc test(ext: string) = + case ext + of ".txt", md_extension: + echo "Found!" + else: + echo "Not found!" + + test(".something") + # ensure it's not evaluated at compile-time: + var foo = ".markdown" + test(foo) + + +converter toInt(x: char): int = + x.int +block t8333: + case 0 + of 'a': echo 0 + else: echo 1 + + +block emptyset_when: + proc whenCase(a: int) = + case a + of (when compiles(whenCase(1)): 1 else: {}): echo "compiles for 1" + of {}: echo "me not fail" + of 2: echo "i am always two" + of []: echo "me neither" + of {4,5}: echo "set is 4 not 5" + of [6,7]: echo "array is 6 not 7" + of (when compiles(neverCompilesIBet()): 3 else: {}): echo "compiles for 3" + #of {},[]: echo "me neither" + else: echo "default for ", a + + whenCase(1) + whenCase(2) + whenCase(3) + whenCase(4) + whenCase(6) + whenCase(8) + + +block setconstr: + const + SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'} + + proc classify(s: string) = + case s[0] + of SymChars, '_': echo "an identifier" + of {'0'..'9'}: echo "a number" + else: echo "other" + + classify("Hurra") + + + +block tduplicates: + type Kind = enum A, B + var k = A + + template reject(b) = + static: doAssert(not compiles(b)) + + reject: + var i = 2 + case i + of [1, 1]: discard + else: discard + + reject: + var i = 2 + case i + of 1, { 1..2 }: discard + else: discard + + reject: + var i = 2 + case i + of { 1, 1 }: discard + of { 1, 1 }: discard + else: discard + + reject: + case k + of [A, A]: discard + + var i = 2 + case i + of { 1, 1 }: discard + of { 2, 2 }: echo "OK" + else: discard + + case i + of { 10..30, 15..25, 5..15, 25..35 }: discard + else: echo "OK" + + case k + of {A, A..A}: echo "OK" + of B: discard + + +block tcasestm: + type + Tenum = enum eA, eB, eC + + var + x: string = "yyy" + y: Tenum = eA + i: int + + case y + of eA: write(stdout, "a") + of eB, eC: write(stdout, "b or c") + + case x + of "Andreas", "Rumpf": write(stdout, "Hallo Meister!") + of "aa", "bb": write(stdout, "Du bist nicht mein Meister") + of "cc", "hash", "when": discard + of "will", "it", "finally", "be", "generated": discard + + var z = case i + of 1..5, 8, 9: "aa" + of 6, 7: "bb" + elif x == "Ha": + "cc" + elif x == "yyy": + write(stdout, x) + "dd" + else: + "zz" + + echo z + #OUT ayyy + + let str1 = "Y" + let str2 = "NN" + let a = case str1: + of "Y": true + of "N": false + else: + echo "no good" + quit("quiting") + + proc toBool(s: string): bool = + case s: + of "": raise newException(ValueError, "Invalid boolean") + elif s[0] == 'Y': true + elif s[0] == 'N': false + else: "error".quit(2) + + + let b = "NN".toBool() + + doAssert(a == true) + doAssert(b == false) + + static: + #bug #7407 + let bstatic = "N".toBool() + doAssert(bstatic == false) + + var bb: bool + doassert(not compiles( + bb = case str2: + of "": raise newException(ValueError, "Invalid boolean") + elif str.startsWith("Y"): true + elif str.startsWith("N"): false + )) + + doassert(not compiles( + bb = case str2: + of "Y": true + of "N": false + )) + + doassert(not compiles( + bb = case str2: + of "Y": true + of "N": raise newException(ValueError, "N not allowed") + )) + + doassert(not compiles( + bb = case str2: + of "Y": raise newException(ValueError, "Invalid Y") + else: raise newException(ValueError, "Invalid N") + )) + + + doassert(not compiles( + bb = case str2: + of "Y": + raise newException(ValueError, "Invalid Y") + true + else: raise newException(ValueError, "Invalid") + )) + + + doassert(not compiles( + bb = case str2: + of "Y": + "invalid Y".quit(3) + true + else: raise newException(ValueError, "Invalid") + )) \ No newline at end of file diff --git a/tests/casestmt/tcomputedgoto.nim b/tests/casestmt/tcomputedgoto.nim index 1490729645ece..58ef3caa47725 100644 --- a/tests/casestmt/tcomputedgoto.nim +++ b/tests/casestmt/tcomputedgoto.nim @@ -1,5 +1,6 @@ discard """ - output: '''yeah A enumB + output: ''' +yeah A enumB yeah A enumB yeah CD enumD yeah CD enumE @@ -10,7 +11,8 @@ yeah A enumB yeah B enumC yeah A enumB yeah A enumB -yeah A enumB''' +yeah A enumB +''' """ type diff --git a/tests/casestmt/tduplicates.nim b/tests/casestmt/tduplicates.nim deleted file mode 100644 index f9fc1cc269279..0000000000000 --- a/tests/casestmt/tduplicates.nim +++ /dev/null @@ -1,50 +0,0 @@ -discard """ - output: ''' -OK -OK -OK - ''' -""" - -type Kind = enum A, B -var k = A - -template reject(b) = - static: doAssert(not compiles(b)) - -reject: - var i = 2 - case i - of [1, 1]: discard - else: discard - -reject: - var i = 2 - case i - of 1, { 1..2 }: discard - else: discard - -reject: - var i = 2 - case i - of { 1, 1 }: discard - of { 1, 1 }: discard - else: discard - -reject: - case k - of [A, A]: discard - -var i = 2 -case i -of { 1, 1 }: discard -of { 2, 2 }: echo "OK" -else: discard - -case i -of { 10..30, 15..25, 5..15, 25..35 }: discard -else: echo "OK" - -case k -of {A, A..A}: echo "OK" -of B: discard \ No newline at end of file diff --git a/tests/closure/tclosure.nim b/tests/closure/tclosure.nim index f4364c24aa7a8..141968462b173 100644 --- a/tests/closure/tclosure.nim +++ b/tests/closure/tclosure.nim @@ -1,64 +1,706 @@ discard """ file: "tclosure.nim" - output: '''1 3 6 11 20 foo''' + output: ''' +1 3 6 11 20 foo +foo88 +23 24foo 88 +18 +18 +99 +99 +99 +99 99 +99 99 +12 99 99 +12 99 99 +success +@[1, 2, 5] +click at 10,20 +lost focus 1 +lost focus 2 +registered handler for UserEvent 1 +registered handler for UserEvent 2 +registered handler for UserEvent 3 +registered handler for UserEvent 4 +asdas +processClient end +false +baro0 +foo88 +23 24foo 88 +foo88 +23 24foo 88 +11 +@[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] +''' """ -# Test the closure implementation -proc map(n: var openarray[int], fn: proc (x: int): int {.closure}) = - for i in 0..n.len-1: n[i] = fn(n[i]) -proc foldr(n: openarray[int], fn: proc (x, y: int): int {.closure}): int = - for i in 0..n.len-1: - result = fn(result, n[i]) +block tclosure: + proc map(n: var openarray[int], fn: proc (x: int): int {.closure}) = + for i in 0..n.len-1: n[i] = fn(n[i]) -proc each(n: openarray[int], fn: proc(x: int) {.closure.}) = - for i in 0..n.len-1: - fn(n[i]) + proc foldr(n: openarray[int], fn: proc (x, y: int): int {.closure}): int = + for i in 0..n.len-1: + result = fn(result, n[i]) -var - myData: array[0..4, int] = [0, 1, 2, 3, 4] + proc each(n: openarray[int], fn: proc(x: int) {.closure.}) = + for i in 0..n.len-1: + fn(n[i]) -proc testA() = - var p = 0 - map(myData, proc (x: int): int = - result = x + 1 shl (proc (y: int): int = - return y + p - )(0) - inc(p)) + var myData: array[0..4, int] = [0, 1, 2, 3, 4] -testA() + proc testA() = + var p = 0 + map(myData, proc (x: int): int = + result = x + 1 shl (proc (y: int): int = + return y + p + )(0) + inc(p)) -myData.each do (x: int): - write(stdout, x) - write(stdout, " ") + testA() -#OUT 2 4 6 8 10 + myData.each do (x: int): + write(stdout, x) + write(stdout, " ") -type - ITest = tuple[ - setter: proc(v: int), - getter: proc(): int] + #OUT 2 4 6 8 10 -proc getInterf(): ITest = - var shared: int + type + ITest = tuple[ + setter: proc(v: int), + getter: proc(): int] - return (setter: proc (x: int) = shared = x, - getter: proc (): int = return shared) + proc getInterf(): ITest = + var shared: int + return (setter: proc (x: int) = shared = x, + getter: proc (): int = return shared) -# bug #5015 -type Mutator* = proc(matched: string): string {.noSideEffect, gcsafe, locks: 0.} + # bug #5015 -proc putMutated*( - MutatorCount: static[int], - mTable: static[array[MutatorCount, Mutator]], input: string) = - for i in 0.. 5000_000: quit("still a leak!") + echo "success" + + main() + + + +import json, tables, sequtils +block tclosure4: + proc run(json_params: OrderedTable) = + let json_elems = json_params["files"].elems + # These fail compilation. + var files = map(json_elems, proc (x: JsonNode): string = x.str) + #var files = json_elems.map do (x: JsonNode) -> string: x.str + + let text = """{"files": ["a", "b", "c"]}""" + run((text.parseJson).fields) + + + +import hashes, math +block tclosurebug2: + type + TSlotEnum = enum seEmpty, seFilled, seDeleted + TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] + TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] + + TOrderedKeyValuePair[A, B] = tuple[ + slot: TSlotEnum, next: int, key: A, val: B] + TOrderedKeyValuePairSeq[A, B] = seq[TOrderedKeyValuePair[A, B]] + OrderedTable[A, B] = object ## table that remembers insertion order + data: TOrderedKeyValuePairSeq[A, B] + counter, first, last: int + + const + growthFactor = 2 + + proc mustRehash(length, counter: int): bool {.inline.} = + assert(length > counter) + result = (length * 2 < counter * 3) or (length - counter < 4) + + proc nextTry(h, maxHash: Hash): Hash {.inline.} = + result = ((5 * h) + 1) and maxHash + + template rawGetImpl() {.dirty.} = + var h: Hash = hash(key) and high(t.data) # start with real hash value + while t.data[h].slot != seEmpty: + if t.data[h].key == key and t.data[h].slot == seFilled: + return h + h = nextTry(h, high(t.data)) + result = -1 + + template rawInsertImpl() {.dirty.} = + var h: Hash = hash(key) and high(data) + while data[h].slot == seFilled: + h = nextTry(h, high(data)) + data[h].key = key + data[h].val = val + data[h].slot = seFilled + + template addImpl() {.dirty.} = + if mustRehash(len(t.data), t.counter): enlarge(t) + rawInsert(t, t.data, key, val) + inc(t.counter) + + template putImpl() {.dirty.} = + var index = rawGet(t, key) + if index >= 0: + t.data[index].val = val + else: + addImpl() + + proc len[A, B](t: OrderedTable[A, B]): int {.inline.} = + ## returns the number of keys in `t`. + result = t.counter + + template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} = + var h = t.first + while h >= 0: + var nxt = t.data[h].next + if t.data[h].slot == seFilled: yieldStmt + h = nxt + + iterator pairs[A, B](t: OrderedTable[A, B]): tuple[key: A, val: B] = + ## iterates over any (key, value) pair in the table `t` in insertion + ## order. + forAllOrderedPairs: + yield (t.data[h].key, t.data[h].val) + + iterator mpairs[A, B](t: var OrderedTable[A, B]): tuple[key: A, val: var B] = + ## iterates over any (key, value) pair in the table `t` in insertion + ## order. The values can be modified. + forAllOrderedPairs: + yield (t.data[h].key, t.data[h].val) + + iterator keys[A, B](t: OrderedTable[A, B]): A = + ## iterates over any key in the table `t` in insertion order. + forAllOrderedPairs: + yield t.data[h].key + + iterator values[A, B](t: OrderedTable[A, B]): B = + ## iterates over any value in the table `t` in insertion order. + forAllOrderedPairs: + yield t.data[h].val + + iterator mvalues[A, B](t: var OrderedTable[A, B]): var B = + ## iterates over any value in the table `t` in insertion order. The values + ## can be modified. + forAllOrderedPairs: + yield t.data[h].val + + proc rawGet[A, B](t: OrderedTable[A, B], key: A): int = + rawGetImpl() + + proc `[]`[A, B](t: OrderedTable[A, B], key: A): B = + ## retrieves the value at ``t[key]``. If `key` is not in `t`, + ## default empty value for the type `B` is returned + ## and no exception is raised. One can check with ``hasKey`` whether the key + ## exists. + var index = rawGet(t, key) + if index >= 0: result = t.data[index].val + + proc mget[A, B](t: var OrderedTable[A, B], key: A): var B = + ## retrieves the value at ``t[key]``. The value can be modified. + ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. + var index = rawGet(t, key) + if index >= 0: result = t.data[index].val + else: raise newException(KeyError, "key not found: " & $key) + + proc hasKey[A, B](t: OrderedTable[A, B], key: A): bool = + ## returns true iff `key` is in the table `t`. + result = rawGet(t, key) >= 0 + + proc rawInsert[A, B](t: var OrderedTable[A, B], + data: var TOrderedKeyValuePairSeq[A, B], + key: A, val: B) = + rawInsertImpl() + data[h].next = -1 + if t.first < 0: t.first = h + if t.last >= 0: data[t.last].next = h + t.last = h + + proc enlarge[A, B](t: var OrderedTable[A, B]) = + var n: TOrderedKeyValuePairSeq[A, B] + newSeq(n, len(t.data) * growthFactor) + var h = t.first + t.first = -1 + t.last = -1 + while h >= 0: + var nxt = t.data[h].next + if t.data[h].slot == seFilled: + rawInsert(t, n, t.data[h].key, t.data[h].val) + h = nxt + swap(t.data, n) + + proc `[]=`[A, B](t: var OrderedTable[A, B], key: A, val: B) = + ## puts a (key, value)-pair into `t`. + putImpl() + + proc add[A, B](t: var OrderedTable[A, B], key: A, val: B) = + ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. + addImpl() + + proc iniOrderedTable[A, B](initialSize=64): OrderedTable[A, B] = + ## creates a new ordered hash table that is empty. `initialSize` needs to be + ## a power of two. + assert isPowerOfTwo(initialSize) + result.counter = 0 + result.first = -1 + result.last = -1 + newSeq(result.data, initialSize) + + proc toOrderedTable[A, B](pairs: openarray[tuple[key: A, + val: B]]): OrderedTable[A, B] = + ## creates a new ordered hash table that contains the given `pairs`. + result = iniOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) + for key, val in items(pairs): result[key] = val + + proc sort[A, B](t: var OrderedTable[A,B], + cmp: proc (x, y: tuple[key: A, val: B]): int {.closure.}) = + ## sorts the ordered table so that the entry with the highest counter comes + ## first. This is destructive (with the advantage of being efficient)! + ## You must not modify `t` afterwards! + ## You can use the iterators `pairs`, `keys`, and `values` to iterate over + ## `t` in the sorted order. + + # we use shellsort here; fast enough and simple + var h = 1 + while true: + h = 3 * h + 1 + if h >= high(t.data): break + while true: + h = h div 3 + for i in countup(h, high(t.data)): + var j = i + #echo(t.data.len, " ", j, " - ", h) + #echo(repr(t.data[j-h])) + proc rawCmp(x, y: TOrderedKeyValuePair[A, B]): int = + if x.slot in {seEmpty, seDeleted} and y.slot in {seEmpty, seDeleted}: + return 0 + elif x.slot in {seEmpty, seDeleted}: + return -1 + elif y.slot in {seEmpty, seDeleted}: + return 1 + else: + let item1 = (x.key, x.val) + let item2 = (y.key, y.val) + return cmp(item1, item2) + + while rawCmp(t.data[j-h], t.data[j]) <= 0: + swap(t.data[j], t.data[j-h]) + j = j-h + if j < h: break + if h == 1: break + + + +import sugar +block inference3304: + type + List[T] = ref object + val: T + + proc foo[T](l: List[T]): seq[int] = + @[1,2,3,5].filter(x => x != l.val) + + echo(foo(List[int](val: 3))) + + + +block tcodegenerr1923: + type + Foo[M] = proc() : M + + proc bar[M](f : Foo[M]) = + discard f() + + proc baz() : int = 42 + + bar(baz) + + + +block doNotation: + type + Button = object + Event = object + x, y: int + + proc onClick(x: Button, handler: proc(x: Event)) = + handler(Event(x: 10, y: 20)) + + proc onFocusLost(x: Button, handler: proc()) = + handler() + + proc onUserEvent(x: Button, eventName: string, handler: proc) = + echo "registered handler for ", eventName + + var b = Button() + + b.onClick do (e: Event): + echo "click at ", e.x, ",", e.y + + b.onFocusLost: + echo "lost focus 1" + + b.onFocusLost do: + echo "lost focus 2" + + b.onUserEvent("UserEvent 1") do: + discard + + b.onUserEvent "UserEvent 2": + discard + + b.onUserEvent("UserEvent 3"): + discard + + b.onUserEvent("UserEvent 4", () => echo "event 4") + + + +import tables +block fib50: + proc memoize(f: proc (a: int64): int64): proc (a: int64): int64 = + var previous = initTable[int64, int64]() + return proc(i: int64): int64 = + if not previous.hasKey i: + previous[i] = f(i) + return previous[i] + + var fib: proc(a: int64): int64 + + fib = memoize(proc (i: int64): int64 = + if i == 0 or i == 1: + return 1 + return fib(i-1) + fib(i-2) + ) + + doAssert fib(50) == 20365011074 + + + +block tflatmap: + # bug #3995 + type + RNG = tuple[] + Rand[A] = (RNG) -> (A, RNG) + + proc nextInt(r: RNG): (int, RNG) = + (1, ()) + + proc flatMap[A,B](f: Rand[A], g: A -> Rand[B]): Rand[B] = + (rng: RNG) => ( + let (a, rng2) = f(rng); + let g1 = g(a); + g1(rng2) + ) + + proc map[A,B](s: Rand[A], f: A -> B): Rand[B] = + let g: A -> Rand[B] = (a: A) => ((rng: RNG) => (f(a), rng)) + flatMap(s, g) + + let f = nextInt.map(i => i - i mod 2) + + + +block tforum: + type + PAsyncHttpServer = ref object + value: string + PFutureBase = ref object + callback: proc () {.closure.} + value: string + failed: bool + + proc accept(server: PAsyncHttpServer): PFutureBase = + new(result) + result.callback = proc () = + discard + server.value = "hahaha" + + proc processClient(): PFutureBase = + new(result) + + proc serve(server: PAsyncHttpServer): PFutureBase = + iterator serveIter(): PFutureBase {.closure.} = + echo server.value + while true: + var acceptAddrFut = server.accept() + yield acceptAddrFut + var fut = acceptAddrFut.value + + var f = processClient() + f.callback = + proc () = + echo("processClient end") + echo(f.failed) + yield f + var x = serveIter + for i in 0 .. 1: + result = x() + result.callback() + + discard serve(PAsyncHttpServer(value: "asdas")) + + + +block futclosure2138: + proc any[T](list: varargs[T], pred: (T) -> bool): bool = + for item in list: + if pred(item): + result = true + break + + proc contains(s: string, words: varargs[string]): bool = + any(words, (word) => s.contains(word)) + + + +block tinterf: + type + ITest = tuple[ + setter: proc(v: int) {.closure.}, + getter1: proc(): int {.closure.}, + getter2: proc(): int {.closure.}] + + proc getInterf(): ITest = + var shared1, shared2: int + + return (setter: proc (x: int) = + shared1 = x + shared2 = x + 10, + getter1: proc (): int = result = shared1, + getter2: proc (): int = return shared2) + + var i = getInterf() + i.setter(56) + + doAssert i.getter1() == 56 + doAssert i.getter2() == 66 + + + +block tjester: + type + Future[T] = ref object + data: T + callback: proc () {.closure.} + + proc cbOuter(response: string) {.discardable.} = + iterator cbIter(): Future[int] {.closure.} = + for i in 0..7: + proc foo(): int = + iterator fooIter(): Future[int] {.closure.} = + echo response, i + yield Future[int](data: 17) + var iterVar = fooIter + iterVar().data + yield Future[int](data: foo()) + + var iterVar2 = cbIter + proc cb2() {.closure.} = + try: + if not finished(iterVar2): + let next = iterVar2() + if next != nil: + next.callback = cb2 + except: + echo "WTF" + cb2() + + cbOuter "baro" + + + +block tnamedparamanonproc: + type + PButton = ref object + TButtonClicked = proc(button: PButton) {.nimcall.} + + proc newButton(onClick: TButtonClicked) = + discard + + proc main() = + newButton(onClick = proc(b: PButton) = + var requestomat = 12 + ) + + main() + + + +block tnestedclosure: + proc main(param: int) = + var foo = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo foo, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + + # test simple closure within dummy 'main': + proc dummy = + proc main2(param: int) = + var fooB = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo fooB, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + main2(24) + + dummy() + + main(24) + + # Jester + async triggered this bug: + proc cbOuter() = + var response = "hohoho" + block: + proc cbIter() = + block: + proc fooIter() = + doAssert response == "hohoho" + fooIter() + cbIter() + cbOuter() + + + +block tnestedproc: + proc p(x, y: int): int = + result = x + y + + echo p((proc (): int = + var x = 7 + return x)(), + (proc (): int = return 4)()) + + + +block tnoclosure: + proc pascal(n: int) = + var row = @[1] + for r in 1..n: + row = zip(row & @[0], @[0] & row).mapIt(it[0] + it[1]) + echo row + pascal(10) diff --git a/tests/closure/tclosure0.nim b/tests/closure/tclosure0.nim deleted file mode 100644 index 9952268d5a831..0000000000000 --- a/tests/closure/tclosure0.nim +++ /dev/null @@ -1,87 +0,0 @@ -discard """ - output: '''foo88 -23 24foo 88 -18 -18 -99 -99 -99 -99 99 -99 99 -12 99 99 -12 99 99''' -""" - -when true: - # test simple closure within dummy 'main': - proc dummy = - proc main2(param: int) = - var fooB = 23 - proc outer(outerParam: string) = - var outerVar = 88 - echo outerParam, outerVar - proc inner() = - block Test: - echo fooB, " ", param, outerParam, " ", outerVar - inner() - outer("foo") - main2(24) - - dummy() - -when true: - proc outer2(x:int) : proc(y:int):int = # curry-ed application - return proc(y:int):int = x*y - - var fn = outer2(6) # the closure - echo fn(3) # it works - - var rawP = fn.rawProc() - var rawE = fn.rawEnv() - - # A type to cast the function pointer into a nimcall - type - TimesClosure = proc(a: int, x: pointer): int {.nimcall.} - - # Call the function with its closure - echo cast[TimesClosure](rawP)(3, rawE) - -when true: - proc outer = - var x, y: int = 99 - proc innerA = echo x - proc innerB = - echo y - innerA() - - innerA() - innerB() - - outer() - -when true: - proc indirectDep = - var x, y: int = 99 - proc innerA = echo x, " ", y - proc innerB = - innerA() - - innerA() - innerB() - - indirectDep() - -when true: - proc needlessIndirection = - var x, y: int = 99 - proc indirection = - var z = 12 - proc innerA = echo z, " ", x, " ", y - proc innerB = - innerA() - - innerA() - innerB() - indirection() - - needlessIndirection() diff --git a/tests/closure/tclosure2.nim b/tests/closure/tclosure2.nim deleted file mode 100644 index 9c5ee14267c4d..0000000000000 --- a/tests/closure/tclosure2.nim +++ /dev/null @@ -1,101 +0,0 @@ -discard """ - output: '''0 -11 -1 -11 -2 -11 -3 -11 -4 -11 -5 -11 -6 -11 -7 -11 -8 -11 -9 -11 -11 -py -py -py -py -px -6''' -""" - -when true: - proc ax = - for xxxx in 0..9: - var i = 0 - proc bx = - if i > 10: - echo xxxx - return - i += 1 - #for j in 0 .. 0: echo i - bx() - - bx() - echo i - - ax() - -when true: - proc accumulator(start: int): (proc(): int {.closure.}) = - var x = start-1 - #let dummy = proc = - # discard start - - result = proc (): int = - #var x = 9 - for i in 0 .. 0: x = x + 1 - - return x - - var a = accumulator(3) - let b = accumulator(4) - echo a() + b() + a() - - - proc outer = - - proc py() = - # no closure here: - for i in 0..3: echo "py" - - py() - - outer() - - -when true: - proc outer2 = - var errorValue = 3 - proc fac[T](n: T): T = - if n < 0: result = errorValue - elif n <= 1: result = 1 - else: result = n * fac(n-1) - - proc px() {.closure.} = - echo "px" - - proc py() {.closure.} = - echo "py" - - let - mapping = { - "abc": px, - "xyz": py - } - mapping[0][1]() - - echo fac(3) - - - outer2() - diff --git a/tests/closure/tclosure3.nim b/tests/closure/tclosure3.nim deleted file mode 100644 index 4de07bdb5baca..0000000000000 --- a/tests/closure/tclosure3.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - file: "tclosure3.nim" - output: "success" -""" - -proc main = - const n = 30 - for iterations in 0..50_000: - var s: seq[proc(): string {.closure.}] = @[] - for i in 0 .. n-1: - (proc () = - let ii = i - s.add(proc(): string = return $(ii*ii)))() - for i in 0 .. n-1: - let val = s[i]() - if val != $(i*i): echo "bug ", val - - if getOccupiedMem() > 5000_000: quit("still a leak!") - echo "success" - -main() diff --git a/tests/closure/tclosure4.nim b/tests/closure/tclosure4.nim deleted file mode 100644 index bc134ded6648c..0000000000000 --- a/tests/closure/tclosure4.nim +++ /dev/null @@ -1,13 +0,0 @@ - -import json, tables, sequtils - -proc run(json_params: OrderedTable) = - let json_elems = json_params["files"].elems - # These fail compilation. - var files = map(json_elems, proc (x: JsonNode): string = x.str) - #var files = json_elems.map do (x: JsonNode) -> string: x.str - echo "Hey!" - -when isMainModule: - let text = """{"files": ["a", "b", "c"]}""" - run((text.parseJson).fields) diff --git a/tests/closure/tclosurebug2.nim b/tests/closure/tclosurebug2.nim deleted file mode 100644 index 5f8911dfaf5f9..0000000000000 --- a/tests/closure/tclosurebug2.nim +++ /dev/null @@ -1,194 +0,0 @@ -import hashes, math - -type - TSlotEnum = enum seEmpty, seFilled, seDeleted - TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] - TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] - - TOrderedKeyValuePair[A, B] = tuple[ - slot: TSlotEnum, next: int, key: A, val: B] - TOrderedKeyValuePairSeq[A, B] = seq[TOrderedKeyValuePair[A, B]] - TOrderedTable*[A, B] = object ## table that remembers insertion order - data: TOrderedKeyValuePairSeq[A, B] - counter, first, last: int - -const - growthFactor = 2 - -proc mustRehash(length, counter: int): bool {.inline.} = - assert(length > counter) - result = (length * 2 < counter * 3) or (length - counter < 4) - -proc nextTry(h, maxHash: Hash): Hash {.inline.} = - result = ((5 * h) + 1) and maxHash - -template rawGetImpl() {.dirty.} = - var h: Hash = hash(key) and high(t.data) # start with real hash value - while t.data[h].slot != seEmpty: - if t.data[h].key == key and t.data[h].slot == seFilled: - return h - h = nextTry(h, high(t.data)) - result = -1 - -template rawInsertImpl() {.dirty.} = - var h: Hash = hash(key) and high(data) - while data[h].slot == seFilled: - h = nextTry(h, high(data)) - data[h].key = key - data[h].val = val - data[h].slot = seFilled - -template addImpl() {.dirty.} = - if mustRehash(len(t.data), t.counter): enlarge(t) - rawInsert(t, t.data, key, val) - inc(t.counter) - -template putImpl() {.dirty.} = - var index = rawGet(t, key) - if index >= 0: - t.data[index].val = val - else: - addImpl() - -proc len*[A, B](t: TOrderedTable[A, B]): int {.inline.} = - ## returns the number of keys in `t`. - result = t.counter - -template forAllOrderedPairs(yieldStmt: untyped) {.dirty.} = - var h = t.first - while h >= 0: - var nxt = t.data[h].next - if t.data[h].slot == seFilled: yieldStmt - h = nxt - -iterator pairs*[A, B](t: TOrderedTable[A, B]): tuple[key: A, val: B] = - ## iterates over any (key, value) pair in the table `t` in insertion - ## order. - forAllOrderedPairs: - yield (t.data[h].key, t.data[h].val) - -iterator mpairs*[A, B](t: var TOrderedTable[A, B]): tuple[key: A, val: var B] = - ## iterates over any (key, value) pair in the table `t` in insertion - ## order. The values can be modified. - forAllOrderedPairs: - yield (t.data[h].key, t.data[h].val) - -iterator keys*[A, B](t: TOrderedTable[A, B]): A = - ## iterates over any key in the table `t` in insertion order. - forAllOrderedPairs: - yield t.data[h].key - -iterator values*[A, B](t: TOrderedTable[A, B]): B = - ## iterates over any value in the table `t` in insertion order. - forAllOrderedPairs: - yield t.data[h].val - -iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B = - ## iterates over any value in the table `t` in insertion order. The values - ## can be modified. - forAllOrderedPairs: - yield t.data[h].val - -proc rawGet[A, B](t: TOrderedTable[A, B], key: A): int = - rawGetImpl() - -proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = - ## retrieves the value at ``t[key]``. If `key` is not in `t`, - ## default empty value for the type `B` is returned - ## and no exception is raised. One can check with ``hasKey`` whether the key - ## exists. - var index = rawGet(t, key) - if index >= 0: result = t.data[index].val - -proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = - ## retrieves the value at ``t[key]``. The value can be modified. - ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. - var index = rawGet(t, key) - if index >= 0: result = t.data[index].val - else: raise newException(KeyError, "key not found: " & $key) - -proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool = - ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 - -proc rawInsert[A, B](t: var TOrderedTable[A, B], - data: var TOrderedKeyValuePairSeq[A, B], - key: A, val: B) = - rawInsertImpl() - data[h].next = -1 - if t.first < 0: t.first = h - if t.last >= 0: data[t.last].next = h - t.last = h - -proc enlarge[A, B](t: var TOrderedTable[A, B]) = - var n: TOrderedKeyValuePairSeq[A, B] - newSeq(n, len(t.data) * growthFactor) - var h = t.first - t.first = -1 - t.last = -1 - while h >= 0: - var nxt = t.data[h].next - if t.data[h].slot == seFilled: - rawInsert(t, n, t.data[h].key, t.data[h].val) - h = nxt - swap(t.data, n) - -proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = - ## puts a (key, value)-pair into `t`. - putImpl() - -proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = - ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. - addImpl() - -proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = - ## creates a new ordered hash table that is empty. `initialSize` needs to be - ## a power of two. - assert isPowerOfTwo(initialSize) - result.counter = 0 - result.first = -1 - result.last = -1 - newSeq(result.data, initialSize) - -proc toOrderedTable*[A, B](pairs: openarray[tuple[key: A, - val: B]]): TOrderedTable[A, B] = - ## creates a new ordered hash table that contains the given `pairs`. - result = initOrderedTable[A, B](nextPowerOfTwo(pairs.len+10)) - for key, val in items(pairs): result[key] = val - -proc sort*[A, B](t: var TOrderedTable[A,B], - cmp: proc (x, y: tuple[key: A, val: B]): int {.closure.}) = - ## sorts the ordered table so that the entry with the highest counter comes - ## first. This is destructive (with the advantage of being efficient)! - ## You must not modify `t` afterwards! - ## You can use the iterators `pairs`, `keys`, and `values` to iterate over - ## `t` in the sorted order. - - # we use shellsort here; fast enough and simple - var h = 1 - while true: - h = 3 * h + 1 - if h >= high(t.data): break - while true: - h = h div 3 - for i in countup(h, high(t.data)): - var j = i - #echo(t.data.len, " ", j, " - ", h) - #echo(repr(t.data[j-h])) - proc rawCmp(x, y: TOrderedKeyValuePair[A, B]): int = - if x.slot in {seEmpty, seDeleted} and y.slot in {seEmpty, seDeleted}: - return 0 - elif x.slot in {seEmpty, seDeleted}: - return -1 - elif y.slot in {seEmpty, seDeleted}: - return 1 - else: - let item1 = (x.key, x.val) - let item2 = (y.key, y.val) - return cmp(item1, item2) - - while rawCmp(t.data[j-h], t.data[j]) <= 0: - swap(t.data[j], t.data[j-h]) - j = j-h - if j < h: break - if h == 1: break diff --git a/tests/closure/tclosureinference3304.nim b/tests/closure/tclosureinference3304.nim deleted file mode 100644 index db4aa1d04d415..0000000000000 --- a/tests/closure/tclosureinference3304.nim +++ /dev/null @@ -1,15 +0,0 @@ -discard """ - output: '''@[1, 2, 5]''' -""" - -import future, sequtils - -type - List[T] = ref object - val: T - -proc foo[T](l: List[T]): seq[int] = - @[1,2,3,5].filter(x => x != l.val) - -when isMainModule: - echo(foo(List[int](val: 3))) diff --git a/tests/closure/tcodegenerr1923.nim b/tests/closure/tcodegenerr1923.nim deleted file mode 100644 index ee131ae159c2e..0000000000000 --- a/tests/closure/tcodegenerr1923.nim +++ /dev/null @@ -1,9 +0,0 @@ -type - Foo[M] = proc() : M - -proc bar[M](f : Foo[M]) = - discard f() - -proc baz() : int = 42 - -bar(baz) \ No newline at end of file diff --git a/tests/closure/tdeeplynested.nim b/tests/closure/tdeeplynested.nim deleted file mode 100644 index ddf4fa6a49d6b..0000000000000 --- a/tests/closure/tdeeplynested.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: '''int: 108''' -""" - -# bug #4070 - -proc id(f: (proc())): auto = - return f - -proc foo(myinteger: int): (iterator(): int) = - return iterator(): int {.closure.} = - proc bar() = - proc kk() = - echo "int: ", myinteger - - kk() - - id(bar)() - -discard foo(108)() diff --git a/tests/closure/tdonotation.nim b/tests/closure/tdonotation.nim deleted file mode 100644 index cc4f46bab85f3..0000000000000 --- a/tests/closure/tdonotation.nim +++ /dev/null @@ -1,50 +0,0 @@ -discard """ -output: ''' -click at 10,20 -lost focus 1 -lost focus 2 -registered handler for UserEvent 1 -registered handler for UserEvent 2 -registered handler for UserEvent 3 -registered handler for UserEvent 4 -''' -""" - -import future - -type - Button = object - Event = object - x, y: int - -proc onClick(x: Button, handler: proc(x: Event)) = - handler(Event(x: 10, y: 20)) - -proc onFocusLost(x: Button, handler: proc()) = - handler() - -proc onUserEvent(x: Button, eventName: string, handler: proc) = - echo "registered handler for ", eventName - -var b = Button() - -b.onClick do (e: Event): - echo "click at ", e.x, ",", e.y - -b.onFocusLost: - echo "lost focus 1" - -b.onFocusLost do: - echo "lost focus 2" - -b.onUserEvent("UserEvent 1") do: - discard - -b.onUserEvent "UserEvent 2": - discard - -b.onUserEvent("UserEvent 3"): - discard - -b.onUserEvent("UserEvent 4", () => echo "event 4") - diff --git a/tests/closure/tfib50.nim b/tests/closure/tfib50.nim deleted file mode 100644 index 719aa3ad540e8..0000000000000 --- a/tests/closure/tfib50.nim +++ /dev/null @@ -1,22 +0,0 @@ -discard """ - output: "20365011074" -""" - -import tables - -proc memoize(f: proc (a: int64): int64): proc (a: int64): int64 = - var previous = initTable[int64, int64]() - return proc(i: int64): int64 = - if not previous.hasKey i: - previous[i] = f(i) - return previous[i] - -var fib: proc(a: int64): int64 - -fib = memoize(proc (i: int64): int64 = - if i == 0 or i == 1: - return 1 - return fib(i-1) + fib(i-2) -) - -echo fib(50) diff --git a/tests/closure/tflatmap.nim b/tests/closure/tflatmap.nim deleted file mode 100644 index 240756424bee2..0000000000000 --- a/tests/closure/tflatmap.nim +++ /dev/null @@ -1,24 +0,0 @@ - -# bug #3995 - -import future - -type - RNG* = tuple[] - Rand*[A] = (RNG) -> (A, RNG) - -proc nextInt*(r: RNG): (int, RNG) = - (1, ()) - -proc flatMap[A,B](f: Rand[A], g: A -> Rand[B]): Rand[B] = - (rng: RNG) => ( - let (a, rng2) = f(rng); - let g1 = g(a); - g1(rng2) - ) - -proc map[A,B](s: Rand[A], f: A -> B): Rand[B] = - let g: A -> Rand[B] = (a: A) => ((rng: RNG) => (f(a), rng)) - flatMap(s, g) - -let f = nextInt.map(i => i - i mod 2) diff --git a/tests/closure/tforum.nim b/tests/closure/tforum.nim deleted file mode 100644 index 4f6a16ff7f557..0000000000000 --- a/tests/closure/tforum.nim +++ /dev/null @@ -1,44 +0,0 @@ -discard """ - output: '''asdas -processClient end -false -''' -""" - -type - PAsyncHttpServer = ref object - value: string - PFutureBase = ref object - callback: proc () {.closure.} - value: string - failed: bool - -proc accept(server: PAsyncHttpServer): PFutureBase = - new(result) - result.callback = proc () = - discard - server.value = "hahaha" - -proc processClient(): PFutureBase = - new(result) - -proc serve(server: PAsyncHttpServer): PFutureBase = - iterator serveIter(): PFutureBase {.closure.} = - echo server.value - while true: - var acceptAddrFut = server.accept() - yield acceptAddrFut - var fut = acceptAddrFut.value - - var f = processClient() - f.callback = - proc () = - echo("processClient end") - echo(f.failed) - yield f - var x = serveIter - for i in 0 .. 1: - result = x() - result.callback() - -discard serve(PAsyncHttpServer(value: "asdas")) diff --git a/tests/closure/tfutclosure2138.nim b/tests/closure/tfutclosure2138.nim deleted file mode 100644 index e188340740775..0000000000000 --- a/tests/closure/tfutclosure2138.nim +++ /dev/null @@ -1,10 +0,0 @@ -import future, sequtils - -proc any[T](list: varargs[T], pred: (T) -> bool): bool = - for item in list: - if pred(item): - result = true - break - -proc contains(s: string, words: varargs[string]): bool = - any(words, (word) => s.contains(word)) \ No newline at end of file diff --git a/tests/closure/tinterf.nim b/tests/closure/tinterf.nim deleted file mode 100644 index 1ac6da9452788..0000000000000 --- a/tests/closure/tinterf.nim +++ /dev/null @@ -1,24 +0,0 @@ -discard """ - output: '''56 66''' -""" - -type - ITest = tuple[ - setter: proc(v: int) {.closure.}, - getter1: proc(): int {.closure.}, - getter2: proc(): int {.closure.}] - -proc getInterf(): ITest = - var shared1, shared2: int - - return (setter: proc (x: int) = - shared1 = x - shared2 = x + 10, - getter1: proc (): int = result = shared1, - getter2: proc (): int = return shared2) - -var i = getInterf() -i.setter(56) - -echo i.getter1(), " ", i.getter2() - diff --git a/tests/closure/tissue1502def.nim b/tests/closure/tissue1502def.nim deleted file mode 100644 index 0aa6b16e3b9d6..0000000000000 --- a/tests/closure/tissue1502def.nim +++ /dev/null @@ -1,6 +0,0 @@ -import sequtils -let xs: seq[tuple[key: string, val: seq[string]]] = @[("foo", @["bar"])] - -let maps = xs.map( - proc(x: auto): tuple[typ: string, maps: seq[string]] = - (x.key, x.val.map(proc(x: string): string = x))) \ No newline at end of file diff --git a/tests/closure/tissue1642.nim b/tests/closure/tissue1642.nim deleted file mode 100644 index 5b921fc05d565..0000000000000 --- a/tests/closure/tissue1642.nim +++ /dev/null @@ -1,3 +0,0 @@ -block: - var i = 0 - proc p() = inc(i) \ No newline at end of file diff --git a/tests/closure/tissue1846.nim b/tests/closure/tissue1846.nim deleted file mode 100644 index 3fbef169d23db..0000000000000 --- a/tests/closure/tissue1846.nim +++ /dev/null @@ -1,16 +0,0 @@ -type - TBinOp*[T] = proc (x,y: T): bool - - THeap*[T] = object - cmp*: TBinOp[T] - -proc less*[T](x,y: T): bool = - x < y - -proc initHeap*[T](cmp: TBinOp[T]): THeap[T] = - result.cmp = cmp - -when isMainModule: - var h = initHeap[int](less[int]) - - echo h.cmp(2,3) \ No newline at end of file diff --git a/tests/closure/tissue1911.nim b/tests/closure/tissue1911.nim deleted file mode 100644 index 311d991349536..0000000000000 --- a/tests/closure/tissue1911.nim +++ /dev/null @@ -1,7 +0,0 @@ -proc foo(x: int) : auto = - - proc helper() : int = x - proc bar() : int = helper() - proc baz() : int = helper() - - return (bar, baz) \ No newline at end of file diff --git a/tests/closure/tissue600.nim b/tests/closure/tissue600.nim deleted file mode 100644 index eacc7a1235100..0000000000000 --- a/tests/closure/tissue600.nim +++ /dev/null @@ -1,4 +0,0 @@ -for i in 1..1: - var reported = false - proc report() = - reported = true \ No newline at end of file diff --git a/tests/closure/tissues.nim b/tests/closure/tissues.nim new file mode 100644 index 0000000000000..d33e3b4035092 --- /dev/null +++ b/tests/closure/tissues.nim @@ -0,0 +1,55 @@ +discard """ + file: "tissues.nim" + output: '''true''' +""" + + +block tissue600: + for i in 1..1: + var reported = false + proc report() = + reported = true + + + +import sequtils +block tissue1502def: + let xs: seq[tuple[key: string, val: seq[string]]] = @[("foo", @["bar"])] + + let maps = xs.map( + proc(x: auto): tuple[typ: string, maps: seq[string]] = + (x.key, x.val.map(proc(x: string): string = x))) + + + +block tissue1642: + var i = 0 + proc p() = inc(i) + + + +block tissue1846: + type + TBinOp[T] = proc (x,y: T): bool + THeap[T] = object + cmp: TBinOp[T] + + proc less[T](x,y: T): bool = + x < y + + proc initHeap[T](cmp: TBinOp[T]): THeap[T] = + result.cmp = cmp + + var h = initHeap[int](less[int]) + echo h.cmp(2,3) + + + +block tissue1911: + proc foo(x: int) : auto = + + proc helper() : int = x + proc bar() : int = helper() + proc baz() : int = helper() + + return (bar, baz) diff --git a/tests/closure/tjester.nim b/tests/closure/tjester.nim deleted file mode 100644 index 84e0fcb71de97..0000000000000 --- a/tests/closure/tjester.nim +++ /dev/null @@ -1,32 +0,0 @@ -discard """ - output: '''baro0''' -""" - -type - Future[T] = ref object - data: T - callback: proc () {.closure.} - -proc cbOuter(response: string) {.discardable.} = - iterator cbIter(): Future[int] {.closure.} = - for i in 0..7: - proc foo(): int = - iterator fooIter(): Future[int] {.closure.} = - echo response, i - yield Future[int](data: 17) - var iterVar = fooIter - iterVar().data - yield Future[int](data: foo()) - - var iterVar2 = cbIter - proc cb2() {.closure.} = - try: - if not finished(iterVar2): - let next = iterVar2() - if next != nil: - next.callback = cb2 - except: - echo "WTF" - cb2() - -cbOuter "baro" diff --git a/tests/closure/tnamedparamanonproc.nim b/tests/closure/tnamedparamanonproc.nim deleted file mode 100644 index 94e32894f3e88..0000000000000 --- a/tests/closure/tnamedparamanonproc.nim +++ /dev/null @@ -1,14 +0,0 @@ - -type - PButton = ref object - TButtonClicked = proc(button: PButton) {.nimcall.} - -proc newButton*(onClick: TButtonClicked) = - discard - -proc main() = - newButton(onClick = proc(b: PButton) = - var requestomat = 12 - ) - -main() diff --git a/tests/closure/tnested.nim b/tests/closure/tnested.nim new file mode 100644 index 0000000000000..f8d69011adc9d --- /dev/null +++ b/tests/closure/tnested.nim @@ -0,0 +1,180 @@ +discard """ + file: "tnested.nim" + output: ''' +foo88 +23 24foo 88 +foo88 +23 24foo 88 +11 +int: 108 +0 +11 +1 +11 +2 +11 +3 +11 +4 +11 +5 +11 +6 +11 +7 +11 +8 +11 +9 +11 +11 +py +py +py +py +px +6 +''' +""" + + +block tnestedclosure: + proc main(param: int) = + var foo = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo foo, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + + # test simple closure within dummy 'main': + proc dummy = + proc main2(param: int) = + var fooB = 23 + proc outer(outerParam: string) = + var outerVar = 88 + echo outerParam, outerVar + proc inner() = + block Test: + echo fooB, " ", param, outerParam, " ", outerVar + inner() + outer("foo") + main2(24) + + dummy() + + main(24) + + # Jester + async triggered this bug: + proc cbOuter() = + var response = "hohoho" + block: + proc cbIter() = + block: + proc fooIter() = + doAssert response == "hohoho" + fooIter() + cbIter() + cbOuter() + + +block tnestedproc: + proc p(x, y: int): int = + result = x + y + + echo p((proc (): int = + var x = 7 + return x)(), + (proc (): int = return 4)()) + + +block deeplynested: + # bug #4070 + proc id(f: (proc())): auto = + return f + + proc foo(myinteger: int): (iterator(): int) = + return iterator(): int {.closure.} = + proc bar() = + proc kk() = + echo "int: ", myinteger + kk() + id(bar)() + + discard foo(108)() + + +block tclosure2: + when true: + proc ax = + for xxxx in 0..9: + var i = 0 + proc bx = + if i > 10: + echo xxxx + return + i += 1 + #for j in 0 .. 0: echo i + bx() + + bx() + echo i + + ax() + + when true: + proc accumulator(start: int): (proc(): int {.closure.}) = + var x = start-1 + #let dummy = proc = + # discard start + + result = proc (): int = + #var x = 9 + for i in 0 .. 0: x = x + 1 + + return x + + var a = accumulator(3) + let b = accumulator(4) + echo a() + b() + a() + + + proc outer = + + proc py() = + # no closure here: + for i in 0..3: echo "py" + + py() + + outer() + + + when true: + proc outer2 = + var errorValue = 3 + proc fac[T](n: T): T = + if n < 0: result = errorValue + elif n <= 1: result = 1 + else: result = n * fac(n-1) + + proc px() {.closure.} = + echo "px" + + proc py() {.closure.} = + echo "py" + + let + mapping = { + "abc": px, + "xyz": py + } + mapping[0][1]() + + echo fac(3) + + + outer2() diff --git a/tests/closure/tnestedclosure.nim b/tests/closure/tnestedclosure.nim deleted file mode 100644 index 0628a6977efcf..0000000000000 --- a/tests/closure/tnestedclosure.nim +++ /dev/null @@ -1,51 +0,0 @@ -discard """ - output: '''foo88 -23 24foo 88 -foo88 -23 24foo 88 -hohoho''' -""" - -# test nested closure -proc main(param: int) = - var foo = 23 - proc outer(outerParam: string) = - var outerVar = 88 - echo outerParam, outerVar - proc inner() = - block Test: - echo foo, " ", param, outerParam, " ", outerVar - inner() - outer("foo") - -# test simple closure within dummy 'main': -proc dummy = - proc main2(param: int) = - var fooB = 23 - proc outer(outerParam: string) = - var outerVar = 88 - echo outerParam, outerVar - proc inner() = - block Test: - echo fooB, " ", param, outerParam, " ", outerVar - inner() - outer("foo") - main2(24) - -dummy() - -main(24) - -# Jester + async triggered this bug: -proc cbOuter() = - var response = "hohoho" - block: - proc cbIter() = - block: - proc fooIter() = - echo response - fooIter() - - cbIter() - -cbOuter() diff --git a/tests/closure/tnestedproc.nim b/tests/closure/tnestedproc.nim deleted file mode 100644 index 7eeeff1988c60..0000000000000 --- a/tests/closure/tnestedproc.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: "11" -""" - -proc p(x, y: int): int = - result = x + y - -echo p((proc (): int = - var x = 7 - return x)(), - (proc (): int = return 4)()) - diff --git a/tests/closure/tnoclosure.nim b/tests/closure/tnoclosure.nim deleted file mode 100644 index 25cce004036f6..0000000000000 --- a/tests/closure/tnoclosure.nim +++ /dev/null @@ -1,25 +0,0 @@ -discard """ - output: '''@[1] -@[1, 1] -@[1, 2, 1] -@[1, 3, 3, 1] -@[1, 4, 6, 4, 1] -@[1, 5, 10, 10, 5, 1] -@[1, 6, 15, 20, 15, 6, 1] -@[1, 7, 21, 35, 35, 21, 7, 1] -@[1, 8, 28, 56, 70, 56, 28, 8, 1] -@[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]''' -""" - -import sequtils - -proc pascal(n: int) = - var row = @[1] - for r in 1..n: - echo row - row = zip(row & @[0], @[0] & row).mapIt(it[0] + it[1]) - -pascal(10) - -# bug #3499 last snippet fixed -# bug 705 last snippet fixed diff --git a/tests/cnstseq/t2656.nim b/tests/cnstseq/t2656.nim deleted file mode 100644 index c6ff182f3674e..0000000000000 --- a/tests/cnstseq/t2656.nim +++ /dev/null @@ -1,35 +0,0 @@ -discard """ - output: ''' -onetwothree -onetwothree -onetwothree -one1two2three3 -''' -""" - -iterator it1(args: seq[string]): string = - for s in args: yield s -iterator it2(args: seq[string]): string {.closure.} = - for s in args: yield s -iterator it3(args: openArray[string]): string {.closure.} = - for s in args: yield s -iterator it4(args: openArray[(string, string)]): string {.closure.} = - for s1, s2 in items(args): yield s1 & s2 - -block: - const myConstSeq = @["one", "two", "three"] - for s in it1(myConstSeq): - stdout.write s - echo "" - for s in it2(myConstSeq): - stdout.write s - echo "" - for s in it3(myConstSeq): - stdout.write s - echo "" - -block: - const myConstSeq = @[("one", "1"), ("two", "2"), ("three", "3")] - for s in it4(myConstSeq): - stdout.write s - echo "" diff --git a/tests/cnstseq/tcnstseq.nim b/tests/cnstseq/tcnstseq.nim index ad0527f10f1f7..e044b9f3fae5d 100644 --- a/tests/cnstseq/tcnstseq.nim +++ b/tests/cnstseq/tcnstseq.nim @@ -1,17 +1,69 @@ discard """ file: "tcnstseq.nim" - output: "AngelikaAnneAnnaAnkaAnja" + output: ''' +AngelikaAnneAnnaAnkaAnja +AngelikaAnneAnnaAnkaAnja +AngelikaAnneAnnaAnkaAnja +onetwothree +onetwothree +onetwothree +one1two2three3 +''' """ # Test the new implicit conversion from sequences to arrays in a constant # context. import strutils -const - myWords = "Angelika Anne Anna Anka Anja".split() -for x in items(myWords): - write(stdout, x) #OUT AngelikaAnneAnnaAnkaAnja +block t1: + const + myWords = "Angelika Anne Anna Anka Anja".split() + for x in items(myWords): + write(stdout, x) #OUT AngelikaAnneAnnaAnkaAnja + echo "" +block t2: + const + myWords = @["Angelika", "Anne", "Anna", "Anka", "Anja"] + + for i in 0 .. high(myWords): + write(stdout, myWords[i]) #OUT AngelikaAnneAnnaAnkaAnja + echo "" + + +block t3: + for w in items(["Angelika", "Anne", "Anna", "Anka", "Anja"]): + write(stdout, w) #OUT AngelikaAnneAnnaAnkaAnja + echo "" + + +block t2656: + iterator it1(args: seq[string]): string = + for s in args: yield s + iterator it2(args: seq[string]): string {.closure.} = + for s in args: yield s + iterator it3(args: openArray[string]): string {.closure.} = + for s in args: yield s + iterator it4(args: openArray[(string, string)]): string {.closure.} = + for s1, s2 in items(args): yield s1 & s2 + + block: + const myConstSeq = @["one", "two", "three"] + for s in it1(myConstSeq): + stdout.write s + echo "" + for s in it2(myConstSeq): + stdout.write s + echo "" + for s in it3(myConstSeq): + stdout.write s + echo "" + + block: + const myConstSeq = @[("one", "1"), ("two", "2"), ("three", "3")] + for s in it4(myConstSeq): + stdout.write s + echo "" diff --git a/tests/cnstseq/tcnstseq2.nim b/tests/cnstseq/tcnstseq2.nim deleted file mode 100644 index 2f364d27841ae..0000000000000 --- a/tests/cnstseq/tcnstseq2.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: "AngelikaAnneAnnaAnkaAnja" -""" - -const - myWords = @["Angelika", "Anne", "Anna", "Anka", "Anja"] - -for i in 0 .. high(myWords): - write(stdout, myWords[i]) #OUT AngelikaAnneAnnaAnkaAnja - - - diff --git a/tests/cnstseq/tcnstseq3.nim b/tests/cnstseq/tcnstseq3.nim deleted file mode 100644 index e59516e85e114..0000000000000 --- a/tests/cnstseq/tcnstseq3.nim +++ /dev/null @@ -1,7 +0,0 @@ -discard """ - output: "AngelikaAnneAnnaAnkaAnja" -""" - -for w in items(["Angelika", "Anne", "Anna", "Anka", "Anja"]): - write(stdout, w) #OUT AngelikaAnneAnnaAnkaAnja - diff --git a/tests/collections/tableadds.nim b/tests/collections/tableadds.nim deleted file mode 100644 index 71f1fad7d853a..0000000000000 --- a/tests/collections/tableadds.nim +++ /dev/null @@ -1,13 +0,0 @@ -discard """ - output: '''done''' -""" - -import tables - -proc main = - var tab = newTable[string, string]() - for i in 0..1000: - tab.add "key", "value " & $i - -main() -echo "done" diff --git a/tests/collections/tapply.nim b/tests/collections/tapply.nim deleted file mode 100644 index 2b7464216a221..0000000000000 --- a/tests/collections/tapply.nim +++ /dev/null @@ -1,11 +0,0 @@ -discard """ - output: '''true''' -""" - -import sequtils - -var x = @[1, 2, 3] -x.apply(proc(x: var int) = x = x+10) -x.apply(proc(x: int): int = x+100) -x.applyIt(it+5000) -echo x == @[5111, 5112, 5113] diff --git a/tests/collections/tcollections.nim b/tests/collections/tcollections.nim new file mode 100644 index 0000000000000..ff6673bba3361 --- /dev/null +++ b/tests/collections/tcollections.nim @@ -0,0 +1,56 @@ +discard """ + file: "tcollections.nim" + output: ''' +''' +""" + +import deques, sequtils + + +block tapply: + var x = @[1, 2, 3] + x.apply(proc(x: var int) = x = x+10) + x.apply(proc(x: int): int = x+100) + x.applyIt(it+5000) + doAssert x == @[5111, 5112, 5113] + + +block tdeques: + proc index(self: Deque[int], idx: Natural): int = + self[idx] + + proc main = + var testDeque = initDeque[int]() + testDeque.addFirst(1) + assert testDeque.index(0) == 1 + + main() + + +block tmapit: + var x = @[1, 2, 3] + # This mapIt call will run with preallocation because ``len`` is available. + var y = x.mapIt($(it+10)) + doAssert y == @["11", "12", "13"] + + type structureWithoutLen = object + a: array[5, int] + + iterator items(s: structureWithoutLen): int {.inline.} = + yield s.a[0] + yield s.a[1] + yield s.a[2] + yield s.a[3] + yield s.a[4] + + var st: structureWithoutLen + st.a[0] = 0 + st.a[1] = 1 + st.a[2] = 2 + st.a[3] = 3 + st.a[4] = 4 + + # this will run without preallocating the result + # since ``len`` is not available + var r = st.mapIt($(it+10)) + doAssert r == @["10", "11", "12", "13", "14"] diff --git a/tests/collections/tcounttable.nim b/tests/collections/tcounttable.nim deleted file mode 100644 index ebbb1c8e511c1..0000000000000 --- a/tests/collections/tcounttable.nim +++ /dev/null @@ -1,19 +0,0 @@ -discard """ - output: "And we get here" -""" - -# bug #2625 - -const s_len = 32 - -import tables -var substr_counts: CountTable[string] = initCountTable[string]() -var my_string = "Hello, this is sadly broken for strings over 64 characters. Note that it *does* appear to work for short strings." -for i in 0..(my_string.len - s_len): - let s = my_string[i..i+s_len-1] - substr_counts[s] = 1 - # substr_counts[s] = substr_counts[s] + 1 # Also breaks, + 2 as well, etc. - # substr_counts.inc(s) # This works - #echo "Iteration ", i - -echo "And we get here" diff --git a/tests/collections/tdeques.nim b/tests/collections/tdeques.nim deleted file mode 100644 index 664ce4324038b..0000000000000 --- a/tests/collections/tdeques.nim +++ /dev/null @@ -1,17 +0,0 @@ -discard """ - output: '''true''' -""" - -import deques - - -proc index(self: Deque[int], idx: Natural): int = - self[idx] - -proc main = - var testDeque = initDeque[int]() - testDeque.addFirst(1) - assert testDeque.index(0) == 1 - -main() -echo "true" diff --git a/tests/collections/thashes.nim b/tests/collections/thashes.nim deleted file mode 100644 index 5cc3cc8bb6c11..0000000000000 --- a/tests/collections/thashes.nim +++ /dev/null @@ -1,90 +0,0 @@ -discard """ - output: '''true''' -""" - -import tables -from hashes import Hash - -# Test with int -block: - var t = initTable[int,int]() - t[0] = 42 - t[1] = t[0] + 1 - assert(t[0] == 42) - assert(t[1] == 43) - let t2 = {1: 1, 2: 2}.toTable - assert(t2[2] == 2) - -# Test with char -block: - var t = initTable[char,int]() - t['0'] = 42 - t['1'] = t['0'] + 1 - assert(t['0'] == 42) - assert(t['1'] == 43) - let t2 = {'1': 1, '2': 2}.toTable - assert(t2['2'] == 2) - -# Test with enum -block: - type - E = enum eA, eB, eC - var t = initTable[E,int]() - t[eA] = 42 - t[eB] = t[eA] + 1 - assert(t[eA] == 42) - assert(t[eB] == 43) - let t2 = {eA: 1, eB: 2}.toTable - assert(t2[eB] == 2) - -# Test with range -block: - type - R = range[1..10] - var t = initTable[R,int]() # causes warning, why? - t[1] = 42 # causes warning, why? - t[2] = t[1] + 1 - assert(t[1] == 42) - assert(t[2] == 43) - let t2 = {1.R: 1, 2.R: 2}.toTable - assert(t2[2.R] == 2) - -# Test which combines the generics for tuples + ordinals -block: - type - E = enum eA, eB, eC - var t = initTable[(string, E, int, char), int]() - t[("a", eA, 0, '0')] = 42 - t[("b", eB, 1, '1')] = t[("a", eA, 0, '0')] + 1 - assert(t[("a", eA, 0, '0')] == 42) - assert(t[("b", eB, 1, '1')] == 43) - let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable - assert(t2[("b", eB, 1, '1')] == 2) - -# Test to check if overloading is possible -# Unfortunately, this does not seem to work for int -# The same test with a custom hash(s: string) does -# work though. -block: - proc hash(x: int): Hash {.inline.} = - echo "overloaded hash" - result = x - var t = initTable[int, int]() - t[0] = 0 - -# Check hashability of all integer types (issue #5429) -block: - let intTables = ( - newTable[int, string](), - newTable[int8, string](), - newTable[int16, string](), - newTable[int32, string](), - newTable[int64, string](), - newTable[uint, string](), - newTable[uint8, string](), - newTable[uint16, string](), - newTable[uint32, string](), - newTable[uint64, string](), - ) - -echo "true" diff --git a/tests/collections/tindexby.nim b/tests/collections/tindexby.nim deleted file mode 100644 index 88c0b263e984e..0000000000000 --- a/tests/collections/tindexby.nim +++ /dev/null @@ -1,22 +0,0 @@ -import tables - -doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table" - -var tbl1 = initTable[int, int]() -tbl1.add(1,1) -tbl1.add(2,2) -doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table" - -type - TElem = object - foo: int - bar: string - -let - elem1 = TElem(foo: 1, bar: "bar") - elem2 = TElem(foo: 2, bar: "baz") - -var tbl2 = initTable[string, TElem]() -tbl2.add("bar", elem1) -tbl2.add("baz", elem2) -doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table" diff --git a/tests/collections/tmapit.nim b/tests/collections/tmapit.nim deleted file mode 100644 index b2afa942954ad..0000000000000 --- a/tests/collections/tmapit.nim +++ /dev/null @@ -1,33 +0,0 @@ -discard """ - output: '''true -true''' -""" - -import sequtils - -var x = @[1, 2, 3] -# This mapIt call will run with preallocation because ``len`` is available. -var y = x.mapIt($(it+10)) -echo y == @["11", "12", "13"] - -type structureWithoutLen = object - a: array[5, int] - -iterator items(s: structureWithoutLen): int {.inline.} = - yield s.a[0] - yield s.a[1] - yield s.a[2] - yield s.a[3] - yield s.a[4] - -var st: structureWithoutLen -st.a[0] = 0 -st.a[1] = 1 -st.a[2] = 2 -st.a[3] = 3 -st.a[4] = 4 - -# this will run without preallocating the result -# since ``len`` is not available -var r = st.mapIt($(it+10)) -echo r == @["10", "11", "12", "13", "14"] diff --git a/tests/collections/tsets.nim b/tests/collections/tsets.nim index 61e14260af0ef..cd44015113627 100644 --- a/tests/collections/tsets.nim +++ b/tests/collections/tsets.nim @@ -1,6 +1,5 @@ -import sets -import hashes -import algorithm +import sets, hashes, algorithm + block setEquality: var diff --git a/tests/collections/ttableconstr.nim b/tests/collections/ttableconstr.nim deleted file mode 100644 index 884378a760ffb..0000000000000 --- a/tests/collections/ttableconstr.nim +++ /dev/null @@ -1,16 +0,0 @@ -# Test if the new table constructor syntax works: - -template ignoreExpr(e) = - discard - -# test first class '..' syntactical citizen: -ignoreExpr x <> 2..4 -# test table constructor: -ignoreExpr({:}) -ignoreExpr({2: 3, "key": "value"}) - -# NEW: -assert 56 in 50..100 - -assert 56 in ..60 - diff --git a/tests/collections/ttables.nim b/tests/collections/ttables.nim index 7fe4c79b13474..cb31a86529df7 100644 --- a/tests/collections/ttables.nim +++ b/tests/collections/ttables.nim @@ -1,275 +1,375 @@ discard """ - cmd: "nim c --threads:on $file" - output: '''true''' + file: "ttables.nim" + output: ''' +done +And we get here +true +true +true +true +''' """ - -import hashes, tables, sharedtables - -const - data = { - "34": 123456, "12": 789, - "90": 343, "0": 34404, - "1": 344004, "2": 344774, - "3": 342244, "4": 3412344, - "5": 341232144, "6": 34214544, - "7": 3434544, "8": 344544, - "9": 34435644, "---00": 346677844, - "10": 34484, "11": 34474, "19": 34464, - "20": 34454, "30": 34141244, "40": 344114, - "50": 344490, "60": 344491, "70": 344492, - "80": 344497} - - sorteddata = { - "---00": 346677844, - "0": 34404, - "1": 344004, - "10": 34484, - "11": 34474, - "12": 789, - "19": 34464, - "2": 344774, "20": 34454, - "3": 342244, "30": 34141244, - "34": 123456, - "4": 3412344, "40": 344114, - "5": 341232144, "50": 344490, - "6": 34214544, "60": 344491, - "7": 3434544, "70": 344492, - "8": 344544, "80": 344497, - "9": 34435644, - "90": 343} - -block tableTest1: - var t = initTable[tuple[x, y: int], string]() - t[(0,0)] = "00" - t[(1,0)] = "10" - t[(0,1)] = "01" - t[(1,1)] = "11" - for x in 0..1: - for y in 0..1: - assert t[(x,y)] == $x & $y - assert($t == - "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") - -block tableTest2: - var t = initTable[string, float]() - t["test"] = 1.2345 - t["111"] = 1.000043 - t["123"] = 1.23 - t.del("111") - - t["012"] = 67.9 - t["123"] = 1.5 # test overwriting - - assert t["123"] == 1.5 - try: - echo t["111"] # deleted - except KeyError: - discard - assert(not hasKey(t, "111")) - - assert "123" in t - assert("111" notin t) - - for key, val in items(data): t[key] = val.toFloat - for key, val in items(data): assert t[key] == val.toFloat - - assert(not t.hasKeyOrPut("456", 4.0)) # test absent key - assert t.hasKeyOrPut("012", 3.0) # test present key - var x = t.mgetOrPut("111", 1.5) # test absent key - x = x * 2 - assert x == 3.0 - x = t.mgetOrPut("test", 1.5) # test present key - x = x * 2 - assert x == 2 * 1.2345 - -block orderedTableTest1: - var t = initOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - var i = 0 - # `pairs` needs to yield in insertion order: - for key, val in pairs(t): - assert key == data[i][0] - assert val == data[i][1] - inc(i) - - for key, val in mpairs(t): val = 99 - for val in mvalues(t): assert val == 99 - -block orderedTableTest2: - var - s = initOrderedTable[string, int]() - t = initOrderedTable[string, int]() - assert s == t - for key, val in items(data): t[key] = val - assert s != t - for key, val in items(sorteddata): s[key] = val - assert s != t - t.clear() - assert s != t - for key, val in items(sorteddata): t[key] = val - assert s == t - -block countTableTest1: - var s = data.toTable - var t = initCountTable[string]() - - for k in s.keys: t.inc(k) - for k in t.keys: assert t[k] == 1 - t.inc("90", 3) - t.inc("12", 2) - t.inc("34", 1) - assert t.largest()[0] == "90" - - t.sort() - var i = 0 - for k, v in t.pairs: - case i - of 0: assert k == "90" and v == 4 - of 1: assert k == "12" and v == 3 - of 2: assert k == "34" and v == 2 - else: break - inc i - -block countTableTest2: - var - s = initCountTable[int]() - t = initCountTable[int]() - assert s == t - s.inc(1) - assert s != t - t.inc(2) - assert s != t - t.inc(1) - assert s != t - s.inc(2) - assert s == t - s.inc(1) - assert s != t - t.inc(1) - assert s == t - -block mpairsTableTest1: - var t = initTable[string, int]() - t["a"] = 1 - t["b"] = 2 - t["c"] = 3 - t["d"] = 4 - for k, v in t.mpairs: - if k == "a" or k == "c": - v = 9 - - for k, v in t.pairs: - if k == "a" or k == "c": - assert v == 9 - else: - assert v != 1 and v != 3 - -block SyntaxTest: - var x = toTable[int, string]({:}) - -block zeroHashKeysTest: - proc doZeroHashValueTest[T, K, V](t: T, nullHashKey: K, value: V) = - let initialLen = t.len - var testTable = t - testTable[nullHashKey] = value - assert testTable[nullHashKey] == value - assert testTable.len == initialLen + 1 - testTable.del(nullHashKey) - assert testTable.len == initialLen - - # with empty table - doZeroHashValueTest(toTable[int,int]({:}), 0, 42) - doZeroHashValueTest(toTable[string,int]({:}), "", 23) - doZeroHashValueTest(toOrderedTable[int,int]({:}), 0, 42) - doZeroHashValueTest(toOrderedTable[string,int]({:}), "", 23) - - # with non-empty table - doZeroHashValueTest(toTable[int,int]({1:2}), 0, 42) - doZeroHashValueTest(toTable[string,string]({"foo": "bar"}), "", "zero") - doZeroHashValueTest(toOrderedTable[int,int]({3:4}), 0, 42) - doZeroHashValueTest(toOrderedTable[string,string]({"egg": "sausage"}), - "", "spam") - -block clearTableTest: - var t = data.toTable - assert t.len() != 0 - t.clear() - assert t.len() == 0 - -block clearOrderedTableTest: - var t = data.toOrderedTable - assert t.len() != 0 - t.clear() - assert t.len() == 0 - -block clearCountTableTest: - var t = initCountTable[string]() - t.inc("90", 3) - t.inc("12", 2) - t.inc("34", 1) - assert t.len() != 0 - t.clear() - assert t.len() == 0 - -block withKeyTest: - var t: SharedTable[int, int] - t.init() - t.withKey(1) do (k: int, v: var int, pairExists: var bool): - assert(v == 0) - pairExists = true - v = 42 - assert(t.mget(1) == 42) - t.withKey(1) do (k: int, v: var int, pairExists: var bool): - assert(v == 42) - pairExists = false - try: - discard t.mget(1) - assert(false, "KeyError expected") - except KeyError: - discard - t.withKey(2) do (k: int, v: var int, pairExists: var bool): - pairExists = false - try: - discard t.mget(2) - assert(false, "KeyError expected") - except KeyError: +import hashes, sequtils, tables + + +block tableadds: + proc main = + var tab = newTable[string, string]() + for i in 0..1000: + tab.add "key", "value " & $i + + main() + echo "done" + + +block tcounttable: + # bug #2625 + const s_len = 32 + var substr_counts: CountTable[string] = initCountTable[string]() + var my_string = "Hello, this is sadly broken for strings over 64 characters. Note that it *does* appear to work for short strings." + for i in 0..(my_string.len - s_len): + let s = my_string[i..i+s_len-1] + substr_counts[s] = 1 + # substr_counts[s] = substr_counts[s] + 1 # Also breaks, + 2 as well, etc. + # substr_counts.inc(s) # This works + #echo "Iteration ", i + + echo "And we get here" + + +block thashes: + # Test with int + block: + var t = initTable[int,int]() + t[0] = 42 + t[1] = t[0] + 1 + assert(t[0] == 42) + assert(t[1] == 43) + let t2 = {1: 1, 2: 2}.toTable + assert(t2[2] == 2) + + # Test with char + block: + var t = initTable[char,int]() + t['0'] = 42 + t['1'] = t['0'] + 1 + assert(t['0'] == 42) + assert(t['1'] == 43) + let t2 = {'1': 1, '2': 2}.toTable + assert(t2['2'] == 2) + + # Test with enum + block: + type + E = enum eA, eB, eC + var t = initTable[E,int]() + t[eA] = 42 + t[eB] = t[eA] + 1 + assert(t[eA] == 42) + assert(t[eB] == 43) + let t2 = {eA: 1, eB: 2}.toTable + assert(t2[eB] == 2) + + # Test with range + block: + type + R = range[1..10] + var t = initTable[R,int]() # causes warning, why? + t[1] = 42 # causes warning, why? + t[2] = t[1] + 1 + assert(t[1] == 42) + assert(t[2] == 43) + let t2 = {1.R: 1, 2.R: 2}.toTable + assert(t2[2.R] == 2) + + # Test which combines the generics for tuples + ordinals + block: + type + E = enum eA, eB, eC + var t = initTable[(string, E, int, char), int]() + t[("a", eA, 0, '0')] = 42 + t[("b", eB, 1, '1')] = t[("a", eA, 0, '0')] + 1 + assert(t[("a", eA, 0, '0')] == 42) + assert(t[("b", eB, 1, '1')] == 43) + let t2 = {("a", eA, 0, '0'): 1, ("b", eB, 1, '1'): 2}.toTable + assert(t2[("b", eB, 1, '1')] == 2) + + # Test to check if overloading is possible + # Unfortunately, this does not seem to work for int + # The same test with a custom hash(s: string) does + # work though. + block: + proc hash(x: int): Hash {.inline.} = + echo "overloaded hash" + result = x + var t = initTable[int, int]() + t[0] = 0 + + # Check hashability of all integer types (issue #5429) + block: + let intTables = ( + newTable[int, string](), + newTable[int8, string](), + newTable[int16, string](), + newTable[int32, string](), + newTable[int64, string](), + newTable[uint, string](), + newTable[uint8, string](), + newTable[uint16, string](), + newTable[uint32, string](), + newTable[uint64, string](), + ) + + echo "true" + + +block tindexby: + doAssert indexBy(newSeq[int](), proc(x: int):int = x) == initTable[int, int](), "empty int table" + + var tbl1 = initTable[int, int]() + tbl1.add(1,1) + tbl1.add(2,2) + doAssert indexBy(@[1,2], proc(x: int):int = x) == tbl1, "int table" + + type + TElem = object + foo: int + bar: string + + let + elem1 = TElem(foo: 1, bar: "bar") + elem2 = TElem(foo: 2, bar: "baz") + + var tbl2 = initTable[string, TElem]() + tbl2.add("bar", elem1) + tbl2.add("baz", elem2) + doAssert indexBy(@[elem1,elem2], proc(x: TElem): string = x.bar) == tbl2, "element table" + + +block tableconstr: + # Test if the new table constructor syntax works: + + template ignoreExpr(e) = discard -block takeTest: - var t = initTable[string, int]() - t["key"] = 123 - - var val = 0 - assert(t.take("key", val)) - assert(val == 123) - - val = -1 - assert(not t.take("key", val)) - assert(val == -1) - - assert(not t.take("otherkey", val)) - assert(val == -1) - -proc orderedTableSortTest() = - var t = initOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) - var i = 0 - # `pairs` needs to yield in sorted order: - for key, val in pairs(t): - doAssert key == sorteddata[i][0] - doAssert val == sorteddata[i][1] - inc(i) - - # check that lookup still works: - for key, val in pairs(t): - doAssert val == t[key] - # check that insert still works: - t["newKeyHere"] = 80 - - -orderedTableSortTest() -echo "true" - + # test first class '..' syntactical citizen: + ignoreExpr x <> 2..4 + # test table constructor: + ignoreExpr({:}) + ignoreExpr({2: 3, "key": "value"}) + + # NEW: + assert 56 in 50..100 + + assert 56 in ..60 + + +block ttables2: + proc TestHashIntInt() = + var tab = initTable[int,int]() + for i in 1..1_000_000: + tab[i] = i + for i in 1..1_000_000: + var x = tab[i] + if x != i : echo "not found ", i + + proc run1() = # occupied Memory stays constant, but + for i in 1 .. 50: # aborts at run: 44 on win32 with 3.2GB with out of memory + TestHashIntInt() + + # bug #2107 + + var delTab = initTable[int,int](4) + + for i in 1..4: + delTab[i] = i + delTab.del(i) + delTab[5] = 5 + + + run1() + echo "true" + + +block tablesref: + const + data = { + "34": 123456, "12": 789, + "90": 343, "0": 34404, + "1": 344004, "2": 344774, + "3": 342244, "4": 3412344, + "5": 341232144, "6": 34214544, + "7": 3434544, "8": 344544, + "9": 34435644, "---00": 346677844, + "10": 34484, "11": 34474, "19": 34464, + "20": 34454, "30": 34141244, "40": 344114, + "50": 344490, "60": 344491, "70": 344492, + "80": 344497} + + sorteddata = { + "---00": 346677844, + "0": 34404, + "1": 344004, + "10": 34484, + "11": 34474, + "12": 789, + "19": 34464, + "2": 344774, "20": 34454, + "3": 342244, "30": 34141244, + "34": 123456, + "4": 3412344, "40": 344114, + "5": 341232144, "50": 344490, + "6": 34214544, "60": 344491, + "7": 3434544, "70": 344492, + "8": 344544, "80": 344497, + "9": 34435644, + "90": 343} + + block tableTest1: + var t = newTable[tuple[x, y: int], string]() + t[(0,0)] = "00" + t[(1,0)] = "10" + t[(0,1)] = "01" + t[(1,1)] = "11" + for x in 0..1: + for y in 0..1: + assert t[(x,y)] == $x & $y + assert($t == + "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") + + block tableTest2: + var t = newTable[string, float]() + t["test"] = 1.2345 + t["111"] = 1.000043 + t["123"] = 1.23 + t.del("111") + + t["012"] = 67.9 + t["123"] = 1.5 # test overwriting + + assert t["123"] == 1.5 + try: + echo t["111"] # deleted + except KeyError: + discard + assert(not hasKey(t, "111")) + assert "111" notin t + + for key, val in items(data): t[key] = val.toFloat + for key, val in items(data): assert t[key] == val.toFloat + + + block orderedTableTest1: + var t = newOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + for key, val in items(data): assert t[key] == val + var i = 0 + # `pairs` needs to yield in insertion order: + for key, val in pairs(t): + assert key == data[i][0] + assert val == data[i][1] + inc(i) + + for key, val in mpairs(t): val = 99 + for val in mvalues(t): assert val == 99 + + block countTableTest1: + var s = data.toTable + var t = newCountTable[string]() + for k in s.keys: t.inc(k) + for k in t.keys: assert t[k] == 1 + t.inc("90", 3) + t.inc("12", 2) + t.inc("34", 1) + assert t.largest()[0] == "90" + + t.sort() + var i = 0 + for k, v in t.pairs: + case i + of 0: assert k == "90" and v == 4 + of 1: assert k == "12" and v == 3 + of 2: assert k == "34" and v == 2 + else: break + inc i + + block SyntaxTest: + var x = newTable[int, string]({:}) + discard x + + block nilTest: + var i, j: TableRef[int, int] = nil + assert i == j + j = newTable[int, int]() + assert i != j + assert j != i + i = newTable[int, int]() + assert i == j + + proc orderedTableSortTest() = + var t = newOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + for key, val in items(data): assert t[key] == val + t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) + var i = 0 + # `pairs` needs to yield in sorted order: + for key, val in pairs(t): + doAssert key == sorteddata[i][0] + doAssert val == sorteddata[i][1] + inc(i) + + # check that lookup still works: + for key, val in pairs(t): + doAssert val == t[key] + # check that insert still works: + t["newKeyHere"] = 80 + + block anonZipTest: + let keys = @['a','b','c'] + let values = @[1, 2, 3] + doAssert "{'a': 1, 'b': 2, 'c': 3}" == $ toTable zip(keys, values) + + block clearTableTest: + var t = newTable[string, float]() + t["test"] = 1.2345 + t["111"] = 1.000043 + t["123"] = 1.23 + assert t.len() != 0 + t.clear() + assert t.len() == 0 + + block clearOrderedTableTest: + var t = newOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + assert t.len() != 0 + t.clear() + assert t.len() == 0 + + block clearCountTableTest: + var t = newCountTable[string]() + t.inc("90", 3) + t.inc("12", 2) + t.inc("34", 1) + assert t.len() != 0 + t.clear() + assert t.len() == 0 + + orderedTableSortTest() + echo "true" + + +block tablesref2: + proc TestHashIntInt() = + var tab = newTable[int,int]() + for i in 1..1_000_000: + tab[i] = i + for i in 1..1_000_000: + var x = tab[i] + if x != i : echo "not found ", i + + proc run1() = # occupied Memory stays constant, but + for i in 1 .. 50: # aborts at run: 44 on win32 with 3.2GB with out of memory + TestHashIntInt() + + run1() + echo "true" diff --git a/tests/collections/ttables2.nim b/tests/collections/ttables2.nim deleted file mode 100644 index 6f3fa841af080..0000000000000 --- a/tests/collections/ttables2.nim +++ /dev/null @@ -1,30 +0,0 @@ -discard """ - output: '''true''' -""" - -import tables - -proc TestHashIntInt() = - var tab = initTable[int,int]() - for i in 1..1_000_000: - tab[i] = i - for i in 1..1_000_000: - var x = tab[i] - if x != i : echo "not found ", i - -proc run1() = # occupied Memory stays constant, but - for i in 1 .. 50: # aborts at run: 44 on win32 with 3.2GB with out of memory - TestHashIntInt() - -# bug #2107 - -var delTab = initTable[int,int](4) - -for i in 1..4: - delTab[i] = i - delTab.del(i) -delTab[5] = 5 - - -run1() -echo "true" diff --git a/tests/collections/ttablesref.nim b/tests/collections/ttablesref.nim deleted file mode 100644 index a4030e0dce05e..0000000000000 --- a/tests/collections/ttablesref.nim +++ /dev/null @@ -1,171 +0,0 @@ -discard """ - output: '''true''' -""" - -import hashes, tables, sequtils - -const - data = { - "34": 123456, "12": 789, - "90": 343, "0": 34404, - "1": 344004, "2": 344774, - "3": 342244, "4": 3412344, - "5": 341232144, "6": 34214544, - "7": 3434544, "8": 344544, - "9": 34435644, "---00": 346677844, - "10": 34484, "11": 34474, "19": 34464, - "20": 34454, "30": 34141244, "40": 344114, - "50": 344490, "60": 344491, "70": 344492, - "80": 344497} - - sorteddata = { - "---00": 346677844, - "0": 34404, - "1": 344004, - "10": 34484, - "11": 34474, - "12": 789, - "19": 34464, - "2": 344774, "20": 34454, - "3": 342244, "30": 34141244, - "34": 123456, - "4": 3412344, "40": 344114, - "5": 341232144, "50": 344490, - "6": 34214544, "60": 344491, - "7": 3434544, "70": 344492, - "8": 344544, "80": 344497, - "9": 34435644, - "90": 343} - -block tableTest1: - var t = newTable[tuple[x, y: int], string]() - t[(0,0)] = "00" - t[(1,0)] = "10" - t[(0,1)] = "01" - t[(1,1)] = "11" - for x in 0..1: - for y in 0..1: - assert t[(x,y)] == $x & $y - assert($t == - "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") - -block tableTest2: - var t = newTable[string, float]() - t["test"] = 1.2345 - t["111"] = 1.000043 - t["123"] = 1.23 - t.del("111") - - t["012"] = 67.9 - t["123"] = 1.5 # test overwriting - - assert t["123"] == 1.5 - try: - echo t["111"] # deleted - except KeyError: - discard - assert(not hasKey(t, "111")) - assert "111" notin t - - for key, val in items(data): t[key] = val.toFloat - for key, val in items(data): assert t[key] == val.toFloat - - -block orderedTableTest1: - var t = newOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - var i = 0 - # `pairs` needs to yield in insertion order: - for key, val in pairs(t): - assert key == data[i][0] - assert val == data[i][1] - inc(i) - - for key, val in mpairs(t): val = 99 - for val in mvalues(t): assert val == 99 - -block countTableTest1: - var s = data.toTable - var t = newCountTable[string]() - for k in s.keys: t.inc(k) - for k in t.keys: assert t[k] == 1 - t.inc("90", 3) - t.inc("12", 2) - t.inc("34", 1) - assert t.largest()[0] == "90" - - t.sort() - var i = 0 - for k, v in t.pairs: - case i - of 0: assert k == "90" and v == 4 - of 1: assert k == "12" and v == 3 - of 2: assert k == "34" and v == 2 - else: break - inc i - -block SyntaxTest: - var x = newTable[int, string]({:}) - discard x - -block nilTest: - var i, j: TableRef[int, int] = nil - assert i == j - j = newTable[int, int]() - assert i != j - assert j != i - i = newTable[int, int]() - assert i == j - -proc orderedTableSortTest() = - var t = newOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - for key, val in items(data): assert t[key] == val - t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) - var i = 0 - # `pairs` needs to yield in sorted order: - for key, val in pairs(t): - doAssert key == sorteddata[i][0] - doAssert val == sorteddata[i][1] - inc(i) - - # check that lookup still works: - for key, val in pairs(t): - doAssert val == t[key] - # check that insert still works: - t["newKeyHere"] = 80 - -block anonZipTest: - let keys = @['a','b','c'] - let values = @[1, 2, 3] - doAssert "{'a': 1, 'b': 2, 'c': 3}" == $ toTable zip(keys, values) - -block clearTableTest: - var t = newTable[string, float]() - t["test"] = 1.2345 - t["111"] = 1.000043 - t["123"] = 1.23 - assert t.len() != 0 - t.clear() - assert t.len() == 0 - -block clearOrderedTableTest: - var t = newOrderedTable[string, int](2) - for key, val in items(data): t[key] = val - assert t.len() != 0 - t.clear() - assert t.len() == 0 - -block clearCountTableTest: - var t = newCountTable[string]() - t.inc("90", 3) - t.inc("12", 2) - t.inc("34", 1) - assert t.len() != 0 - t.clear() - assert t.len() == 0 - -orderedTableSortTest() -echo "true" - diff --git a/tests/collections/ttablesref2.nim b/tests/collections/ttablesref2.nim deleted file mode 100644 index 939de2b84fbfc..0000000000000 --- a/tests/collections/ttablesref2.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - output: '''true''' -""" - -import tables - -proc TestHashIntInt() = - var tab = newTable[int,int]() - for i in 1..1_000_000: - tab[i] = i - for i in 1..1_000_000: - var x = tab[i] - if x != i : echo "not found ", i - -proc run1() = # occupied Memory stays constant, but - for i in 1 .. 50: # aborts at run: 44 on win32 with 3.2GB with out of memory - TestHashIntInt() - -run1() -echo "true" diff --git a/tests/collections/ttablesthreads.nim b/tests/collections/ttablesthreads.nim new file mode 100644 index 0000000000000..7fe4c79b13474 --- /dev/null +++ b/tests/collections/ttablesthreads.nim @@ -0,0 +1,275 @@ +discard """ + cmd: "nim c --threads:on $file" + output: '''true''' +""" + +import hashes, tables, sharedtables + +const + data = { + "34": 123456, "12": 789, + "90": 343, "0": 34404, + "1": 344004, "2": 344774, + "3": 342244, "4": 3412344, + "5": 341232144, "6": 34214544, + "7": 3434544, "8": 344544, + "9": 34435644, "---00": 346677844, + "10": 34484, "11": 34474, "19": 34464, + "20": 34454, "30": 34141244, "40": 344114, + "50": 344490, "60": 344491, "70": 344492, + "80": 344497} + + sorteddata = { + "---00": 346677844, + "0": 34404, + "1": 344004, + "10": 34484, + "11": 34474, + "12": 789, + "19": 34464, + "2": 344774, "20": 34454, + "3": 342244, "30": 34141244, + "34": 123456, + "4": 3412344, "40": 344114, + "5": 341232144, "50": 344490, + "6": 34214544, "60": 344491, + "7": 3434544, "70": 344492, + "8": 344544, "80": 344497, + "9": 34435644, + "90": 343} + +block tableTest1: + var t = initTable[tuple[x, y: int], string]() + t[(0,0)] = "00" + t[(1,0)] = "10" + t[(0,1)] = "01" + t[(1,1)] = "11" + for x in 0..1: + for y in 0..1: + assert t[(x,y)] == $x & $y + assert($t == + "{(x: 0, y: 1): \"01\", (x: 0, y: 0): \"00\", (x: 1, y: 0): \"10\", (x: 1, y: 1): \"11\"}") + +block tableTest2: + var t = initTable[string, float]() + t["test"] = 1.2345 + t["111"] = 1.000043 + t["123"] = 1.23 + t.del("111") + + t["012"] = 67.9 + t["123"] = 1.5 # test overwriting + + assert t["123"] == 1.5 + try: + echo t["111"] # deleted + except KeyError: + discard + assert(not hasKey(t, "111")) + + assert "123" in t + assert("111" notin t) + + for key, val in items(data): t[key] = val.toFloat + for key, val in items(data): assert t[key] == val.toFloat + + assert(not t.hasKeyOrPut("456", 4.0)) # test absent key + assert t.hasKeyOrPut("012", 3.0) # test present key + var x = t.mgetOrPut("111", 1.5) # test absent key + x = x * 2 + assert x == 3.0 + x = t.mgetOrPut("test", 1.5) # test present key + x = x * 2 + assert x == 2 * 1.2345 + +block orderedTableTest1: + var t = initOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + for key, val in items(data): assert t[key] == val + var i = 0 + # `pairs` needs to yield in insertion order: + for key, val in pairs(t): + assert key == data[i][0] + assert val == data[i][1] + inc(i) + + for key, val in mpairs(t): val = 99 + for val in mvalues(t): assert val == 99 + +block orderedTableTest2: + var + s = initOrderedTable[string, int]() + t = initOrderedTable[string, int]() + assert s == t + for key, val in items(data): t[key] = val + assert s != t + for key, val in items(sorteddata): s[key] = val + assert s != t + t.clear() + assert s != t + for key, val in items(sorteddata): t[key] = val + assert s == t + +block countTableTest1: + var s = data.toTable + var t = initCountTable[string]() + + for k in s.keys: t.inc(k) + for k in t.keys: assert t[k] == 1 + t.inc("90", 3) + t.inc("12", 2) + t.inc("34", 1) + assert t.largest()[0] == "90" + + t.sort() + var i = 0 + for k, v in t.pairs: + case i + of 0: assert k == "90" and v == 4 + of 1: assert k == "12" and v == 3 + of 2: assert k == "34" and v == 2 + else: break + inc i + +block countTableTest2: + var + s = initCountTable[int]() + t = initCountTable[int]() + assert s == t + s.inc(1) + assert s != t + t.inc(2) + assert s != t + t.inc(1) + assert s != t + s.inc(2) + assert s == t + s.inc(1) + assert s != t + t.inc(1) + assert s == t + +block mpairsTableTest1: + var t = initTable[string, int]() + t["a"] = 1 + t["b"] = 2 + t["c"] = 3 + t["d"] = 4 + for k, v in t.mpairs: + if k == "a" or k == "c": + v = 9 + + for k, v in t.pairs: + if k == "a" or k == "c": + assert v == 9 + else: + assert v != 1 and v != 3 + +block SyntaxTest: + var x = toTable[int, string]({:}) + +block zeroHashKeysTest: + proc doZeroHashValueTest[T, K, V](t: T, nullHashKey: K, value: V) = + let initialLen = t.len + var testTable = t + testTable[nullHashKey] = value + assert testTable[nullHashKey] == value + assert testTable.len == initialLen + 1 + testTable.del(nullHashKey) + assert testTable.len == initialLen + + # with empty table + doZeroHashValueTest(toTable[int,int]({:}), 0, 42) + doZeroHashValueTest(toTable[string,int]({:}), "", 23) + doZeroHashValueTest(toOrderedTable[int,int]({:}), 0, 42) + doZeroHashValueTest(toOrderedTable[string,int]({:}), "", 23) + + # with non-empty table + doZeroHashValueTest(toTable[int,int]({1:2}), 0, 42) + doZeroHashValueTest(toTable[string,string]({"foo": "bar"}), "", "zero") + doZeroHashValueTest(toOrderedTable[int,int]({3:4}), 0, 42) + doZeroHashValueTest(toOrderedTable[string,string]({"egg": "sausage"}), + "", "spam") + +block clearTableTest: + var t = data.toTable + assert t.len() != 0 + t.clear() + assert t.len() == 0 + +block clearOrderedTableTest: + var t = data.toOrderedTable + assert t.len() != 0 + t.clear() + assert t.len() == 0 + +block clearCountTableTest: + var t = initCountTable[string]() + t.inc("90", 3) + t.inc("12", 2) + t.inc("34", 1) + assert t.len() != 0 + t.clear() + assert t.len() == 0 + +block withKeyTest: + var t: SharedTable[int, int] + t.init() + t.withKey(1) do (k: int, v: var int, pairExists: var bool): + assert(v == 0) + pairExists = true + v = 42 + assert(t.mget(1) == 42) + t.withKey(1) do (k: int, v: var int, pairExists: var bool): + assert(v == 42) + pairExists = false + try: + discard t.mget(1) + assert(false, "KeyError expected") + except KeyError: + discard + t.withKey(2) do (k: int, v: var int, pairExists: var bool): + pairExists = false + try: + discard t.mget(2) + assert(false, "KeyError expected") + except KeyError: + discard + +block takeTest: + var t = initTable[string, int]() + t["key"] = 123 + + var val = 0 + assert(t.take("key", val)) + assert(val == 123) + + val = -1 + assert(not t.take("key", val)) + assert(val == -1) + + assert(not t.take("otherkey", val)) + assert(val == -1) + +proc orderedTableSortTest() = + var t = initOrderedTable[string, int](2) + for key, val in items(data): t[key] = val + for key, val in items(data): assert t[key] == val + t.sort(proc (x, y: tuple[key: string, val: int]): int = cmp(x.key, y.key)) + var i = 0 + # `pairs` needs to yield in sorted order: + for key, val in pairs(t): + doAssert key == sorteddata[i][0] + doAssert val == sorteddata[i][1] + inc(i) + + # check that lookup still works: + for key, val in pairs(t): + doAssert val == t[key] + # check that insert still works: + t["newKeyHere"] = 80 + + +orderedTableSortTest() +echo "true" + diff --git a/tests/concepts/t1128.nim b/tests/concepts/t1128.nim deleted file mode 100644 index 69a2fa9b73ba8..0000000000000 --- a/tests/concepts/t1128.nim +++ /dev/null @@ -1,21 +0,0 @@ -discard """ - output: "true\ntrue" -""" - -type - TFooContainer[T] = object - - TContainer[T] = concept var c - foo(c, T) - -proc foo[T](c: var TFooContainer[T], val: T) = - discard - -proc bar(c: var TContainer) = - discard - -var fooContainer: TFooContainer[int] -echo fooContainer is TFooContainer # true. -echo fooContainer is TFooContainer[int] # true. -fooContainer.bar() - diff --git a/tests/concepts/t3414.nim b/tests/concepts/t3414.nim deleted file mode 100644 index d45973034ef35..0000000000000 --- a/tests/concepts/t3414.nim +++ /dev/null @@ -1,22 +0,0 @@ -type - View[T] = concept v - v.empty is bool - v.front is T - popFront v - -proc find(view: View; target: View.T): View = - result = view - - while not result.empty: - if view.front == target: - return - - mixin popFront - popFront result - -proc popFront[T](s: var seq[T]) = discard -proc empty[T](s: seq[T]): bool = false - -var s1 = @[1, 2, 3] -let s2 = s1.find(10) - diff --git a/tests/concepts/t5642.nim b/tests/concepts/t5642.nim deleted file mode 100644 index f08b4629be494..0000000000000 --- a/tests/concepts/t5642.nim +++ /dev/null @@ -1,25 +0,0 @@ -discard """ - output: 9 -""" - -type DataTable = concept x - x is object - for f in fields(x): - f is seq - -type Students = object - id : seq[int] - name : seq[string] - age: seq[int] - -proc nrow*(dt: DataTable) : Natural = - var totalLen = 0 - for f in fields(dt): - totalLen += f.len - return totalLen - -let - stud = Students(id : @[1,2,3], name : @["Vas", "Pas", "NafNaf"], age : @[10,16,32]) - -echo nrow(stud) - diff --git a/tests/concepts/t5888.nim b/tests/concepts/t5888.nim deleted file mode 100644 index dbbab8c4cc4af..0000000000000 --- a/tests/concepts/t5888.nim +++ /dev/null @@ -1,26 +0,0 @@ -discard """ -output: ''' -true -true -true -f -0 -''' -""" - -import t5888lib/ca, t5888lib/opt - -type LocalCA = ca.CA - -proc f(c: CA) = - echo "f" - echo c.x - -var o = new(Opt) - -echo o is CA -echo o is LocalCA -echo o is ca.CA - -o.f() - diff --git a/tests/concepts/t5968.nim b/tests/concepts/t5968.nim deleted file mode 100644 index adb374c65a675..0000000000000 --- a/tests/concepts/t5968.nim +++ /dev/null @@ -1,20 +0,0 @@ -discard """ - exitcode: 0 -""" - -type - Enumerable[T] = concept e - for it in e: - it is T - -proc cmap[T, G](e: Enumerable[T], fn: proc(t: T): G): seq[G] = - result = @[] - for it in e: result.add(fn(it)) - -import json - -var x = %["hello", "world"] - -var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!") -assert z == @["hello!", "world!"] - diff --git a/tests/concepts/t5983.nim b/tests/concepts/t5983.nim deleted file mode 100644 index e696474483201..0000000000000 --- a/tests/concepts/t5983.nim +++ /dev/null @@ -1,22 +0,0 @@ -discard """ - output: "20.0 USD" -""" - -import typetraits - -const currencies = ["USD", "EUR"] # in real code 120 currencies - -type USD* = distinct float # in real code 120 types generates using macro -type EUR* = distinct float - -type CurrencyAmount = concept c - type t = c.type - const name = c.type.name - name in currencies - -proc `$`(x: CurrencyAmount): string = - $float(x) & " " & x.name - -let amount = 20.USD -echo amount - diff --git a/tests/concepts/t6462.nim b/tests/concepts/t6462.nim deleted file mode 100644 index 2fa2268f83077..0000000000000 --- a/tests/concepts/t6462.nim +++ /dev/null @@ -1,23 +0,0 @@ -discard """ - output: "true" -""" - -import future - -type - FilterMixin*[T] = ref object - test*: (T) -> bool - trans*: (T) -> T - - SeqGen*[T] = ref object - fil*: FilterMixin[T] - - WithFilter[T] = concept a - a.fil is FilterMixin[T] - -proc test*[T](a: WithFilter[T]): (T) -> bool = - a.fil.test - -var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil)) -echo s.test() == nil - diff --git a/tests/concepts/t6770.nim b/tests/concepts/t6770.nim deleted file mode 100644 index 1787ee670b3b9..0000000000000 --- a/tests/concepts/t6770.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ -output: ''' -10 -10 -''' -""" - -type GA = concept c - c.a is int - -type A = object - a: int - -type AA = object - case exists: bool - of true: - a: int - else: - discard - -proc print(inp: GA) = - echo inp.a - -let failing = AA(exists: true, a: 10) -let working = A(a:10) -print(working) -print(failing) diff --git a/tests/concepts/t7952.nim b/tests/concepts/t7952.nim deleted file mode 100644 index 96ff47e4a7faf..0000000000000 --- a/tests/concepts/t7952.nim +++ /dev/null @@ -1,12 +0,0 @@ -discard """ - output: 5 -""" - -type - HasLen = concept iter - len(iter) is int - -proc echoLen(x: HasLen) = - echo len(x) - -echoLen([1, 2, 3, 4, 5]) diff --git a/tests/concepts/t8280.nim b/tests/concepts/t8280.nim deleted file mode 100644 index ba33af34e0b27..0000000000000 --- a/tests/concepts/t8280.nim +++ /dev/null @@ -1,16 +0,0 @@ -discard """ - output: "()" -""" - -type - Iterable[T] = concept x - for elem in x: - elem is T - -proc max[A](iter: Iterable[A]): A = - discard - -type - MyType = object - -echo max(@[MyType()]) diff --git a/tests/concepts/t976.nim b/tests/concepts/t976.nim deleted file mode 100644 index 32421950857cd..0000000000000 --- a/tests/concepts/t976.nim +++ /dev/null @@ -1,54 +0,0 @@ -discard """ - output: '''Printable''' -""" - -import macros - -type - int1 = distinct int - int2 = distinct int - - int1g = concept x - x is int1 - - int2g = concept x - x is int2 - -proc take[T: int1g](value: int1) = - when T is int2: - static: error("killed in take(int1)") - -proc take[T: int2g](vale: int2) = - when T is int1: - static: error("killed in take(int2)") - -var i1: int1 = 1.int1 -var i2: int2 = 2.int2 - -take[int1](i1) -take[int2](i2) - -template reject(e) = - static: assert(not compiles(e)) - -reject take[string](i2) -reject take[int1](i2) - -# bug #6249 -type - Obj1[T] = object - v: T - - Obj2 = ref object - - PrintAble = concept x - $x is string - -converter toObj1[T](t: T): Obj1[T] = - return Obj1[T](v: t) - -proc `$`[T](nt: Obj1[T]): string = - when T is PrintAble: result = "Printable" - else: result = "Non Printable" - -echo Obj2() diff --git a/tests/concepts/tconcepts.nim b/tests/concepts/tconcepts.nim new file mode 100644 index 0000000000000..dec1dafe07af9 --- /dev/null +++ b/tests/concepts/tconcepts.nim @@ -0,0 +1,441 @@ +discard """ + file: "tconcepts.nim" + output: ''' +10 +20 +int +20 +3 +x as ParameterizedType[T] +x as ParameterizedType[T] +x as ParameterizedType[T] +x as ParameterizedType +x as ParameterizedType +x as CustomTypeClass +1 +2 +3 +4 +5 +6 +a +b +t +e +s +t +z +e +1 +2 +3 +20 +10 +5 +''' +""" + + +import typetraits, strutils + + +block tcomparable: + type + Comparable = concept a + (a < a) is bool + + proc myMax(a, b: Comparable): Comparable = + if a < b: + return b + else: + return a + + doAssert myMax(5, 10) == 10 + doAssert myMax(31.3, 1.23124) == 31.3 + + + +block tconceptinclosure: + type + FonConcept = concept x + x.x is int + GenericConcept[T] = concept x + x.x is T + const L = T.name.len + Implementation = object + x: int + Closure = object + f: proc() + + proc f1(x: FonConcept): Closure = + result.f = proc () = + echo x.x + + proc f2(x: GenericConcept): Closure = + result.f = proc () = + echo x.x + echo GenericConcept.T.name + + proc f3[T](x: GenericConcept[T]): Closure = + result.f = proc () = + echo x.x + echo x.L + + let x = Implementation(x: 10) + let y = Implementation(x: 20) + + let a = x.f1 + let b = x.f2 + let c = x.f1 + let d = y.f2 + let e = y.f3 + + a.f() + d.f() + e.f() + + + +block overload_precedence: + type ParameterizedType[T] = object + + type CustomTypeClass = concept + true + + # 3 competing procs + proc a[T](x: ParameterizedType[T]) = + echo "x as ParameterizedType[T]" + + proc a(x: ParameterizedType) = + echo "x as ParameterizedType" + + proc a(x: CustomTypeClass) = + echo "x as CustomTypeClass" + + # the same procs in different order + proc b(x: ParameterizedType) = + echo "x as ParameterizedType" + + proc b(x: CustomTypeClass) = + echo "x as CustomTypeClass" + + proc b[T](x: ParameterizedType[T]) = + echo "x as ParameterizedType[T]" + + # and yet another order + proc c(x: CustomTypeClass) = + echo "x as CustomTypeClass" + + proc c(x: ParameterizedType) = + echo "x as ParameterizedType" + + proc c[T](x: ParameterizedType[T]) = + echo "x as ParameterizedType[T]" + + # remove the most specific one + proc d(x: ParameterizedType) = + echo "x as ParameterizedType" + + proc d(x: CustomTypeClass) = + echo "x as CustomTypeClass" + + # then shuffle the order again + proc e(x: CustomTypeClass) = + echo "x as CustomTypeClass" + + proc e(x: ParameterizedType) = + echo "x as ParameterizedType" + + # the least specific one is a match + proc f(x: CustomTypeClass) = + echo "x as CustomTypeClass" + + a(ParameterizedType[int]()) + b(ParameterizedType[int]()) + c(ParameterizedType[int]()) + d(ParameterizedType[int]()) + e(ParameterizedType[int]()) + f(ParameterizedType[int]()) + + + +block templates: + template typeLen(x): int = x.type.name.len + + template bunchOfChecks(x) = + x.typeLen > 3 + x != 10 is bool + + template stmtListExprTmpl(x: untyped): untyped = + x is int + x + + type + Obj = object + x: int + + Gen[T] = object + x: T + + Eq = concept x, y + (x == y) is bool + + NotEq = concept x, y + (x != y) is bool + + ConceptUsingTemplate1 = concept x + echo x + sizeof(x) is int + bunchOfChecks x + + ConceptUsingTemplate2 = concept x + stmtListExprTmpl x + + template ok(x) = + static: assert(x) + + template no(x) = + static: assert(not(x)) + + ok int is Eq + ok int is NotEq + ok string is Eq + ok string is NotEq + ok Obj is Eq + ok Obj is NotEq + ok Gen[string] is Eq + ok Gen[int] is NotEq + + no int is ConceptUsingTemplate1 + ok float is ConceptUsingTemplate1 + no string is ConceptUsingTemplate1 + + ok int is ConceptUsingTemplate2 + no float is ConceptUsingTemplate2 + no string is ConceptUsingTemplate2 + + + +block titerable: + type + Iterable[T] = concept x + for value in x: + type(value) is T + + proc sum[T](iter: Iterable[T]): T = + static: echo T.name + for element in iter: + static: echo element.type.name + result += element + + doAssert sum([1, 2, 3, 4, 5]) == 15 + + + +block tmanual: + template accept(e) = + static: assert compiles(e) + + template reject(e) = + static: assert(not compiles(e)) + + type + Container[T] = concept c + c.len is Ordinal + items(c) is T + for value in c: + type(value) is T + + proc takesIntContainer(c: Container[int]) = + for e in c: echo e + + takesIntContainer(@[1, 2, 3]) + reject takesIntContainer(@["x", "y"]) + + proc takesContainer(c: Container) = + for e in c: echo e + + takesContainer(@[4, 5, 6]) + takesContainer(@["a", "b"]) + takesContainer "test" + reject takesContainer(10) + + + +block modifiers_in_place: + type + VarContainer[T] = concept c + put(var c, T) + AltVarContainer[T] = concept var c + put(c, T) + NonVarContainer[T] = concept c + put(c, T) + GoodContainer = object + x: int + BadContainer = object + x: int + + proc put(x: BadContainer, y: int) = discard + proc put(x: var GoodContainer, y: int) = discard + + template ok(x) = assert(x) + template no(x) = assert(not(x)) + + static: + ok GoodContainer is VarContainer[int] + ok GoodContainer is AltVarContainer[int] + no BadContainer is VarContainer[int] + no BadContainer is AltVarContainer[int] + ok GoodContainer is NonVarContainer[int] + ok BadContainer is NonVarContainer[int] + + + +block treversable: + type + Reversable[T] = concept a + a[int] is T + a.high is int + a.len is int + a.low is int + + proc get[T](s: Reversable[T], n: int): T = + s[n] + + proc hi[T](s: Reversable[T]): int = + s.high + + proc lo[T](s: Reversable[T]): int = + s.low + + iterator reverse[T](s: Reversable[T]): T = + assert hi(s) - lo(s) == len(s) - 1 + for z in hi(s).countdown(lo(s)): + yield s.get(z) + + for s in @["e", "z"].reverse: + echo s + + + +block tmonoid: + type Monoid = concept x, y + x + y is type(x) + type(z(type(x))) is type(x) + + proc z(x: typedesc[int]): int = 0 + + doAssert(int is Monoid) + + # https://github.com/nim-lang/Nim/issues/8126 + type AdditiveMonoid = concept x, y, type T + x + y is T + + # some redundant checks to test an alternative approaches: + type TT = type(x) + x + y is type(x) + x + y is TT + + doAssert(1 is AdditiveMonoid) + + + +block tesqofconcept: + type + MyConcept = concept x + someProc(x) + SomeSeq = seq[MyConcept] + + proc someProc(x:int) = echo x + + proc work (s: SomeSeq) = + for item in s: + someProc item + + var s = @[1, 2, 3] + work s + + + +block tvectorspace: + type VectorSpace[K] = concept x, y + x + y is type(x) + zero(type(x)) is type(x) + -x is type(x) + x - y is type(x) + var k: K + k * x is type(x) + + proc zero(T: typedesc): T = 0 + + static: + assert float is VectorSpace[float] + # assert float is VectorSpace[int] + # assert int is VectorSpace + + + +block tstack: + template reject(e) = + static: assert(not compiles(e)) + + type + ArrayStack = object + data: seq[int] + + proc push(s: var ArrayStack, item: int) = + s.data.add item + + proc pop(s: var ArrayStack): int = + return s.data.pop() + + type + Stack[T] = concept var s + s.push(T) + s.pop() is T + + type ValueType = T + const ValueTypeName = T.name.toUpperAscii + + proc genericAlgorithm[T](s: var Stack[T], y: T) = + static: + echo "INFERRED ", T.name + echo "VALUE TYPE ", s.ValueType.name + echo "VALUE TYPE NAME ", s.ValueTypeName + + s.push(y) + echo s.pop + + proc implicitGeneric(s: var Stack): auto = + static: + echo "IMPLICIT INFERRED ", s.T.name, " ", Stack.T.name + echo "IMPLICIT VALUE TYPE ", s.ValueType.name, " ", Stack.ValueType.name + echo "IMPLICIT VALUE TYPE NAME ", s.ValueTypeName, " ", Stack.ValueTypeName + + return s.pop() + + var s = ArrayStack(data: @[]) + + s.push 10 + s.genericAlgorithm 20 + echo s.implicitGeneric + + reject s.genericAlgorithm "x" + reject s.genericAlgorithm 1.0 + reject "str".implicitGeneric + reject implicitGeneric(10) + + + +import libs/[trie_database, trie] +block ttrie: + proc takeDb(d: TrieDatabase) = discard + var mdb: MemDB + takeDb(mdb) + + + +import mvarconcept +block tvar: + # bug #2346, bug #2404 + echo randomInt(5) diff --git a/tests/concepts/tgraph.nim b/tests/concepts/tgraph.nim deleted file mode 100644 index 985f04a615955..0000000000000 --- a/tests/concepts/tgraph.nim +++ /dev/null @@ -1,34 +0,0 @@ -# bug #3452 -import math - -type - Node* = concept n - `==`(n, n) is bool - - Graph1* = concept g - type N = Node - distance(g, N, N) is float - - Graph2 = concept g - distance(g, Node, Node) is float - - Graph3 = concept g - var x: Node - distance(g, x, x) is float - - XY* = tuple[x, y: int] - - MyGraph* = object - points: seq[XY] - -static: - assert XY is Node - -proc distance*( g: MyGraph, a, b: XY): float = - sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) ) - -static: - assert MyGraph is Graph1 - assert MyGraph is Graph2 - assert MyGraph is Graph3 - diff --git a/tests/concepts/tinfrecursion.nim b/tests/concepts/tinfrecursion.nim deleted file mode 100644 index 60db410dee093..0000000000000 --- a/tests/concepts/tinfrecursion.nim +++ /dev/null @@ -1,13 +0,0 @@ - -# bug #6691 -type - ConceptA = concept c - - ConceptB = concept c - c.myProc(ConceptA) - - Obj = object - -proc myProc(obj: Obj, x: ConceptA) = discard - -echo Obj is ConceptB diff --git a/tests/concepts/tissues.nim b/tests/concepts/tissues.nim new file mode 100644 index 0000000000000..080711434b73b --- /dev/null +++ b/tests/concepts/tissues.nim @@ -0,0 +1,421 @@ +discard """ + file: "tissues.nim" + output: ''' +20.0 USD +Printable +true +true +true +true +true +f +0 +10 +10 +5 +() +false +true +true +true +true +p has been called. +p has been called. +implicit generic +generic +false +true +-1 +Meow +''' +""" + +import macros, typetraits + + +block t5983: + const currencies = ["USD", "EUR"] # in real code 120 currencies + + type USD = distinct float # in real code 120 types generates using macro + type EUR = distinct float + + type CurrencyAmount = concept c + type t = c.type + const name = c.type.name + name in currencies + + proc `$`(x: CurrencyAmount): string = + $float(x) & " " & x.name + + let amount = 20.USD + echo amount + + +block t3414: + type + View[T] = concept v + v.empty is bool + v.front is T + popFront v + + proc find(view: View; target: View.T): View = + result = view + + while not result.empty: + if view.front == target: + return + + mixin popFront + popFront result + + proc popFront[T](s: var seq[T]) = discard + proc empty[T](s: seq[T]): bool = false + + var s1 = @[1, 2, 3] + let s2 = s1.find(10) + + + +type + Obj1[T] = object + v: T +converter toObj1[T](t: T): Obj1[T] = + return Obj1[T](v: t) +block t976: + type + int1 = distinct int + int2 = distinct int + int1g = concept x + x is int1 + int2g = concept x + x is int2 + + proc take[T: int1g](value: int1) = + when T is int2: + static: error("killed in take(int1)") + + proc take[T: int2g](vale: int2) = + when T is int1: + static: error("killed in take(int2)") + + var i1: int1 = 1.int1 + var i2: int2 = 2.int2 + + take[int1](i1) + take[int2](i2) + + template reject(e) = + static: assert(not compiles(e)) + + reject take[string](i2) + reject take[int1](i2) + + # bug #6249 + type + Obj2 = ref object + PrintAble = concept x + $x is string + + proc `$`[T](nt: Obj1[T]): string = + when T is PrintAble: result = "Printable" + else: result = "Non Printable" + + echo Obj2() + + + +block t1128: + type + TFooContainer[T] = object + + TContainer[T] = concept var c + foo(c, T) + + proc foo[T](c: var TFooContainer[T], val: T) = + discard + + proc bar(c: var TContainer) = + discard + + var fooContainer: TFooContainer[int] + echo fooContainer is TFooContainer # true. + echo fooContainer is TFooContainer[int] # true. + fooContainer.bar() + + + +block t5642: + type DataTable = concept x + x is object + for f in fields(x): + f is seq + + type Students = object + id : seq[int] + name : seq[string] + age: seq[int] + + proc nrow(dt: DataTable) : Natural = + var totalLen = 0 + for f in fields(dt): + totalLen += f.len + return totalLen + + let + stud = Students(id: @[1,2,3], name: @["Vas", "Pas", "NafNaf"], age: @[10,16,32]) + + doAssert nrow(stud) == 9 + + + +import t5888lib/ca, t5888lib/opt +block t5888: + type LocalCA = ca.CA + + proc f(c: CA) = + echo "f" + echo c.x + + var o = new(Opt) + + echo o is CA + echo o is LocalCA + echo o is ca.CA + + o.f() + + + +import json +block t5968: + type + Enumerable[T] = concept e + for it in e: + it is T + + proc cmap[T, G](e: Enumerable[T], fn: proc(t: T): G): seq[G] = + result = @[] + for it in e: result.add(fn(it)) + + var x = %["hello", "world"] + + var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!") + assert z == @["hello!", "world!"] + + + +import sugar +block t6462: + type + FilterMixin[T] = ref object + test: (T) -> bool + trans: (T) -> T + + SeqGen[T] = ref object + fil: FilterMixin[T] + + WithFilter[T] = concept a + a.fil is FilterMixin[T] + + proc test[T](a: WithFilter[T]): (T) -> bool = + a.fil.test + + var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil)) + doAssert s.test() == nil + + + +block t6770: + type GA = concept c + c.a is int + + type A = object + a: int + + type AA = object + case exists: bool + of true: + a: int + else: + discard + + proc print(inp: GA) = + echo inp.a + + let failing = AA(exists: true, a: 10) + let working = A(a:10) + print(working) + print(failing) + + + +block t7952: + type + HasLen = concept iter + len(iter) is int + + proc echoLen(x: HasLen) = + echo len(x) + + echoLen([1, 2, 3, 4, 5]) + + + +block t8280: + type + Iterable[T] = concept x + for elem in x: + elem is T + + proc max[A](iter: Iterable[A]): A = + discard + + type + MyType = object + + echo max(@[MyType()]) + + + +import math +block t3452: + type + Node = concept n + `==`(n, n) is bool + Graph1 = concept g + type N = Node + distance(g, N, N) is float + Graph2 = concept g + distance(g, Node, Node) is float + Graph3 = concept g + var x: Node + distance(g, x, x) is float + XY = tuple[x, y: int] + MyGraph = object + points: seq[XY] + + static: + assert XY is Node + + proc distance( g: MyGraph, a, b: XY): float = + sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) ) + + static: + assert MyGraph is Graph1 + assert MyGraph is Graph2 + assert MyGraph is Graph3 + + + +block t6691: + type + ConceptA = concept c + ConceptB = concept c + c.myProc(ConceptA) + Obj = object + + proc myProc(obj: Obj, x: ConceptA) = discard + + echo Obj is ConceptB + + + +block misc_issues: + # https://github.com/nim-lang/Nim/issues/1147 + type TTest = object + vals: seq[int] + + proc add(self: var TTest, val: int) = + self.vals.add(val) + + type CAddable = concept x + x[].add(int) + + echo((ref TTest) is CAddable) # true + + # https://github.com/nim-lang/Nim/issues/1570 + type ConcretePointOfFloat = object + x, y: float + + type ConcretePoint[Value] = object + x, y: Value + + type AbstractPointOfFloat = concept p + p.x is float and p.y is float + + let p1 = ConcretePointOfFloat(x: 0, y: 0) + let p2 = ConcretePoint[float](x: 0, y: 0) + + echo p1 is AbstractPointOfFloat # true + echo p2 is AbstractPointOfFloat # true + echo p2.x is float and p2.y is float # true + + # https://github.com/nim-lang/Nim/issues/2018 + type ProtocolFollower = concept + true # not a particularly involved protocol + + type ImplementorA = object + type ImplementorB = object + + proc p[A: ProtocolFollower, B: ProtocolFollower](a: A, b: B) = + echo "p has been called." + + p(ImplementorA(), ImplementorA()) + p(ImplementorA(), ImplementorB()) + + # https://github.com/nim-lang/Nim/issues/2423 + proc put[T](c: seq[T], x: T) = echo "generic" + proc put(c: seq) = echo "implicit generic" + + type + Container[T] = concept c + put(c) + put(c, T) + + proc c1(x: Container) = echo "implicit generic" + c1(@[1]) + + proc c2[T](x: Container[T]) = echo "generic" + c2(@[1]) + + # https://github.com/nim-lang/Nim/issues/2882 + type + Paper = object + name: string + + Bendable = concept x + bend(x is Bendable) + + proc bend(p: Paper): Paper = Paper(name: "bent-" & p.name) + + var paper = Paper(name: "red") + echo paper is Bendable + + type + A = concept self + size(self) is int + + B = object + + proc size(self: B): int = + return -1 + + proc size(self: A): int = + return 0 + + let b = B() + echo b is A + echo b.size() + + # https://github.com/nim-lang/Nim/issues/7125 + type + Thing = concept x + x.hello is string + Cat = object + + proc hello(d: Cat): string = "Meow" + + proc sayHello(c: Thing) = echo(c.hello) + + var a: Thing = Cat() + a.sayHello() diff --git a/tests/concepts/tmisc_issues.nim b/tests/concepts/tmisc_issues.nim deleted file mode 100644 index e21988c73d049..0000000000000 --- a/tests/concepts/tmisc_issues.nim +++ /dev/null @@ -1,113 +0,0 @@ -discard """ -output: '''true -true -true -true -p has been called. -p has been called. -implicit generic -generic -false -true --1 -Meow''' -""" - -# https://github.com/nim-lang/Nim/issues/1147 -type TTest = object - vals: seq[int] - -proc add*(self: var TTest, val: int) = - self.vals.add(val) - -type CAddable = concept x - x[].add(int) - -echo((ref TTest) is CAddable) # true - -# https://github.com/nim-lang/Nim/issues/1570 -type ConcretePointOfFloat = object - x, y: float - -type ConcretePoint[Value] = object - x, y: Value - -type AbstractPointOfFloat = concept p - p.x is float and p.y is float - -let p1 = ConcretePointOfFloat(x: 0, y: 0) -let p2 = ConcretePoint[float](x: 0, y: 0) - -echo p1 is AbstractPointOfFloat # true -echo p2 is AbstractPointOfFloat # true -echo p2.x is float and p2.y is float # true - -# https://github.com/nim-lang/Nim/issues/2018 -type ProtocolFollower = concept - true # not a particularly involved protocol - -type ImplementorA = object -type ImplementorB = object - -proc p[A: ProtocolFollower, B: ProtocolFollower](a: A, b: B) = - echo "p has been called." - -p(ImplementorA(), ImplementorA()) -p(ImplementorA(), ImplementorB()) - -# https://github.com/nim-lang/Nim/issues/2423 -proc put*[T](c: seq[T], x: T) = echo "generic" -proc put*(c: seq) = echo "implicit generic" - -type - Container[T] = concept c - put(c) - put(c, T) - -proc c1(x: Container) = echo "implicit generic" -c1(@[1]) - -proc c2[T](x: Container[T]) = echo "generic" -c2(@[1]) - -# https://github.com/nim-lang/Nim/issues/2882 -type - Paper = object - name: string - - Bendable = concept x - bend(x is Bendable) - -proc bend(p: Paper): Paper = Paper(name: "bent-" & p.name) - -var paper = Paper(name: "red") -echo paper is Bendable - -type - A = concept self - size(self) is int - - B = object - -proc size(self: B): int = - return -1 - -proc size(self: A): int = - return 0 - -let b = B() -echo b is A -echo b.size() - -# https://github.com/nim-lang/Nim/issues/7125 -type - Thing = concept x - x.hello is string - Cat = object - -proc hello(d: Cat): string = "Meow" - -proc sayHello(c: Thing) = echo(c.hello) - -var a: Thing = Cat() -a.sayHello()