From 104a8872f3b12db9ef27fde2ea37cfe0dfaca81a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Mon, 26 Feb 2018 19:39:29 +0100 Subject: [PATCH 1/9] fix for Regression that the introduction of BackwardsIndex introduced --- lib/system.nim | 57 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index ce6ed4c7fae6..003784ebcd99 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3830,8 +3830,36 @@ template spliceImpl(s, a, L, b: untyped): untyped = # fill the hole: for i in 0 ..< b.len: s[a+i] = b[i] -template `^^`(s, i: untyped): untyped = - (when i is BackwardsIndex: s.len - int(i) else: int(i)) +template `^^`*(s: untyped; i: BackwardsIndex): int = + ## General converter template to convert the Backwards index back to + ## a normal integer index. If your own type has a special conversion + ## from Backwards index to int, you can write your own overload, + ## otherwis it will be just default to this: `s.len - int(i)`. + ## + ## .. code-block:: nim + ## + ## type + ## MyType = object + ## + ## template `^^`(a: MyType, b: BackwardsIndex): int = + ## ## my conversion of `BackwardsIndex` for `MyType` + ## 1000 + int(b) + ## + ## proc `[]`(arg: MyType; idx: int): int = + ## idx + ## + ## var mt: MyType + ## echo mt[^1] # 1001 + s.len - int(i) + +template `^^`*[Idx, T](a: array[Idx, T], i: BackwardsIndex): int = + ## Converter template specialized for the array type. + int(a.low) + a.len - int(i) + +template `^^`*(s: untyped; i: int): int = + ## No operation in case the index is not a backwards index. For + ## generic programming only. + i template `[]`*(s: string; i: int): char = arrGet(s, i) template `[]=`*(s: string; i: int; val: char) = arrPut(s, i, val) @@ -3922,24 +3950,15 @@ proc `[]=`*[T, U, V](s: var seq[T], x: HSlice[U, V], b: openArray[T]) = else: spliceImpl(s, a, L, b) -proc `[]`*[T](s: openArray[T]; i: BackwardsIndex): T {.inline.} = - system.`[]`(s, s.len - int(i)) - -proc `[]`*[Idx, T](a: array[Idx, T]; i: BackwardsIndex): T {.inline.} = - a[Idx(a.len - int(i) + int low(a))] -proc `[]`*(s: string; i: BackwardsIndex): char {.inline.} = s[s.len - int(i)] - -proc `[]`*[T](s: var openArray[T]; i: BackwardsIndex): var T {.inline.} = - system.`[]`(s, s.len - int(i)) -proc `[]`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex): var T {.inline.} = - a[Idx(a.len - int(i) + int low(a))] +template `[]`*(s: untyped; i: BackwardsIndex): untyped = + ## Default behavior for the backwards index, so that when your type + ## supports `len` and the index operator, `BackwardsIndex` will work, too. + s[s ^^ i] -proc `[]=`*[T](s: var openArray[T]; i: BackwardsIndex; x: T) {.inline.} = - system.`[]=`(s, s.len - int(i), x) -proc `[]=`*[Idx, T](a: var array[Idx, T]; i: BackwardsIndex; x: T) {.inline.} = - a[Idx(a.len - int(i) + int low(a))] = x -proc `[]=`*(s: var string; i: BackwardsIndex; x: char) {.inline.} = - s[s.len - int(i)] = x +template `[]=`*(s: untyped; i: BackwardsIndex; x: untyped): untyped = + ## Default behavior for the backwards index, so that when your type + ## supports `len` and the index operator, `BackwardsIndex` will work, too. + s[s ^^ i] = x proc slurp*(filename: string): string {.magic: "Slurp".} ## This is an alias for `staticRead <#staticRead,string>`_. From c9d82a3d7836662ec04d7f48156d25f6e8d5fbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Mon, 26 Feb 2018 20:04:43 +0100 Subject: [PATCH 2/9] changed comment --- lib/system.nim | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 003784ebcd99..18730dc3e86f 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3951,13 +3951,13 @@ proc `[]=`*[T, U, V](s: var seq[T], x: HSlice[U, V], b: openArray[T]) = spliceImpl(s, a, L, b) template `[]`*(s: untyped; i: BackwardsIndex): untyped = - ## Default behavior for the backwards index, so that when your type - ## supports `len` and the index operator, `BackwardsIndex` will work, too. + ## Default support for `BackwardsIndex`. The `BackwardsIndex` is + ## resolved with `^^` to a normal `int`. s[s ^^ i] template `[]=`*(s: untyped; i: BackwardsIndex; x: untyped): untyped = - ## Default behavior for the backwards index, so that when your type - ## supports `len` and the index operator, `BackwardsIndex` will work, too. + ## Default support for `BackwardsIndex`. The `BackwardsIndex` is + ## resolved with `^^` to a normal `int`. s[s ^^ i] = x proc slurp*(filename: string): string {.magic: "Slurp".} From bd2ac8216b530b6ea3c49880e764807e1f50aa9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 27 Feb 2018 13:37:17 +0100 Subject: [PATCH 3/9] fix for tests/misc/tslices.nim --- lib/system.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/system.nim b/lib/system.nim index 18730dc3e86f..37f457c1f1c7 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3854,11 +3854,14 @@ template `^^`*(s: untyped; i: BackwardsIndex): int = template `^^`*[Idx, T](a: array[Idx, T], i: BackwardsIndex): int = ## Converter template specialized for the array type. - int(a.low) + a.len - int(i) + a.len - int(i) + int low(a) + +template `^^`*[Idx, T](a: array[Idx, T], i: Idx): int = + ## The default conversion from an idex type to an int is `int(i)`. + int(i) template `^^`*(s: untyped; i: int): int = - ## No operation in case the index is not a backwards index. For - ## generic programming only. + ## Do no conversion at all, when the input is already an integer. i template `[]`*(s: string; i: int): char = arrGet(s, i) From 123fd8b49fa5a9cb19fc6e90294032bbad797e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 27 Feb 2018 18:20:59 +0100 Subject: [PATCH 4/9] added changelog entry --- changelog.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index adc35a079669..1db6eb74776d 100644 --- a/changelog.md +++ b/changelog.md @@ -160,7 +160,7 @@ proc enumToString*(enums: openArray[enum]): string = - Added `system.default`. -- Added `sequtils.items` for closure iterators, allows closure iterators +- Added `sequtils.items` for closure iterators, allows closure iterators to be used by the the mapIt, filterIt, allIt, anyIt, etc. @@ -224,7 +224,6 @@ proc enumToString*(enums: openArray[enum]): string = - Hash sets and tables are initialized by default. The explicit `initHashSet`, `initTable`, etc. are not needed anymore. - ### Tool changes - `jsondoc` now include a `moduleDescription` field with the module From 7faf0573572b1f58c8ddb8a745c2da055c66969a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Wed, 28 Feb 2018 17:07:15 +0100 Subject: [PATCH 5/9] nicer error messages for old list comprehension. --- tests/compiles/trecursive_generic_in_compiles.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compiles/trecursive_generic_in_compiles.nim b/tests/compiles/trecursive_generic_in_compiles.nim index c435ebaac5bd..66c1b0767ce3 100644 --- a/tests/compiles/trecursive_generic_in_compiles.nim +++ b/tests/compiles/trecursive_generic_in_compiles.nim @@ -96,7 +96,7 @@ proc foldLeft*[T,U](xs: List[T], z: U, f: (U, T) -> U): U = suite "unittest compilation error": test "issue 3313": - let lst = lc[$x | (x <- 'a'..'z'), string].asList + let lst = lc($x | (x <- 'a'..'z'), string).asList let lstCopy = lst.dup check: lstCopy == lst From 5594b76793b4b903352d88eca46a5890edee902f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 10 Apr 2018 17:32:32 +0200 Subject: [PATCH 6/9] merge changes into devel --- changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.md b/changelog.md index 1db6eb74776d..386d06f03e44 100644 --- a/changelog.md +++ b/changelog.md @@ -98,6 +98,10 @@ explicit overload of `formatValue`. +- Using the ``BackwardsIndex`` on arrays that are not accessed by + integer types (for example enums or characters) is not supported + anymore. + #### Breaking changes in the compiler - The compiler now implements the "generic symbol prepass" for `when` statements From 613efcbd71dac3c26618d9e6a73ae7cbfbcb6b5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 10 Apr 2018 21:49:37 +0200 Subject: [PATCH 7/9] fix for tests --- tests/array/tarray.nim | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/array/tarray.nim b/tests/array/tarray.nim index b40c8757c581..66eebd589e48 100644 --- a/tests/array/tarray.nim +++ b/tests/array/tarray.nim @@ -262,7 +262,19 @@ block troof: var d: array['a'..'c', string] = ["a", "b", "c"] doAssert d[^1] == "c" + # test for default implementation of backwards index + type + MyType = object + + proc len(arg: MyType): int = 100 + proc `[]`(arg: MyType; idx: int): int = idx + + var mt: MyType + + assert mt[0] == 0 + assert mt[^0] == 100 + assert mt[^1] == 99 import strutils, sequtils, typetraits, os From 54290c4f9964e35688d3aefb4bc34c719eb4f998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Tue, 7 May 2019 18:04:00 +0200 Subject: [PATCH 8/9] stuff --- lib/core/macros.nim | 3 --- lib/pure/sugar.nim | 18 ++++++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 847e17c56c86..ffdf44b20af8 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -174,9 +174,6 @@ proc `[]`*(n: NimNode, i: int): NimNode {.magic: "NChild", noSideEffect.} proc `[]`*(n: NimNode, i: BackwardsIndex): NimNode = n[n.len - i.int] ## get `n`'s `i`'th child. -template `^^`(n: NimNode, i: untyped): untyped = - (when i is BackwardsIndex: n.len - int(i) else: int(i)) - proc `[]`*[T, U](n: NimNode, x: HSlice[T, U]): seq[NimNode] = ## slice operation for NimNode. ## returns a seq of child of `n` who inclusive range [n[x.a], n[x.b]]. diff --git a/lib/pure/sugar.nim b/lib/pure/sugar.nim index c4c99121420f..4dc13a556b55 100644 --- a/lib/pure/sugar.nim +++ b/lib/pure/sugar.nim @@ -122,12 +122,18 @@ macro `->`*(p, b: untyped): untyped = result = createProcType(p, b) -type ListComprehension = object -var lc* {.deprecated.}: ListComprehension - -template `|`*(lc: ListComprehension, comp: untyped): untyped {.deprecated.} = lc - -macro `[]`*(lc: ListComprehension, comp, typ: untyped): untyped {.deprecated.} = +template `|`*(a,b: untyped): untyped = + ## This template should never expand. At some point in the future it + ## will be reved without replacement. When it causes problems, + ## unexport with ``import future except `|` ``. It is just a hack to + ## get useful error messages for the old `[]` brackeds based list + ## comprehension syntax. + {.error: "this should never expand. If it does use ``import future except `|` ``.".} + +template lc*: untyped = + {.error: "list comprehension syntax got changed. replace lc[ x | ... ] with lc( x | ... ) now!".} + +macro lc*(comp, typ: untyped): untyped = ## List comprehension, returns a sequence. `comp` is the actual list ## comprehension, for example ``x | (x <- 1..10, x mod 2 == 0)``. `typ` is ## the type that will be stored inside the result seq. From 762fe4da538252a333cddf2ce1b92d9ec292c7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20D=C3=B6ring?= Date: Wed, 12 Feb 2020 21:39:30 +0100 Subject: [PATCH 9/9] disable tmapconcept --- tests/concepts/tmapconcept.nim | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/concepts/tmapconcept.nim b/tests/concepts/tmapconcept.nim index 6b959eff2428..4c1d46bffda9 100644 --- a/tests/concepts/tmapconcept.nim +++ b/tests/concepts/tmapconcept.nim @@ -8,6 +8,7 @@ K=string V=int K=int64 V=string K=int V=int ''' +disabled: true """ import tables, typetraits