From 62878287c17c3fe9d4004e456a648db86d0c5bca Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 14 Jan 2025 17:32:49 +0100 Subject: [PATCH 1/6] More efficient `breakString` (#169) --- src/ocamlutil/pretty.ml | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/ocamlutil/pretty.ml b/src/ocamlutil/pretty.ml index 7063c21a2..4eb515704 100644 --- a/src/ocamlutil/pretty.ml +++ b/src/ocamlutil/pretty.ml @@ -70,26 +70,27 @@ type doc = | Unmark (* Break a string at \n *) -let rec breakString (acc: doc) (str: string) : doc = - (* Printf.printf "breaking string %s\n" str; *) - match (try Some (String.index str '\n') with Not_found -> None) with - | None -> if acc = Nil then Text str else CText (acc, str) - | Some r -> - (* Printf.printf "r=%d\n" r; *) - let len = String.length str in - if r > 0 then begin - (* Printf.printf "Taking %s\n" (String.sub str 0 r); *) - let acc' = Concat(CText (acc, String.sub str 0 r), Line) in - if r = len - 1 then (* The last one *) - acc' - else begin - (* Printf.printf "Continuing with %s\n" (String.sub str (r + 1) (len - r - 1)); *) - breakString acc' - (String.sub str (r + 1) (len - r - 1)) +(* Replaces an earlier implementation that relied on repeatedly calling sub, with one inspired by the standard library *) +let breakString init s = + if s = "" then + Nil + else + let r = ref init in + let j = ref (String.length s) in + for i = String.length s - 1 downto 0 do + let text = Text (String.sub s (i + 1) (!j - i - 1)) in + if String.unsafe_get s i = '\n' then begin + if !r = Nil then + r := Concat(Line, text) + else + r := Concat(Line, Concat(text, !r)); + j := i end - end else (* The first is a newline *) - breakString (Concat(acc, Line)) - (String.sub str (r + 1) (len - r - 1)) + done; + if !r = Nil then + Text (String.sub s 0 !j) + else + Concat(Text (String.sub s 0 !j), Concat(Line, !r)) let nil = Nil @@ -591,7 +592,7 @@ let print_with_state ~width f = topAlignAbsCol := old_topAlignAbsCol; breakAllMode := old_breakAllMode in - + match f () with | r -> finally (); From 2faf7321e54c448c234d9d586f576733aa93c816 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 14 Jan 2025 17:35:37 +0100 Subject: [PATCH 2/6] Pull out variable --- src/ocamlutil/pretty.ml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ocamlutil/pretty.ml b/src/ocamlutil/pretty.ml index 4eb515704..34fbda42f 100644 --- a/src/ocamlutil/pretty.ml +++ b/src/ocamlutil/pretty.ml @@ -87,10 +87,11 @@ let breakString init s = j := i end done; + let text = Text (String.sub s 0 !j) in if !r = Nil then - Text (String.sub s 0 !j) + text else - Concat(Text (String.sub s 0 !j), Concat(Line, !r)) + Concat(text, Concat(Line, !r)) let nil = Nil From f99b977d90793676daab783835775d3364ec667a Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 14 Jan 2025 17:52:41 +0100 Subject: [PATCH 3/6] Fix duplicate lines --- src/ocamlutil/pretty.ml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ocamlutil/pretty.ml b/src/ocamlutil/pretty.ml index 34fbda42f..02a9cbf76 100644 --- a/src/ocamlutil/pretty.ml +++ b/src/ocamlutil/pretty.ml @@ -73,25 +73,25 @@ type doc = (* Replaces an earlier implementation that relied on repeatedly calling sub, with one inspired by the standard library *) let breakString init s = if s = "" then - Nil + init else let r = ref init in let j = ref (String.length s) in for i = String.length s - 1 downto 0 do - let text = Text (String.sub s (i + 1) (!j - i - 1)) in if String.unsafe_get s i = '\n' then begin - if !r = Nil then - r := Concat(Line, text) + let text = (String.sub s (i + 1) (!j - i - 1)) in + (if !r = Nil then + r := CText(Line, text) else - r := Concat(Line, Concat(text, !r)); + r := Concat(Line, CText(!r, text))); j := i end done; - let text = Text (String.sub s 0 !j) in + let text = String.sub s 0 !j in if !r = Nil then - text + Text text else - Concat(text, Concat(Line, !r)) + CText(!r, text) let nil = Nil From 98fb22b0b9b98b48d22649cad1d4538471ff3226 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 14 Jan 2025 21:27:41 +0100 Subject: [PATCH 4/6] Fix acc position --- src/ocamlutil/pretty.ml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ocamlutil/pretty.ml b/src/ocamlutil/pretty.ml index 02a9cbf76..09e539a01 100644 --- a/src/ocamlutil/pretty.ml +++ b/src/ocamlutil/pretty.ml @@ -71,19 +71,19 @@ type doc = (* Break a string at \n *) (* Replaces an earlier implementation that relied on repeatedly calling sub, with one inspired by the standard library *) -let breakString init s = +let breakString s = if s = "" then - init + Nil else - let r = ref init in + let r = ref Nil in let j = ref (String.length s) in for i = String.length s - 1 downto 0 do if String.unsafe_get s i = '\n' then begin let text = (String.sub s (i + 1) (!j - i - 1)) in (if !r = Nil then - r := CText(Line, text) + r := Concat(Line,Text text) else - r := Concat(Line, CText(!r, text))); + r := Concat(Line, Concat(Text text, !r))); j := i end done; @@ -91,11 +91,11 @@ let breakString init s = if !r = Nil then Text text else - CText(!r, text) + Concat(Text text,!r) let nil = Nil -let text s = breakString nil s +let text s = breakString s let num i = text (string_of_int i) let num64 i = text (Int64.to_string i) let real f = text (string_of_float f) @@ -707,7 +707,7 @@ let gprintf (finish : doc -> 'b) else s in - collect (breakString acc str) (succ j)) + collect (Concat(acc, breakString str)) (succ j)) | 'c' -> Obj.magic(fun c -> collect (dctext1 acc (String.make 1 c)) (succ j)) From bd042da6f47e240ded2db947b1aa80f0d05c7251 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 14 Jan 2025 21:31:04 +0100 Subject: [PATCH 5/6] Indent --- src/ocamlutil/pretty.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ocamlutil/pretty.ml b/src/ocamlutil/pretty.ml index 09e539a01..4425c41c9 100644 --- a/src/ocamlutil/pretty.ml +++ b/src/ocamlutil/pretty.ml @@ -79,11 +79,11 @@ let breakString s = let j = ref (String.length s) in for i = String.length s - 1 downto 0 do if String.unsafe_get s i = '\n' then begin - let text = (String.sub s (i + 1) (!j - i - 1)) in + let text = Text (String.sub s (i + 1) (!j - i - 1)) in (if !r = Nil then - r := Concat(Line,Text text) + r := Concat(Line, text) else - r := Concat(Line, Concat(Text text, !r))); + r := Concat(Line, Concat(text, !r))); j := i end done; @@ -91,7 +91,7 @@ let breakString s = if !r = Nil then Text text else - Concat(Text text,!r) + Concat(Text text, !r) let nil = Nil From 4d77053d5b3d7fe3e462ff6353b610b773406969 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Fri, 17 Jan 2025 13:51:55 +0100 Subject: [PATCH 6/6] Simplify generated string --- src/ocamlutil/pretty.ml | 42 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/ocamlutil/pretty.ml b/src/ocamlutil/pretty.ml index 4425c41c9..18fcb75c3 100644 --- a/src/ocamlutil/pretty.ml +++ b/src/ocamlutil/pretty.ml @@ -72,26 +72,30 @@ type doc = (* Break a string at \n *) (* Replaces an earlier implementation that relied on repeatedly calling sub, with one inspired by the standard library *) let breakString s = - if s = "" then - Nil - else - let r = ref Nil in - let j = ref (String.length s) in - for i = String.length s - 1 downto 0 do - if String.unsafe_get s i = '\n' then begin - let text = Text (String.sub s (i + 1) (!j - i - 1)) in - (if !r = Nil then - r := Concat(Line, text) + let r = ref Nil in + let j = ref (String.length s) in + for i = String.length s - 1 downto 0 do + if String.unsafe_get s i = '\n' then begin + let text = String.sub s (i + 1) (!j - i - 1) in + (if text = "" then + if !r = Nil then + r := Line else - r := Concat(Line, Concat(text, !r))); - j := i - end - done; - let text = String.sub s 0 !j in - if !r = Nil then - Text text - else - Concat(Text text, !r) + r := Concat(Line, !r) + else + if !r = Nil then + r := Concat(Line, Text text) + else + r := Concat(Line, Concat(Text text, !r)) + ); + j := i + end + done; + let text = String.sub s 0 !j in + if text = "" then + !r + else + Concat(Text text, !r) let nil = Nil