Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 98627c2

Browse files
committed
Clean up res_doc.fits
1 parent 980a7dd commit 98627c2

File tree

1 file changed

+40
-80
lines changed

1 file changed

+40
-80
lines changed

src/res_doc.ml

+40-80
Original file line numberDiff line numberDiff line change
@@ -133,91 +133,51 @@ let join ~sep docs =
133133
in
134134
concat(loop [] sep docs)
135135

136+
let fits w stack =
137+
let width = ref w in
138+
let result = ref None in
136139

137-
let rec fits w doc = match doc with
138-
| _ when w < 0 -> false
139-
| [] -> true
140-
| (_ind, _mode, Text txt)::rest -> fits (w - String.length txt) rest
141-
| (ind, mode, Indent doc)::rest -> fits w ((ind + 2, mode, doc)::rest)
142-
| (_ind, Flat, LineBreak break)::rest ->
143-
if break = Hard || break = Literal then true
144-
else
145-
let w = if break = Classic then w - 1 else w in
146-
fits w rest
147-
| (_ind, _mode, Nil)::rest -> fits w rest
148-
| (_ind, Break, LineBreak _break)::_rest -> true
149-
| (ind, mode, Group {shouldBreak = forceBreak; doc})::rest ->
150-
let mode = if forceBreak then Break else mode in
151-
fits w ((ind, mode, doc)::rest)
152-
| (ind, mode, IfBreaks {yes = breakDoc; no = flatDoc})::rest ->
153-
if mode = Break then
154-
fits w ((ind, mode, breakDoc)::rest)
155-
else
156-
fits w ((ind, mode, flatDoc)::rest)
157-
| (ind, mode, Concat docs)::rest ->
158-
let ops = List.map (fun doc -> (ind, mode, doc)) docs in
159-
fits w (List.append ops rest)
160-
(* | (_ind, _mode, Cursor)::rest -> fits w rest *)
161-
| (_ind, _mode, LineSuffix _)::rest -> fits w rest
162-
| (_ind, _mode, BreakParent)::rest -> fits w rest
163-
| (ind, mode, CustomLayout (hd::_))::rest ->
164-
(* TODO: if we have nested custom layouts, what we should do here? *)
165-
fits w ((ind, mode, hd)::rest)
166-
| (_ind, _mode, CustomLayout _)::rest ->
167-
fits w rest
168-
169-
(* Version of fits that does not allocate *)
170-
let fits0 w ops =
171-
let wr = ref w in
172-
let res = ref None in
173-
let rec doOp ind mode doc = match (mode, doc) with
174-
| _ when !res <> None -> ()
175-
| _ when !wr < 0 -> res := Some false
176-
| _, Text txt -> wr := !wr - (String.length txt)
177-
| _, Indent doc -> doOp (ind + 2) mode doc
178-
| Flat, LineBreak break ->
179-
if break = Hard || break = Literal then res := Some true
180-
else wr := if break = Classic then !wr - 1 else !wr
181-
| _, Nil -> ()
182-
| Break, LineBreak _break -> res := Some true
183-
| _, Group {shouldBreak = forceBreak; doc} ->
184-
let mode = if forceBreak then Break else mode in
185-
doOp ind mode doc
186-
| _, IfBreaks {yes = breakDoc; no = flatDoc} ->
187-
if mode = Break then
188-
doOp ind mode breakDoc
189-
else
190-
doOp ind mode flatDoc
191-
| _, Concat docs ->
192-
doConcat ind mode docs
193-
| _, LineSuffix _ -> ()
140+
let rec calculate indent mode doc =
141+
match mode, doc with
142+
| _ when result.contents != None -> ()
143+
| _ when width.contents < 0 -> result := Some false
144+
| _, Nil
145+
| _, LineSuffix _
194146
| _, BreakParent -> ()
147+
| _, Text txt -> width := width.contents - (String.length txt)
148+
| _, Indent doc -> calculate (indent + 2) mode doc
149+
| Flat, LineBreak Hard
150+
| Flat, LineBreak Literal -> result := Some true
151+
| Flat, LineBreak Classic -> width := width.contents - 1
152+
| Flat, LineBreak Soft -> ()
153+
| Break, LineBreak _ -> result := Some true
154+
| _, Group {shouldBreak = true; doc} -> calculate indent Break doc
155+
| _, Group {doc} -> calculate indent mode doc
156+
| Break, IfBreaks {yes = breakDoc} -> calculate indent mode breakDoc
157+
| Flat, IfBreaks {no = flatDoc} -> calculate indent mode flatDoc
158+
| _, Concat docs -> calculateConcat indent mode docs
195159
| _, CustomLayout (hd::_) ->
196160
(* TODO: if we have nested custom layouts, what we should do here? *)
197-
doOp ind mode hd
198-
| _, CustomLayout [] ->
199-
()
200-
and doConcat ind mode docs = match docs with
201-
| _ when !res <> None -> ()
202-
| [] -> ()
203-
| doc::rest ->
204-
doOp ind mode doc;
205-
doConcat ind mode rest
161+
calculate indent mode hd
162+
| _, CustomLayout [] -> ()
163+
and calculateConcat indent mode docs =
164+
if result.contents == None then (
165+
match docs with
166+
| [] -> ()
167+
| doc::rest ->
168+
calculate indent mode doc;
169+
calculateConcat indent mode rest
170+
)
206171
in
207-
let rec doOps ops = match ops with
208-
| _ when !res != None -> !res = Some true
209-
| (ind, mode, doc)::rest ->
210-
doOp ind mode doc;
211-
doOps rest
212-
| [] -> !wr >= 0
172+
let rec calculateAll stack =
173+
match result.contents, stack with
174+
| Some r, _ -> r
175+
| None, [] -> !width >= 0
176+
| None, (indent, mode, doc)::rest ->
177+
calculate indent mode doc;
178+
calculateAll rest
213179
in
214-
doOps ops
215-
216-
217-
let _ = fits0
218-
let _ = fits
219-
220-
let fits = fits0
180+
calculateAll stack
221181

222182
let toString ~width doc =
223183
let doc = propagateForcedBreaks doc in
@@ -293,7 +253,7 @@ let toString ~width doc =
293253
process ~pos:0 [] (List.rev suffices)
294254
end
295255
in
296-
process ~pos:0 [] [0, Flat, doc];
256+
process ~pos:0 [] [(0, Flat, doc)];
297257
MiniBuffer.contents buffer
298258

299259

0 commit comments

Comments
 (0)