From 48d4cad0a28eaf12674f2d532ec64391fc10f9e4 Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Thu, 5 Jun 2014 10:25:57 -0400 Subject: [PATCH] lib/standard/ropes: Added a forward postfix iterator on Rope. Signed-off-by: Lucas Bajolet --- lib/standard/ropes.nit | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/lib/standard/ropes.nit b/lib/standard/ropes.nit index d1f7398..01e09c4 100644 --- a/lib/standard/ropes.nit +++ b/lib/standard/ropes.nit @@ -111,6 +111,9 @@ abstract class Rope redef fun length do return root.length + # Iterator on the nodes of the rope, in forward postfix order + private fun postfix(from: Int): Postfix do return new Postfix.from(self, from) + # Path to the Leaf for `position` private fun node_at(position: Int): Path do @@ -306,3 +309,81 @@ private class IteratorElement var done = false end +# Simple Postfix iterator on the nodes of a Rope +private class Postfix + super IndexedIterator[RopeNode] + + # Target Rope to iterate on + var target: Rope + + # Current position in Rope + var pos: Int + + # Visited nodes + var stack = new List[IteratorElement] + + init from(tgt: Rope, pos: Int) + do + self.target = tgt + self.pos = pos + if pos < 0 or pos >= tgt.length then return + var path = tgt.node_at(pos) + self.pos -= path.offset + for i in path.stack do + var item = new IteratorElement(i.node) + item.left = true + if i.right then item.right = true + stack.push item + end + var item = new IteratorElement(path.leaf) + item.done = true + stack.push item + end + + redef fun item + do + assert is_ok + return stack.last.node + end + + redef fun is_ok do return not stack.is_empty + + redef fun index do return pos + + redef fun next do + if stack.is_empty then return + if pos > target.length-1 then + stack.clear + return + end + var lst = stack.last + if lst.done then + if lst.node isa Leaf then + pos += lst.node.length + end + stack.pop + next + return + end + if not lst.left then + lst.left = true + var nod = lst.node + if nod isa Concat and nod.left != null then + stack.push(new IteratorElement(nod.left.as(not null))) + next + return + end + end + if not lst.right then + lst.right = true + var nod = lst.node + if nod isa Concat and nod.right != null then + stack.push(new IteratorElement(nod.right.as(not null))) + next + return + end + end + lst.done = true + end +end + -- 1.7.9.5