diff options
author | Araq <rumpf_a@web.de> | 2011-10-28 17:57:58 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-10-28 17:57:58 +0200 |
commit | 22115a2c6a43709aba02054b77ce2e641f280be1 (patch) | |
tree | be232f47fb7beacb4761e9ebb882265734268401 | |
parent | a0a8934a4f089f8a438da280a4c80051ba3607b5 (diff) | |
download | Nim-22115a2c6a43709aba02054b77ce2e641f280be1.tar.gz |
splicing tested and documented
-rwxr-xr-x | lib/system.nim | 43 | ||||
-rwxr-xr-x | tests/accept/run/tslices.nim | 16 | ||||
-rw-r--r-- | tests/rodfiles/bmethods.nim | 3 | ||||
-rw-r--r-- | tests/rodfiles/bmethods2.nim | 3 | ||||
-rw-r--r-- | tests/rodfiles/deada.nim | 3 | ||||
-rw-r--r-- | tests/rodfiles/deada2.nim | 3 | ||||
-rwxr-xr-x | todo.txt | 31 |
7 files changed, 72 insertions, 30 deletions
diff --git a/lib/system.nim b/lib/system.nim index 885449537..8657efe2a 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -1930,36 +1930,37 @@ proc `[]`*(s: string, x: TSlice[int]): string {.inline.} = ## slice operation for strings. Negative indexes are supported. result = s.substr(x.a-|s, x.b-|s) -template spliceImpl(x, start, endp, spliced: expr): stmt = - var - count = endp - start + 1 - shift = spliced.len - count - newLen = x.len + shift - totalShifted = x.len - (start + count) - firstShifted = newLen - totalShifted - +template spliceImpl(s, a, L, b: expr): stmt = + # make room for additional elements or cut: + var slen = s.len + var shift = b.len - L + var newLen = slen + shift if shift > 0: - setLen(x, newLen) - - for i in countdown(newLen - 1, firstShifted): - shallowCopy(x[i], x[i-shift]) - - for c in countup(0, spliced.len - 1): - x[start + c] = spliced[c] - - if shift < 0: - setLen(x, newLen) + # enlarge: + setLen(s, newLen) + for i in countdown(newLen-1, a+shift+1): shallowCopy(s[i], s[i-shift]) + else: + for i in countup(a+b.len, s.len-1+shift): shallowCopy(s[i], s[i-shift]) + # cut down: + setLen(s, newLen) + # fill the hole: + for i in 0 .. <b.len: s[i+a] = b[i] proc `[]=`*(s: var string, x: TSlice[int], b: string) = ## slice assignment for strings. Negative indexes are supported. If ## ``b.len`` is not exactly the number of elements that are referred to - ## by `x`, a `splice`:idx: is performed. + ## by `x`, a `splice`:idx: is performed: + ## + ## .. code-block:: nimrod + ## var s = "abcdef" + ## s[1 .. -2] = "xyz" + ## assert s == "axyzf" var a = x.a-|s var L = x.b-|s - a + 1 if L == b.len: for i in 0 .. <L: s[i+a] = b[i] else: - spliceImpl(s, x.a, x.b, b) + spliceImpl(s, a, L, b) proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[int]): seq[T] = ## slice operation for arrays. Negative indexes are **not** supported @@ -2015,7 +2016,7 @@ proc `[]=`*[T](s: var seq[T], x: TSlice[int], b: openArray[T]) = if L == b.len: for i in 0 .. <L: s[i+a] = b[i] else: - spliceImpl(s, x.a, x.b, b) + spliceImpl(s, a, L, b) proc getTypeInfo*[T](x: T): pointer {.magic: "GetTypeInfo".} ## get type information for `x`. Ordinary code should not use this, but diff --git a/tests/accept/run/tslices.nim b/tests/accept/run/tslices.nim index 1061b4245..0de1171e3 100755 --- a/tests/accept/run/tslices.nim +++ b/tests/accept/run/tslices.nim @@ -4,6 +4,8 @@ discard """ 456456 456456 Zugr5nd +egerichtetd +verichtetd ''' """ @@ -41,3 +43,17 @@ echo() echo mystr +mystr[4..4] = "u" + +# test full replacement +mystr[.. -2] = "egerichtet" + +echo mystr + +mystr[0..2] = "ve" +echo mystr + +var s = "abcdef" +s[1 .. -2] = "xyz" +assert s == "axyzf" + diff --git a/tests/rodfiles/bmethods.nim b/tests/rodfiles/bmethods.nim index f665efa09..995942ad6 100644 --- a/tests/rodfiles/bmethods.nim +++ b/tests/rodfiles/bmethods.nim @@ -1,6 +1,5 @@ discard """ - output: ''' -derived class + output: '''derived class base class ''' """ diff --git a/tests/rodfiles/bmethods2.nim b/tests/rodfiles/bmethods2.nim index c4b9c37b6..ac24a2201 100644 --- a/tests/rodfiles/bmethods2.nim +++ b/tests/rodfiles/bmethods2.nim @@ -1,6 +1,5 @@ discard """ - output: ''' -derived class 2 + output: '''derived class 2 base class ''' """ diff --git a/tests/rodfiles/deada.nim b/tests/rodfiles/deada.nim index dca776640..3fa4192f8 100644 --- a/tests/rodfiles/deada.nim +++ b/tests/rodfiles/deada.nim @@ -1,6 +1,5 @@ discard """ - output: ''' -246 + output: '''246 ''' """ diff --git a/tests/rodfiles/deada2.nim b/tests/rodfiles/deada2.nim index ee8298371..2925b4d43 100644 --- a/tests/rodfiles/deada2.nim +++ b/tests/rodfiles/deada2.nim @@ -1,6 +1,5 @@ discard """ - output: ''' -246 + output: '''246 xyzabc ''' """ diff --git a/todo.txt b/todo.txt index 6455ca8a4..de27c6fa1 100755 --- a/todo.txt +++ b/todo.txt @@ -5,7 +5,6 @@ Version 0.8.14 - 'let x = y' - fix actors.nim - make threadvar efficient again on linux after testing -- document & test splicing; don't forget to test negative indexes - dead code elim for JS backend @@ -17,6 +16,36 @@ incremental compilation - implement lib/pure/memfiles properly +Destructors +----------- + +A destructor is bound to a proc instead of a type. The proc is then called +an *init proc*. A destructor is called at +scope exit for the local variables (declared with ``var`` or ``let``) +that are initialized with its corresponding init proc: + +.. code-block:: nimrod + proc autoOpen(filename: string): TFile {.destructor: close.} = + result = open(filename) + + var f = autoOpen("abc.txt") + +A template ``atScopeExit`` can easily be defined with this mechanism. However +unfortunately the regex problem is not solved at all: + +.. code-block:: nimrod + if x =~ re"abc": + ... + +We really need some form of escape analysis; ``var`` or ``let`` is not enough! +Hm, but what if the procs declare that property: + +.. code-block:: nimrod + proc `=~` (s: string, pattern: TRegex{.noEscape.}): bool + +So it's bound to a type again? + + version 0.9.0 ============= |