-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make be
stack safe
#11
base: master
Are you sure you want to change the base?
Conversation
src/Prettier/Printer.purs
Outdated
(Cons (Tuple i LINE) z) -> f $ Loop $ State { f: map (Line i), w, k: i, l: z } | ||
(Cons (Tuple i (UNION x y)) z) -> Done Nil | ||
-- let l' = f $ Loop $ State { f: id, w, k, l: (Tuple i x) : z } | ||
-- in if fits (w - k) l' then l' else f $ Loop $ State { f: id, w, k, l: (Tuple i y) : z } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what to do here just yet.
This is what I came up with, but I don't know if it broke anything (I can't find a non-trivial test for newtype State = State
{ f :: Doc -> Doc
, k :: Int
, l :: List (Tuple Int DOC)
-- Based on the generated document, should it keep the result or try a new state
, next :: Maybe (Tuple (Doc -> Boolean) State)
}
be :: Int -> Int -> List (Tuple Int DOC) -> Doc
be w k0 l0 = tailRec go $ State { f: id, k: k0, l: l0, next: Nothing }
where
go :: State -> Step State Doc
go (State { f, k, l, next }) = case l of
List.Nil ->
-- obtain the result by running the function on the empty document
let res = f Nil in
case next of
-- if this one fails, continue at the next state
Just (Tuple p st) | not p res ->
Loop st
-- otherwise return what we got
_ -> Done res
(Cons (Tuple _ NIL) z) -> Loop $
State { f, k, l: z, next }
(Cons (Tuple i (APPEND x y)) z) -> Loop $
State { f, k, l: (Tuple i x) : (Tuple i y) : z, next }
(Cons (Tuple i (NEST j x)) z) -> Loop $
State { f, k, l: (Tuple (i + j) x) : z, next }
(Cons (Tuple _ (TEXT s)) z) -> Loop $
State { f: f <<< Text s, k: (k + String.length s), l: z, next }
(Cons (Tuple i LINE) z) -> Loop $
State { f: f <<< Line i, k: i, l: z, next }
(Cons (Tuple i (UNION x y)) z) ->
let
-- add a continuation that tests whether the previous doc is too long
trial = Tuple (fits (w - k)) nextSt
nextSt = State { f, k, l: (Tuple i y) : z, next }
in Loop $ State { f, k, l: (Tuple i x) : z, next: Just trial } Basically I make it into a little linked list of predicates (does the first guess fit?) and other documents to try with I don't think Also note that Laziness would help with the |
@MonoidMusician I've committed and pushed your changes to facilitate more detailed discussion on the diff. |
This is a rough first attempt at trying to fix #10.