@@ -11,6 +11,7 @@ import Data.Foldable (foldr, intercalate)
1111import Data.Generic.Rep (class Generic )
1212import Data.Generic.Rep.Show (genericShow )
1313import Data.Int as Int
14+ import Data.Lazy (Lazy , force , defer )
1415import Data.List as List
1516import Data.List.Lazy as LL
1617import Data.Maybe (Maybe (..))
@@ -589,6 +590,20 @@ data SimpleDoc = SFail
589590 | SText Int String SimpleDoc
590591 | SLine Int SimpleDoc
591592
593+ data LazySimpleDoc = SFail'
594+ | SEmpty'
595+ | SChar' Char (Lazy LazySimpleDoc )
596+ | SText' Int String (Lazy LazySimpleDoc )
597+ | SLine' Int (Lazy LazySimpleDoc )
598+
599+ forceSimpleDoc :: LazySimpleDoc -> SimpleDoc
600+ forceSimpleDoc = case _ of
601+ SFail' -> SFail
602+ SEmpty' -> SEmpty
603+ SChar' c x -> SChar c (forceSimpleDoc $ force x)
604+ SText' i s x -> SText i s (forceSimpleDoc $ force x)
605+ SLine' i x -> SLine i (forceSimpleDoc $ force x)
606+
592607derive instance simpleDocEq :: Eq SimpleDoc
593608derive instance simpleDocOrd :: Ord SimpleDoc
594609derive instance genericSimpleDoc :: Generic SimpleDoc _
@@ -748,7 +763,7 @@ renderPretty = renderFits fits1
748763renderSmart :: Number -> Int -> Doc -> SimpleDoc
749764renderSmart = renderFits fitsR
750765
751- renderFits :: (Int -> Int -> Int -> SimpleDoc -> Boolean )
766+ renderFits :: (Int -> Int -> Int -> LazySimpleDoc -> Boolean )
752767 -> Number -> Int -> Doc -> SimpleDoc
753768renderFits fits rfrac w headNode
754769 -- I used to do a @SSGR [Reset]@ here, but if you do that it will result
@@ -759,22 +774,23 @@ renderFits fits rfrac w headNode
759774 -- What I "really" want to do here is do an initial Reset iff there is some
760775 -- ANSI color within the Doc, but that's a bit fiddly. I'll fix it if someone
761776 -- complains!
762- = best 0 0 (Cons 0 headNode Nil )
777+ = forceSimpleDoc $ best 0 0 (Cons 0 headNode Nil )
763778 where
764779 -- r :: the ribbon width in characters
765780 r = max 0 (min w (Int .round (Int .toNumber w * rfrac)))
766781
767782 -- best :: n = indentation of current line
768783 -- k = current column
769784 -- (ie. (k >= n) && (k - n == count of inserted characters)
770- best n k Nil = SEmpty
785+ best :: Int -> Int -> Docs -> LazySimpleDoc
786+ best n k Nil = SEmpty'
771787 best n k (Cons i d ds)
772788 = case d of
773- Fail -> SFail
789+ Fail -> SFail'
774790 Empty -> best n k ds
775- Char c -> let k' = k+1 in SChar c (best n k' ds)
776- Text l s -> let k' = k+l in SText l s (best n k' ds)
777- Line -> SLine i (best i i ds)
791+ Char c -> let k' = k+1 in SChar' c (defer \_ -> best n k' ds)
792+ Text l s -> let k' = k+l in SText' l s (defer\_ -> best n k' ds)
793+ Line -> SLine' i (defer \_ -> best i i ds)
778794 FlatAlt x _ -> best n k (Cons i x ds)
779795 Cat x y -> best n k (Cons i x (Cons i y ds))
780796 Nest j x -> let i' = i+j in best n k (Cons i' x ds)
@@ -800,13 +816,13 @@ renderFits fits rfrac w headNode
800816 in if fits w (min n k) width' x' then x' else let y' = best n k (Cons i y ds) in y'
801817
802818-- | @fits1@ does 1 line lookahead.
803- fits1 :: Int -> Int -> Int -> SimpleDoc -> Boolean
804- fits1 _ _ w x | w < 0 = false
805- fits1 _ _ w SFail = false
806- fits1 _ _ w SEmpty = true
807- fits1 p m w (SChar c x) = fits1 p m (w - 1 ) x
808- fits1 p m w (SText l s x) = fits1 p m (w - l) x
809- fits1 _ _ w (SLine i x) = true
819+ fits1 :: Int -> Int -> Int -> LazySimpleDoc -> Boolean
820+ fits1 _ _ w x | w < 0 = false
821+ fits1 _ _ w SFail' = false
822+ fits1 _ _ w SEmpty' = true
823+ fits1 p m w (SChar' c x) = fits1 p m (w - 1 ) (force x)
824+ fits1 p m w (SText' l s x) = fits1 p m (w - l) (force x)
825+ fits1 _ _ w (SLine' i x) = true
810826
811827-- | @fitsR@ has a little more lookahead: assuming that nesting roughly
812828-- | corresponds to syntactic depth, @fitsR@ checks that not only the current line
@@ -818,14 +834,14 @@ fits1 _ _ w (SLine i x) = true
818834-- | p = pagewidth
819835-- | m = minimum nesting level to fit in
820836-- | w = the width in which to fit the first line
821- fitsR :: Int -> Int -> Int -> SimpleDoc -> Boolean
822- fitsR p m w x | w < 0 = false
823- fitsR p m w SFail = false
824- fitsR p m w SEmpty = true
825- fitsR p m w (SChar c x) = fitsR p m (w - 1 ) x
826- fitsR p m w (SText l s x) = fitsR p m (w - l) x
827- fitsR p m w (SLine i x) | m < i = fitsR p m (p - i) x
828- | otherwise = true
837+ fitsR :: Int -> Int -> Int -> LazySimpleDoc -> Boolean
838+ fitsR p m w x | w < 0 = false
839+ fitsR p m w SFail' = false
840+ fitsR p m w SEmpty' = true
841+ fitsR p m w (SChar' c x) = fitsR p m (w - 1 ) (force x)
842+ fitsR p m w (SText' l s x) = fitsR p m (w - l) (force x)
843+ fitsR p m w (SLine' i x) | m < i = fitsR p m (p - i) (force x)
844+ | otherwise = true
829845
830846-- ---------------------------------------------------------
831847-- renderCompact: renders documents without indentation
0 commit comments