diff options
author | Dmitry Atamanov <data-man@users.noreply.github.com> | 2018-08-20 17:55:22 +0300 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-20 16:55:22 +0200 |
commit | b75808c7d992ea47f8d6abc656b881b2aa0f86de (patch) | |
tree | 15db5f0070445def74e12bd957fe54cf5b347712 | |
parent | b28c7d434b16ebd9cc33ef1d6b267b49660153ba (diff) | |
download | Nim-b75808c7d992ea47f8d6abc656b881b2aa0f86de.tar.gz |
Fixes ropes regressions due to the not-nil strings (#8687)
-rw-r--r-- | lib/pure/ropes.nim | 19 | ||||
-rw-r--r-- | tests/stdlib/tropes.nim | 36 |
2 files changed, 46 insertions, 9 deletions
diff --git a/lib/pure/ropes.nim b/lib/pure/ropes.nim index fb371cdce..559afd279 100644 --- a/lib/pure/ropes.nim +++ b/lib/pure/ropes.nim @@ -37,8 +37,6 @@ type length: int data: string # != nil if a leaf -proc isConc(r: Rope): bool {.inline.} = return r.length > 0 - # Note that the left and right pointers are not needed for leafs. # Leaves have relatively high memory overhead (~30 bytes on a 32 # bit machine) and we produce many of them. This is why we cache and @@ -50,12 +48,12 @@ proc isConc(r: Rope): bool {.inline.} = return r.length > 0 proc len*(a: Rope): int {.rtl, extern: "nro$1".} = ## the rope's length if a == nil: result = 0 - else: result = abs a.length + else: result = a.length proc newRope(): Rope = new(result) proc newRope(data: string): Rope = new(result) - result.length = -len(data) + result.length = len(data) result.data = data var @@ -170,7 +168,9 @@ proc `&`*(a, b: Rope): Rope {.rtl, extern: "nroConcRopeRope".} = result = a else: result = newRope() - result.length = abs(a.length) + abs(b.length) + result.length = a.length + b.length + result.left = a + result.right = b proc `&`*(a: Rope, b: string): Rope {.rtl, extern: "nroConcRopeStr".} = ## the concatenation operator for ropes. @@ -199,11 +199,11 @@ proc `[]`*(r: Rope, i: int): char {.rtl, extern: "nroCharAt".} = var j = i if x == nil: return while true: - if not isConc(x): - if x.data.len <% j: return x.data[j] + if x != nil and x.data.len > 0: + if j < x.data.len: return x.data[j] return '\0' else: - if x.left.len >% j: + if x.left.length > j: x = x.left else: x = x.right @@ -215,7 +215,8 @@ iterator leaves*(r: Rope): string = var stack = @[r] while stack.len > 0: var it = stack.pop - while isConc(it): + while it.left != nil: + assert(it.right != nil) stack.add(it.right) it = it.left assert(it != nil) diff --git a/tests/stdlib/tropes.nim b/tests/stdlib/tropes.nim new file mode 100644 index 000000000..59239a600 --- /dev/null +++ b/tests/stdlib/tropes.nim @@ -0,0 +1,36 @@ +discard """ + file: "tropes.nim" + output: '''0 +3 + +123 +3 +6 +123 +123456 +2 +3''' +""" +import ropes + +var + r1 = rope("") + r2 = rope("123") + +echo r1.len +echo r2.len + +echo r1 +echo r2 + +r1.add("123") +r2.add("456") + +echo r1.len +echo r2.len + +echo r1 +echo r2 + +echo r1[1] +echo r2[2] \ No newline at end of file |