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 )
61 import Char ( chr, ord, isDigit )
65 %************************************************************************
67 \subsection{The @PprStyle@ data type}
69 %************************************************************************
73 = PprUser PrintUnqualified Depth -- Pretty-print in a way that will
74 -- make sense to the ordinary user;
75 -- must be very close to Haskell
78 | PprInterface PrintUnqualified -- Interface generation
80 | PprCode CodeStyle -- Print code; either C or assembler
82 | PprDebug -- Standard debugging output
84 data CodeStyle = CStyle -- The format of labels differs for C and assembler
87 data Depth = AllTheWay
88 | PartWay Int -- 0 => stop
91 type PrintUnqualified = Name -> Bool
92 -- This function tells when it's ok to print
93 -- a (Global) name unqualified
95 alwaysQualify,neverQualify :: PrintUnqualified
96 alwaysQualify n = False
99 defaultUserStyle = mkUserStyle alwaysQualify AllTheWay
101 mkUserStyle unqual depth | opt_PprStyle_Debug = PprDebug
102 | otherwise = PprUser unqual depth
105 Orthogonal to the above printing styles are (possibly) some
106 command-line flags that affect printing (often carried with the
107 style). The most likely ones are variations on how much type info is
110 The following test decides whether or not we are actually generating
111 code (either C or assembly), or generating interface files.
113 %************************************************************************
115 \subsection{The @SDoc@ data type}
117 %************************************************************************
120 type SDoc = PprStyle -> Doc
122 withPprStyle :: PprStyle -> SDoc -> SDoc
123 withPprStyle sty d sty' = d sty
125 pprDeeper :: SDoc -> SDoc
126 pprDeeper d (PprUser unqual (PartWay 0)) = Pretty.text "..."
127 pprDeeper d (PprUser unqual (PartWay n)) = d (PprUser unqual (PartWay (n-1)))
128 pprDeeper d other_sty = d other_sty
130 getPprStyle :: (PprStyle -> SDoc) -> SDoc
131 getPprStyle df sty = df sty sty
135 unqualStyle :: PprStyle -> Name -> Bool
136 unqualStyle (PprUser unqual _) n = unqual n
137 unqualStyle (PprInterface unqual) n = unqual n
138 unqualStyle other n = False
140 codeStyle :: PprStyle -> Bool
141 codeStyle (PprCode _) = True
144 asmStyle :: PprStyle -> Bool
145 asmStyle (PprCode AsmStyle) = True
146 asmStyle other = False
148 ifaceStyle :: PprStyle -> Bool
149 ifaceStyle (PprInterface _) = True
150 ifaceStyle other = False
152 debugStyle :: PprStyle -> Bool
153 debugStyle PprDebug = True
154 debugStyle other = False
156 userStyle :: PprStyle -> Bool
157 userStyle (PprUser _ _) = True
158 userStyle other = False
160 ifPprDebug :: SDoc -> SDoc -- Empty for non-debug style
161 ifPprDebug d sty@PprDebug = d sty
162 ifPprDebug d sty = Pretty.empty
166 printSDoc :: SDoc -> PprStyle -> IO ()
167 printSDoc d sty = printDoc PageMode stdout (d sty)
169 -- I'm not sure whether the direct-IO approach of printDoc
170 -- above is better or worse than the put-big-string approach here
171 printErrs :: PrintUnqualified -> SDoc -> IO ()
172 printErrs unqual doc = printDoc PageMode stderr (doc style)
174 style = mkUserStyle unqual (PartWay opt_PprUserLength)
176 printDump :: SDoc -> IO ()
177 printDump doc = printDoc PageMode stdout (better_doc defaultUserStyle)
179 better_doc = doc $$ text ""
180 -- We used to always print in debug style, but I want
181 -- to try the effect of a more user-ish style (unless you
184 printForUser :: Handle -> PrintUnqualified -> SDoc -> IO ()
185 printForUser handle unqual doc
186 = printDoc PageMode handle (doc (mkUserStyle unqual AllTheWay))
188 -- printForIface prints all on one line for interface files.
189 -- It's called repeatedly for successive lines
190 printForIface :: Handle -> PrintUnqualified -> SDoc -> IO ()
191 printForIface handle unqual doc
192 = printDoc LeftMode handle (doc (PprInterface unqual))
194 -- printForC, printForAsm do what they sound like
195 printForC :: Handle -> SDoc -> IO ()
196 printForC handle doc = printDoc LeftMode handle (doc (PprCode CStyle))
198 printForAsm :: Handle -> SDoc -> IO ()
199 printForAsm handle doc = printDoc LeftMode handle (doc (PprCode AsmStyle))
201 pprCode :: CodeStyle -> SDoc -> SDoc
202 pprCode cs d = withPprStyle (PprCode cs) d
204 -- Can't make SDoc an instance of Show because SDoc is just a function type
205 -- However, Doc *is* an instance of Show
206 -- showSDoc just blasts it out as a string
207 showSDoc :: SDoc -> String
208 showSDoc d = show (d defaultUserStyle)
210 showSDocForUser :: PrintUnqualified -> SDoc -> String
211 showSDocForUser unqual doc = show (doc (mkUserStyle unqual AllTheWay))
213 showSDocUnqual :: SDoc -> String
214 -- Only used in the gruesome HsExpr.isOperator
215 showSDocUnqual d = show (d (mkUserStyle neverQualify AllTheWay))
217 showsPrecSDoc :: Int -> SDoc -> ShowS
218 showsPrecSDoc p d = showsPrec p (d defaultUserStyle)
220 showSDocIface :: SDoc -> String
221 showSDocIface doc = showDocWith OneLineMode (doc (PprInterface alwaysQualify))
223 showSDocDebug :: SDoc -> String
224 showSDocDebug d = show (d PprDebug)
228 docToSDoc :: Doc -> SDoc
229 docToSDoc d = \_ -> d
231 empty sty = Pretty.empty
232 text s sty = Pretty.text s
233 char c sty = Pretty.char c
234 ptext s sty = Pretty.ptext s
235 int n sty = Pretty.int n
236 integer n sty = Pretty.integer n
237 float n sty = Pretty.float n
238 double n sty = Pretty.double n
239 rational n sty = Pretty.rational n
241 parens d sty = Pretty.parens (d sty)
242 braces d sty = Pretty.braces (d sty)
243 brackets d sty = Pretty.brackets (d sty)
244 doubleQuotes d sty = Pretty.doubleQuotes (d sty)
245 angleBrackets d = char '<' <> d <> char '>'
247 -- quotes encloses something in single quotes...
248 -- but it omits them if the thing ends in a single quote
249 -- so that we don't get `foo''. Instead we just have foo'.
250 quotes d sty = case show pp_d of
252 other -> Pretty.quotes pp_d
256 semi sty = Pretty.semi
257 comma sty = Pretty.comma
258 colon sty = Pretty.colon
259 equals sty = Pretty.equals
260 space sty = Pretty.space
261 lparen sty = Pretty.lparen
262 rparen sty = Pretty.rparen
263 lbrack sty = Pretty.lbrack
264 rbrack sty = Pretty.rbrack
265 lbrace sty = Pretty.lbrace
266 rbrace sty = Pretty.rbrace
267 dcolon sty = Pretty.ptext SLIT("::")
268 underscore = char '_'
271 nest n d sty = Pretty.nest n (d sty)
272 (<>) d1 d2 sty = (Pretty.<>) (d1 sty) (d2 sty)
273 (<+>) d1 d2 sty = (Pretty.<+>) (d1 sty) (d2 sty)
274 ($$) d1 d2 sty = (Pretty.$$) (d1 sty) (d2 sty)
275 ($+$) d1 d2 sty = (Pretty.$+$) (d1 sty) (d2 sty)
277 hcat ds sty = Pretty.hcat [d sty | d <- ds]
278 hsep ds sty = Pretty.hsep [d sty | d <- ds]
279 vcat ds sty = Pretty.vcat [d sty | d <- ds]
280 sep ds sty = Pretty.sep [d sty | d <- ds]
281 cat ds sty = Pretty.cat [d sty | d <- ds]
282 fsep ds sty = Pretty.fsep [d sty | d <- ds]
283 fcat ds sty = Pretty.fcat [d sty | d <- ds]
285 hang d1 n d2 sty = Pretty.hang (d1 sty) n (d2 sty)
287 punctuate :: SDoc -> [SDoc] -> [SDoc]
289 punctuate p (d:ds) = go d ds
292 go d (e:es) = (d <> p) : go e es
296 %************************************************************************
298 \subsection[Outputable-class]{The @Outputable@ class}
300 %************************************************************************
303 class Outputable a where
308 instance Outputable Bool where
309 ppr True = ptext SLIT("True")
310 ppr False = ptext SLIT("False")
312 instance Outputable Int where
315 instance Outputable () where
318 instance (Outputable a) => Outputable [a] where
319 ppr xs = brackets (fsep (punctuate comma (map ppr xs)))
321 instance (Outputable a, Outputable b) => Outputable (a, b) where
322 ppr (x,y) = parens (sep [ppr x <> comma, ppr y])
324 instance Outputable a => Outputable (Maybe a) where
325 ppr Nothing = ptext SLIT("Nothing")
326 ppr (Just x) = ptext SLIT("Just") <+> ppr x
328 -- ToDo: may not be used
329 instance (Outputable a, Outputable b, Outputable c) => Outputable (a, b, c) where
331 parens (sep [ppr x <> comma,
335 instance (Outputable a, Outputable b, Outputable c, Outputable d) =>
336 Outputable (a, b, c, d) where
338 parens (sep [ppr x <> comma,
343 instance Outputable FastString where
344 ppr fs = text (unpackFS fs) -- Prints an unadorned string,
345 -- no double quotes or anything
347 #if __GLASGOW_HASKELL__ < 410
348 -- Assume we have only 8-bit Chars.
350 pprHsChar :: Int -> SDoc
351 pprHsChar c = char '\'' <> text (showCharLit c "") <> char '\''
353 pprHsString :: FAST_STRING -> SDoc
354 pprHsString fs = doubleQuotes (text (foldr showCharLit "" (_UNPK_INT_ fs)))
356 showCharLit :: Int -> String -> String
358 | c == ord '\"' = "\\\"" ++ rest
359 | c == ord '\'' = "\\\'" ++ rest
360 | c == ord '\\' = "\\\\" ++ rest
361 | c >= 0x20 && c <= 0x7E = chr c : rest
362 | c == ord '\a' = "\\a" ++ rest
363 | c == ord '\b' = "\\b" ++ rest
364 | c == ord '\f' = "\\f" ++ rest
365 | c == ord '\n' = "\\n" ++ rest
366 | c == ord '\r' = "\\r" ++ rest
367 | c == ord '\t' = "\\t" ++ rest
368 | c == ord '\v' = "\\v" ++ rest
369 | otherwise = ('\\':) $ shows (fromIntegral c :: Word32) $ case rest of
370 d:_ | isDigit d -> "\\&" ++ rest
374 -- We have 31-bit Chars and will simply use Show instances
375 -- of Char and String.
377 pprHsChar :: Int -> SDoc
378 pprHsChar c | c > 0x10ffff = char '\\' <> text (show (fromIntegral c :: Word32))
379 | otherwise = text (show (chr c))
381 pprHsString :: FastString -> SDoc
382 pprHsString fs = text (show (unpackFS fs))
386 instance Show FastString where
387 showsPrec p fs = showsPrecSDoc p (ppr fs)
391 %************************************************************************
393 \subsection{Other helper functions}
395 %************************************************************************
398 pprCols = (100 :: Int) -- could make configurable
400 printDoc :: Mode -> Handle -> Doc -> IO ()
401 printDoc mode hdl doc
402 = fullRender mode pprCols 1.5 put done doc
404 put (Chr c) next = hPutChar hdl c >> next
405 put (Str s) next = hPutStr hdl s >> next
406 put (PStr s) next = hPutFS hdl s >> next
408 done = hPutChar hdl '\n'
410 showDocWith :: Mode -> Doc -> String
412 = fullRender mode 100 1.5 put "" doc
415 put (Str s1) s2 = s1 ++ s2
416 put (PStr s1) s2 = _UNPK_ s1 ++ s2
421 pprWithCommas :: (a -> SDoc) -> [a] -> SDoc
422 pprWithCommas pp xs = hsep (punctuate comma (map pp xs))
424 interppSP :: Outputable a => [a] -> SDoc
425 interppSP xs = hsep (map ppr xs)
427 interpp'SP :: Outputable a => [a] -> SDoc
428 interpp'SP xs = hsep (punctuate comma (map ppr xs))
430 pprQuotedList :: Outputable a => [a] -> SDoc
431 -- [x,y,z] ==> `x', `y', `z'
432 pprQuotedList xs = hsep (punctuate comma (map (quotes . ppr) xs))
436 %************************************************************************
438 \subsection{Printing numbers verbally}
440 %************************************************************************
442 @speakNth@ converts an integer to a verbal index; eg 1 maps to
446 speakNth :: Int -> SDoc
448 speakNth 1 = ptext SLIT("first")
449 speakNth 2 = ptext SLIT("second")
450 speakNth 3 = ptext SLIT("third")
451 speakNth 4 = ptext SLIT("fourth")
452 speakNth 5 = ptext SLIT("fifth")
453 speakNth 6 = ptext SLIT("sixth")
454 speakNth n = hcat [ int n, text st_nd_rd_th ]
456 st_nd_rd_th | n_rem_10 == 1 = "st"
457 | n_rem_10 == 2 = "nd"
458 | n_rem_10 == 3 = "rd"
461 n_rem_10 = n `rem` 10
465 speakNTimes :: Int {- >=1 -} -> SDoc
466 speakNTimes t | t == 1 = ptext SLIT("once")
467 | t == 2 = ptext SLIT("twice")
468 | otherwise = int t <+> ptext SLIT("times")
472 %************************************************************************
474 \subsection{Error handling}
476 %************************************************************************
479 pprPanic :: String -> SDoc -> a
480 pprError :: String -> SDoc -> a
481 pprTrace :: String -> SDoc -> a -> a
482 pprPanic = pprAndThen panic
483 pprError = pprAndThen error
484 pprTrace = pprAndThen trace
486 pprPanic# heading pretty_msg = panic# (show (doc PprDebug))
488 doc = text heading <+> pretty_msg
490 pprAndThen :: (String -> a) -> String -> SDoc -> a
491 pprAndThen cont heading pretty_msg = cont (show (doc PprDebug))
493 doc = sep [text heading, nest 4 pretty_msg]
495 assertPprPanic :: String -> Int -> SDoc -> a
496 assertPprPanic file line msg
497 = panic (show (doc PprDebug))
499 doc = sep [hsep[text "ASSERT failed! file",
501 text "line", int line],
504 warnPprTrace :: Bool -> String -> Int -> SDoc -> a -> a
505 warnPprTrace False file line msg x = x
506 warnPprTrace True file line msg x
507 = trace (show (doc PprDebug)) x
509 doc = sep [hsep [text "WARNING: file", text file, text "line", int line],