2 % (c) The GRASP Project, Glasgow University, 1992-1998
4 \section[Outputable]{Classes for pretty-printing}
6 Defines classes for pretty-printing and forcing, both forms of
12 Outputable(..), -- Class
14 PprStyle, CodeStyle(..), PrintUnqualified, alwaysQualify,
15 getPprStyle, withPprStyle, pprDeeper,
16 codeStyle, ifaceStyle, userStyle, debugStyle, asmStyle,
17 ifPprDebug, unqualStyle,
21 interppSP, interpp'SP, pprQuotedList, pprWithCommas,
24 int, integer, float, double, rational,
25 parens, brackets, braces, quotes, doubleQuotes, angleBrackets,
26 semi, comma, colon, dcolon, space, equals, dot,
27 lparen, rparen, lbrack, rbrack, lbrace, rbrace, underscore,
28 (<>), (<+>), hcat, hsep,
33 speakNth, speakNTimes,
35 printSDoc, printErrs, printDump,
36 printForC, printForAsm, printForIface, printForUser,
38 showSDoc, showSDocForUser, showSDocDebug, showSDocIface,
39 showSDocUnqual, showsPrecSDoc,
40 pprHsChar, pprHsString,
44 pprPanic, pprPanic#, pprError, pprTrace, assertPprPanic, warnPprTrace,
45 trace, panic, panic#, assertPanic
48 #include "HsVersions.h"
51 import {-# SOURCE #-} Name( Name )
53 import CmdLineOpts ( opt_PprStyle_Debug, opt_PprUserLength )
55 import qualified Pretty
56 import Pretty ( Doc, Mode(..), TextDetails(..), fullRender )
59 import Word ( Word32 )
60 import IO ( Handle, hPutChar, hPutStr, stderr, stdout )
62 #if __GLASGOW_HASKELL__ < 410
63 import Char ( ord, isDigit )
68 %************************************************************************
70 \subsection{The @PprStyle@ data type}
72 %************************************************************************
76 = PprUser PrintUnqualified Depth -- Pretty-print in a way that will
77 -- make sense to the ordinary user;
78 -- must be very close to Haskell
81 | PprInterface PrintUnqualified -- Interface generation
83 | PprCode CodeStyle -- Print code; either C or assembler
85 | PprDebug -- Standard debugging output
87 data CodeStyle = CStyle -- The format of labels differs for C and assembler
90 data Depth = AllTheWay
91 | PartWay Int -- 0 => stop
94 type PrintUnqualified = Name -> Bool
95 -- This function tells when it's ok to print
96 -- a (Global) name unqualified
98 alwaysQualify,neverQualify :: PrintUnqualified
99 alwaysQualify n = False
100 neverQualify n = True
102 defaultUserStyle = mkUserStyle alwaysQualify AllTheWay
104 mkUserStyle unqual depth | opt_PprStyle_Debug = PprDebug
105 | otherwise = PprUser unqual depth
108 Orthogonal to the above printing styles are (possibly) some
109 command-line flags that affect printing (often carried with the
110 style). The most likely ones are variations on how much type info is
113 The following test decides whether or not we are actually generating
114 code (either C or assembly), or generating interface files.
116 %************************************************************************
118 \subsection{The @SDoc@ data type}
120 %************************************************************************
123 type SDoc = PprStyle -> Doc
125 withPprStyle :: PprStyle -> SDoc -> SDoc
126 withPprStyle sty d sty' = d sty
128 pprDeeper :: SDoc -> SDoc
129 pprDeeper d (PprUser unqual (PartWay 0)) = Pretty.text "..."
130 pprDeeper d (PprUser unqual (PartWay n)) = d (PprUser unqual (PartWay (n-1)))
131 pprDeeper d other_sty = d other_sty
133 getPprStyle :: (PprStyle -> SDoc) -> SDoc
134 getPprStyle df sty = df sty sty
138 unqualStyle :: PprStyle -> Name -> Bool
139 unqualStyle (PprUser unqual _) n = unqual n
140 unqualStyle (PprInterface unqual) n = unqual n
141 unqualStyle other n = False
143 codeStyle :: PprStyle -> Bool
144 codeStyle (PprCode _) = True
147 asmStyle :: PprStyle -> Bool
148 asmStyle (PprCode AsmStyle) = True
149 asmStyle other = False
151 ifaceStyle :: PprStyle -> Bool
152 ifaceStyle (PprInterface _) = True
153 ifaceStyle other = False
155 debugStyle :: PprStyle -> Bool
156 debugStyle PprDebug = True
157 debugStyle other = False
159 userStyle :: PprStyle -> Bool
160 userStyle (PprUser _ _) = True
161 userStyle other = False
163 ifPprDebug :: SDoc -> SDoc -- Empty for non-debug style
164 ifPprDebug d sty@PprDebug = d sty
165 ifPprDebug d sty = Pretty.empty
169 printSDoc :: SDoc -> PprStyle -> IO ()
170 printSDoc d sty = printDoc PageMode stdout (d sty)
172 -- I'm not sure whether the direct-IO approach of printDoc
173 -- above is better or worse than the put-big-string approach here
174 printErrs :: PrintUnqualified -> SDoc -> IO ()
175 printErrs unqual doc = printDoc PageMode stderr (doc style)
177 style = mkUserStyle unqual (PartWay opt_PprUserLength)
179 printDump :: SDoc -> IO ()
180 printDump doc = printDoc PageMode stdout (better_doc defaultUserStyle)
182 better_doc = doc $$ text ""
183 -- We used to always print in debug style, but I want
184 -- to try the effect of a more user-ish style (unless you
187 printForUser :: Handle -> PrintUnqualified -> SDoc -> IO ()
188 printForUser handle unqual doc
189 = printDoc PageMode handle (doc (mkUserStyle unqual AllTheWay))
191 -- printForIface prints all on one line for interface files.
192 -- It's called repeatedly for successive lines
193 printForIface :: Handle -> PrintUnqualified -> SDoc -> IO ()
194 printForIface handle unqual doc
195 = printDoc LeftMode handle (doc (PprInterface unqual))
197 -- printForC, printForAsm do what they sound like
198 printForC :: Handle -> SDoc -> IO ()
199 printForC handle doc = printDoc LeftMode handle (doc (PprCode CStyle))
201 printForAsm :: Handle -> SDoc -> IO ()
202 printForAsm handle doc = printDoc LeftMode handle (doc (PprCode AsmStyle))
204 pprCode :: CodeStyle -> SDoc -> SDoc
205 pprCode cs d = withPprStyle (PprCode cs) d
207 -- Can't make SDoc an instance of Show because SDoc is just a function type
208 -- However, Doc *is* an instance of Show
209 -- showSDoc just blasts it out as a string
210 showSDoc :: SDoc -> String
211 showSDoc d = show (d defaultUserStyle)
213 showSDocForUser :: PrintUnqualified -> SDoc -> String
214 showSDocForUser unqual doc = show (doc (mkUserStyle unqual AllTheWay))
216 showSDocUnqual :: SDoc -> String
217 -- Only used in the gruesome HsExpr.isOperator
218 showSDocUnqual d = show (d (mkUserStyle neverQualify AllTheWay))
220 showsPrecSDoc :: Int -> SDoc -> ShowS
221 showsPrecSDoc p d = showsPrec p (d defaultUserStyle)
223 showSDocIface :: SDoc -> String
224 showSDocIface doc = showDocWith OneLineMode (doc (PprInterface alwaysQualify))
226 showSDocDebug :: SDoc -> String
227 showSDocDebug d = show (d PprDebug)
231 docToSDoc :: Doc -> SDoc
232 docToSDoc d = \_ -> d
234 empty sty = Pretty.empty
235 text s sty = Pretty.text s
236 char c sty = Pretty.char c
237 ptext s sty = Pretty.ptext s
238 int n sty = Pretty.int n
239 integer n sty = Pretty.integer n
240 float n sty = Pretty.float n
241 double n sty = Pretty.double n
242 rational n sty = Pretty.rational n
244 parens d sty = Pretty.parens (d sty)
245 braces d sty = Pretty.braces (d sty)
246 brackets d sty = Pretty.brackets (d sty)
247 doubleQuotes d sty = Pretty.doubleQuotes (d sty)
248 angleBrackets d = char '<' <> d <> char '>'
250 -- quotes encloses something in single quotes...
251 -- but it omits them if the thing ends in a single quote
252 -- so that we don't get `foo''. Instead we just have foo'.
253 quotes d sty = case show pp_d of
255 other -> Pretty.quotes pp_d
259 semi sty = Pretty.semi
260 comma sty = Pretty.comma
261 colon sty = Pretty.colon
262 equals sty = Pretty.equals
263 space sty = Pretty.space
264 lparen sty = Pretty.lparen
265 rparen sty = Pretty.rparen
266 lbrack sty = Pretty.lbrack
267 rbrack sty = Pretty.rbrack
268 lbrace sty = Pretty.lbrace
269 rbrace sty = Pretty.rbrace
270 dcolon sty = Pretty.ptext SLIT("::")
271 underscore = char '_'
274 nest n d sty = Pretty.nest n (d sty)
275 (<>) d1 d2 sty = (Pretty.<>) (d1 sty) (d2 sty)
276 (<+>) d1 d2 sty = (Pretty.<+>) (d1 sty) (d2 sty)
277 ($$) d1 d2 sty = (Pretty.$$) (d1 sty) (d2 sty)
278 ($+$) d1 d2 sty = (Pretty.$+$) (d1 sty) (d2 sty)
280 hcat ds sty = Pretty.hcat [d sty | d <- ds]
281 hsep ds sty = Pretty.hsep [d sty | d <- ds]
282 vcat ds sty = Pretty.vcat [d sty | d <- ds]
283 sep ds sty = Pretty.sep [d sty | d <- ds]
284 cat ds sty = Pretty.cat [d sty | d <- ds]
285 fsep ds sty = Pretty.fsep [d sty | d <- ds]
286 fcat ds sty = Pretty.fcat [d sty | d <- ds]
288 hang d1 n d2 sty = Pretty.hang (d1 sty) n (d2 sty)
290 punctuate :: SDoc -> [SDoc] -> [SDoc]
292 punctuate p (d:ds) = go d ds
295 go d (e:es) = (d <> p) : go e es
299 %************************************************************************
301 \subsection[Outputable-class]{The @Outputable@ class}
303 %************************************************************************
306 class Outputable a where
311 instance Outputable Bool where
312 ppr True = ptext SLIT("True")
313 ppr False = ptext SLIT("False")
315 instance Outputable Int where
318 instance Outputable () where
321 instance (Outputable a) => Outputable [a] where
322 ppr xs = brackets (fsep (punctuate comma (map ppr xs)))
324 instance (Outputable a, Outputable b) => Outputable (a, b) where
325 ppr (x,y) = parens (sep [ppr x <> comma, ppr y])
327 instance Outputable a => Outputable (Maybe a) where
328 ppr Nothing = ptext SLIT("Nothing")
329 ppr (Just x) = ptext SLIT("Just") <+> ppr x
331 -- ToDo: may not be used
332 instance (Outputable a, Outputable b, Outputable c) => Outputable (a, b, c) where
334 parens (sep [ppr x <> comma,
338 instance (Outputable a, Outputable b, Outputable c, Outputable d) =>
339 Outputable (a, b, c, d) where
341 parens (sep [ppr x <> comma,
346 instance Outputable FastString where
347 ppr fs = text (unpackFS fs) -- Prints an unadorned string,
348 -- no double quotes or anything
350 #if __GLASGOW_HASKELL__ < 410
351 -- Assume we have only 8-bit Chars.
353 pprHsChar :: Int -> SDoc
354 pprHsChar c = char '\'' <> text (showCharLit c "") <> char '\''
356 pprHsString :: FAST_STRING -> SDoc
357 pprHsString fs = doubleQuotes (text (foldr showCharLit "" (_UNPK_INT_ fs)))
359 showCharLit :: Int -> String -> String
361 | c == ord '\"' = "\\\"" ++ rest
362 | c == ord '\'' = "\\\'" ++ rest
363 | c == ord '\\' = "\\\\" ++ rest
364 | c >= 0x20 && c <= 0x7E = chr c : rest
365 | c == ord '\a' = "\\a" ++ rest
366 | c == ord '\b' = "\\b" ++ rest
367 | c == ord '\f' = "\\f" ++ rest
368 | c == ord '\n' = "\\n" ++ rest
369 | c == ord '\r' = "\\r" ++ rest
370 | c == ord '\t' = "\\t" ++ rest
371 | c == ord '\v' = "\\v" ++ rest
372 | otherwise = ('\\':) $ shows (fromIntegral c :: Word32) $ case rest of
373 d:_ | isDigit d -> "\\&" ++ rest
377 -- We have 31-bit Chars and will simply use Show instances
378 -- of Char and String.
380 pprHsChar :: Int -> SDoc
381 pprHsChar c | c > 0x10ffff = char '\\' <> text (show (fromIntegral c :: Word32))
382 | otherwise = text (show (chr c))
384 pprHsString :: FastString -> SDoc
385 pprHsString fs = text (show (unpackFS fs))
389 instance Show FastString where
390 showsPrec p fs = showsPrecSDoc p (ppr fs)
394 %************************************************************************
396 \subsection{Other helper functions}
398 %************************************************************************
401 pprCols = (100 :: Int) -- could make configurable
403 printDoc :: Mode -> Handle -> Doc -> IO ()
404 printDoc mode hdl doc
405 = fullRender mode pprCols 1.5 put done doc
407 put (Chr c) next = hPutChar hdl c >> next
408 put (Str s) next = hPutStr hdl s >> next
409 put (PStr s) next = hPutFS hdl s >> next
411 done = hPutChar hdl '\n'
413 showDocWith :: Mode -> Doc -> String
415 = fullRender mode 100 1.5 put "" doc
418 put (Str s1) s2 = s1 ++ s2
419 put (PStr s1) s2 = _UNPK_ s1 ++ s2
424 pprWithCommas :: (a -> SDoc) -> [a] -> SDoc
425 pprWithCommas pp xs = hsep (punctuate comma (map pp xs))
427 interppSP :: Outputable a => [a] -> SDoc
428 interppSP xs = hsep (map ppr xs)
430 interpp'SP :: Outputable a => [a] -> SDoc
431 interpp'SP xs = hsep (punctuate comma (map ppr xs))
433 pprQuotedList :: Outputable a => [a] -> SDoc
434 -- [x,y,z] ==> `x', `y', `z'
435 pprQuotedList xs = hsep (punctuate comma (map (quotes . ppr) xs))
439 %************************************************************************
441 \subsection{Printing numbers verbally}
443 %************************************************************************
445 @speakNth@ converts an integer to a verbal index; eg 1 maps to
449 speakNth :: Int -> SDoc
451 speakNth 1 = ptext SLIT("first")
452 speakNth 2 = ptext SLIT("second")
453 speakNth 3 = ptext SLIT("third")
454 speakNth 4 = ptext SLIT("fourth")
455 speakNth 5 = ptext SLIT("fifth")
456 speakNth 6 = ptext SLIT("sixth")
457 speakNth n = hcat [ int n, text st_nd_rd_th ]
459 st_nd_rd_th | n_rem_10 == 1 = "st"
460 | n_rem_10 == 2 = "nd"
461 | n_rem_10 == 3 = "rd"
464 n_rem_10 = n `rem` 10
468 speakNTimes :: Int {- >=1 -} -> SDoc
469 speakNTimes t | t == 1 = ptext SLIT("once")
470 | t == 2 = ptext SLIT("twice")
471 | otherwise = int t <+> ptext SLIT("times")
475 %************************************************************************
477 \subsection{Error handling}
479 %************************************************************************
482 pprPanic :: String -> SDoc -> a
483 pprError :: String -> SDoc -> a
484 pprTrace :: String -> SDoc -> a -> a
485 pprPanic = pprAndThen panic
486 pprError = pprAndThen error
487 pprTrace = pprAndThen trace
489 pprPanic# heading pretty_msg = panic# (show (doc PprDebug))
491 doc = text heading <+> pretty_msg
493 pprAndThen :: (String -> a) -> String -> SDoc -> a
494 pprAndThen cont heading pretty_msg = cont (show (doc PprDebug))
496 doc = sep [text heading, nest 4 pretty_msg]
498 assertPprPanic :: String -> Int -> SDoc -> a
499 assertPprPanic file line msg
500 = panic (show (doc PprDebug))
502 doc = sep [hsep[text "ASSERT failed! file",
504 text "line", int line],
507 warnPprTrace :: Bool -> String -> Int -> SDoc -> a -> a
508 warnPprTrace False file line msg x = x
509 warnPprTrace True file line msg x
510 = trace (show (doc PprDebug)) x
512 doc = sep [hsep [text "WARNING: file", text file, text "line", int line],