diff --git a/moon.mod.json b/moon.mod.json index 03944a2..59c75fd 100644 --- a/moon.mod.json +++ b/moon.mod.json @@ -1,6 +1,6 @@ { "name": "Yoorkin/prettyprinter", - "version": "0.4.1", + "version": "0.4.3", "readme": "README.md", "repository": "https://github.com/Yoorkin/prettyprinter", "license": "Apache-2.0", diff --git a/src/document.mbt b/src/document.mbt index 8d877e1..8ed7d9a 100644 --- a/src/document.mbt +++ b/src/document.mbt @@ -93,9 +93,10 @@ pub impl Show for Document with output(self, buf) { ///| fn render_document(width : Int, doc : Document) -> String { - let buf = @buffer.new() + let buf = StringBuilder::new() + let queue = [(0, false, doc)] let mut column = 0 - fn aux(indent, flat_mode, doc) { + while queue.pop() is Some((indent, flat_mode, doc)) { match doc { Empty => () Text(s) => { @@ -103,14 +104,14 @@ fn render_document(width : Int, doc : Document) -> String { column += s.length() } Concat(_, l, r) => { - aux(indent, flat_mode, l) - aux(indent, flat_mode, r) + queue.push((indent, flat_mode, r)) + queue.push((indent, flat_mode, l)) } Switch(_, l, r) => if flat_mode { - aux(indent, flat_mode, l) + queue.push((indent, flat_mode, l)) } else { - aux(indent, flat_mode, r) + queue.push((indent, flat_mode, r)) } Line => { buf.write_char('\n') @@ -119,14 +120,12 @@ fn render_document(width : Int, doc : Document) -> String { } column = indent } - Nest(_, i, d) => aux(indent + i, flat_mode, d) + Nest(_, i, d) => queue.push((indent + i, flat_mode, d)) Group(req, d) => { let flat_mode = Space(column) + req <= Space(width) - aux(indent, flat_mode, d) + queue.push((indent, flat_mode, d)) } } } - - aux(0, true, doc) - buf.contents().to_unchecked_string() + buf.to_string() } diff --git a/src/test.mbt b/src/test.mbt new file mode 100644 index 0000000..9c94d49 --- /dev/null +++ b/src/test.mbt @@ -0,0 +1,8 @@ +///| +test "stack-safe test for render" { + let mut doc = empty + for i in 0..=3000 { + doc = doc + text(i.to_string()) + line + } + doc.pretty() |> ignore +}