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, withPprStyleDoc, pprDeeper,
16 codeStyle, userStyle, debugStyle, asmStyle,
17 ifPprDebug, unqualStyle,
21 interppSP, interpp'SP, pprQuotedList, pprWithCommas,
23 text, char, ftext, ptext,
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, printForUser,
38 showSDoc, showSDocForUser, showSDocDebug,
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(..) )
59 import Word ( Word32 )
60 import IO ( Handle, stderr, stdout, hFlush )
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 withPprStyleDoc :: PprStyle -> SDoc -> Doc
129 withPprStyleDoc sty d = d sty
131 pprDeeper :: SDoc -> SDoc
132 pprDeeper d (PprUser unqual (PartWay 0)) = Pretty.text "..."
133 pprDeeper d (PprUser unqual (PartWay n)) = d (PprUser unqual (PartWay (n-1)))
134 pprDeeper d other_sty = d other_sty
136 getPprStyle :: (PprStyle -> SDoc) -> SDoc
137 getPprStyle df sty = df sty sty
141 unqualStyle :: PprStyle -> Name -> Bool
142 unqualStyle (PprUser unqual _) n = unqual n
143 unqualStyle (PprInterface unqual) n = unqual n
144 unqualStyle other n = False
146 codeStyle :: PprStyle -> Bool
147 codeStyle (PprCode _) = True
150 asmStyle :: PprStyle -> Bool
151 asmStyle (PprCode AsmStyle) = True
152 asmStyle other = False
154 debugStyle :: PprStyle -> Bool
155 debugStyle PprDebug = True
156 debugStyle other = False
158 userStyle :: PprStyle -> Bool
159 userStyle (PprUser _ _) = True
160 userStyle other = False
162 ifPprDebug :: SDoc -> SDoc -- Empty for non-debug style
163 ifPprDebug d sty@PprDebug = d sty
164 ifPprDebug d sty = Pretty.empty
169 printSDoc :: SDoc -> PprStyle -> IO ()
171 Pretty.printDoc PageMode stdout (d sty)
174 -- I'm not sure whether the direct-IO approach of Pretty.printDoc
175 -- above is better or worse than the put-big-string approach here
176 printErrs :: PrintUnqualified -> SDoc -> IO ()
177 printErrs unqual doc = do
178 Pretty.printDoc PageMode stderr (doc style)
181 style = mkUserStyle unqual (PartWay opt_PprUserLength)
183 printDump :: SDoc -> IO ()
185 Pretty.printDoc PageMode stdout (better_doc defaultUserStyle)
188 better_doc = doc $$ text ""
189 -- We used to always print in debug style, but I want
190 -- to try the effect of a more user-ish style (unless you
193 printForUser :: Handle -> PrintUnqualified -> SDoc -> IO ()
194 printForUser handle unqual doc
195 = Pretty.printDoc PageMode handle (doc (mkUserStyle unqual AllTheWay))
197 -- printForC, printForAsm do what they sound like
198 printForC :: Handle -> SDoc -> IO ()
199 printForC handle doc = Pretty.printDoc LeftMode handle (doc (PprCode CStyle))
201 printForAsm :: Handle -> SDoc -> IO ()
202 printForAsm handle doc = Pretty.printDoc LeftMode handle (doc (PprCode AsmStyle))
204 pprCode :: CodeStyle -> SDoc -> SDoc
205 pprCode cs d = withPprStyle (PprCode cs) d
207 mkCodeStyle :: CodeStyle -> PprStyle
208 mkCodeStyle = PprCode
210 -- Can't make SDoc an instance of Show because SDoc is just a function type
211 -- However, Doc *is* an instance of Show
212 -- showSDoc just blasts it out as a string
213 showSDoc :: SDoc -> String
214 showSDoc d = show (d defaultUserStyle)
216 showSDocForUser :: PrintUnqualified -> SDoc -> String
217 showSDocForUser unqual doc = show (doc (mkUserStyle unqual AllTheWay))
219 showSDocUnqual :: SDoc -> String
220 -- Only used in the gruesome HsExpr.isOperator
221 showSDocUnqual d = show (d (mkUserStyle neverQualify AllTheWay))
223 showsPrecSDoc :: Int -> SDoc -> ShowS
224 showsPrecSDoc p d = showsPrec p (d defaultUserStyle)
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 ftext s sty = Pretty.ftext s
238 ptext s sty = Pretty.ptext s
239 int n sty = Pretty.int n
240 integer n sty = Pretty.integer n
241 float n sty = Pretty.float n
242 double n sty = Pretty.double n
243 rational n sty = Pretty.rational n
245 parens d sty = Pretty.parens (d sty)
246 braces d sty = Pretty.braces (d sty)
247 brackets d sty = Pretty.brackets (d sty)
248 doubleQuotes d sty = Pretty.doubleQuotes (d sty)
249 angleBrackets d = char '<' <> d <> char '>'
251 -- quotes encloses something in single quotes...
252 -- but it omits them if the thing ends in a single quote
253 -- so that we don't get `foo''. Instead we just have foo'.
254 quotes d sty = case show pp_d of
256 other -> Pretty.quotes pp_d
260 semi sty = Pretty.semi
261 comma sty = Pretty.comma
262 colon sty = Pretty.colon
263 equals sty = Pretty.equals
264 space sty = Pretty.space
265 lparen sty = Pretty.lparen
266 rparen sty = Pretty.rparen
267 lbrack sty = Pretty.lbrack
268 rbrack sty = Pretty.rbrack
269 lbrace sty = Pretty.lbrace
270 rbrace sty = Pretty.rbrace
271 dcolon sty = Pretty.ptext SLIT("::")
272 underscore = char '_'
275 nest n d sty = Pretty.nest n (d 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)
279 ($+$) d1 d2 sty = (Pretty.$+$) (d1 sty) (d2 sty)
281 hcat ds sty = Pretty.hcat [d sty | d <- ds]
282 hsep ds sty = Pretty.hsep [d sty | d <- ds]
283 vcat ds sty = Pretty.vcat [d sty | d <- ds]
284 sep ds sty = Pretty.sep [d sty | d <- ds]
285 cat ds sty = Pretty.cat [d sty | d <- ds]
286 fsep ds sty = Pretty.fsep [d sty | d <- ds]
287 fcat ds sty = Pretty.fcat [d sty | d <- ds]
289 hang d1 n d2 sty = Pretty.hang (d1 sty) n (d2 sty)
291 punctuate :: SDoc -> [SDoc] -> [SDoc]
293 punctuate p (d:ds) = go d ds
296 go d (e:es) = (d <> p) : go e es
300 %************************************************************************
302 \subsection[Outputable-class]{The @Outputable@ class}
304 %************************************************************************
307 class Outputable a where
312 instance Outputable Bool where
313 ppr True = ptext SLIT("True")
314 ppr False = ptext SLIT("False")
316 instance Outputable Int where
319 instance Outputable () where
322 instance (Outputable a) => Outputable [a] where
323 ppr xs = brackets (fsep (punctuate comma (map ppr xs)))
325 instance (Outputable a, Outputable b) => Outputable (a, b) where
326 ppr (x,y) = parens (sep [ppr x <> comma, ppr y])
328 instance Outputable a => Outputable (Maybe a) where
329 ppr Nothing = ptext SLIT("Nothing")
330 ppr (Just x) = ptext SLIT("Just") <+> ppr x
332 -- ToDo: may not be used
333 instance (Outputable a, Outputable b, Outputable c) => Outputable (a, b, c) where
335 parens (sep [ppr x <> comma,
339 instance (Outputable a, Outputable b, Outputable c, Outputable d) =>
340 Outputable (a, b, c, d) where
342 parens (sep [ppr x <> comma,
347 instance Outputable FastString where
348 ppr fs = text (unpackFS fs) -- Prints an unadorned string,
349 -- no double quotes or anything
351 #if __GLASGOW_HASKELL__ < 410
352 -- Assume we have only 8-bit Chars.
354 pprHsChar :: Int -> SDoc
355 pprHsChar c = char '\'' <> text (showCharLit c "") <> char '\''
357 pprHsString :: FastString -> SDoc
358 pprHsString fs = doubleQuotes (text (foldr showCharLit "" (unpackIntFS fs)))
360 showCharLit :: Int -> String -> String
362 | c == ord '\"' = "\\\"" ++ rest
363 | c == ord '\'' = "\\\'" ++ rest
364 | c == ord '\\' = "\\\\" ++ rest
365 | c >= 0x20 && c <= 0x7E = chr c : rest
366 | c == ord '\a' = "\\a" ++ rest
367 | c == ord '\b' = "\\b" ++ rest
368 | c == ord '\f' = "\\f" ++ rest
369 | c == ord '\n' = "\\n" ++ rest
370 | c == ord '\r' = "\\r" ++ rest
371 | c == ord '\t' = "\\t" ++ rest
372 | c == ord '\v' = "\\v" ++ rest
373 | otherwise = ('\\':) $ shows (fromIntegral c :: Word32) $ case rest of
374 d:_ | isDigit d -> "\\&" ++ rest
378 -- We have 31-bit Chars and will simply use Show instances
379 -- of Char and String.
381 pprHsChar :: Int -> SDoc
382 pprHsChar c | c > 0x10ffff = char '\\' <> text (show (fromIntegral c :: Word32))
383 | otherwise = text (show (chr c))
385 pprHsString :: FastString -> SDoc
386 pprHsString fs = text (show (unpackFS fs))
390 instance Show FastString where
391 showsPrec p fs = showsPrecSDoc p (ppr fs)
395 %************************************************************************
397 \subsection{Other helper functions}
399 %************************************************************************
402 pprWithCommas :: (a -> SDoc) -> [a] -> SDoc
403 pprWithCommas pp xs = hsep (punctuate comma (map pp xs))
405 interppSP :: Outputable a => [a] -> SDoc
406 interppSP xs = hsep (map ppr xs)
408 interpp'SP :: Outputable a => [a] -> SDoc
409 interpp'SP xs = hsep (punctuate comma (map ppr xs))
411 pprQuotedList :: Outputable a => [a] -> SDoc
412 -- [x,y,z] ==> `x', `y', `z'
413 pprQuotedList xs = hsep (punctuate comma (map (quotes . ppr) xs))
417 %************************************************************************
419 \subsection{Printing numbers verbally}
421 %************************************************************************
423 @speakNth@ converts an integer to a verbal index; eg 1 maps to
427 speakNth :: Int -> SDoc
429 speakNth 1 = ptext SLIT("first")
430 speakNth 2 = ptext SLIT("second")
431 speakNth 3 = ptext SLIT("third")
432 speakNth 4 = ptext SLIT("fourth")
433 speakNth 5 = ptext SLIT("fifth")
434 speakNth 6 = ptext SLIT("sixth")
435 speakNth n = hcat [ int n, text suffix ]
437 suffix | n <= 20 = "th" -- 11,12,13 are non-std
438 | last_dig == 1 = "st"
439 | last_dig == 2 = "nd"
440 | last_dig == 3 = "rd"
443 last_dig = n `rem` 10
447 speakNTimes :: Int {- >=1 -} -> SDoc
448 speakNTimes t | t == 1 = ptext SLIT("once")
449 | t == 2 = ptext SLIT("twice")
450 | otherwise = int t <+> ptext SLIT("times")
454 %************************************************************************
456 \subsection{Error handling}
458 %************************************************************************
461 pprPanic :: String -> SDoc -> a
462 pprError :: String -> SDoc -> a
463 pprTrace :: String -> SDoc -> a -> a
464 pprPanic = pprAndThen panic
465 pprError = pprAndThen error
466 pprTrace = pprAndThen trace
468 pprPanic# heading pretty_msg = panic# (show (doc PprDebug))
470 doc = text heading <+> pretty_msg
472 pprAndThen :: (String -> a) -> String -> SDoc -> a
473 pprAndThen cont heading pretty_msg = cont (show (doc PprDebug))
475 doc = sep [text heading, nest 4 pretty_msg]
477 assertPprPanic :: String -> Int -> SDoc -> a
478 assertPprPanic file line msg
479 = panic (show (doc PprDebug))
481 doc = sep [hsep[text "ASSERT failed! file",
483 text "line", int line],
486 warnPprTrace :: Bool -> String -> Int -> SDoc -> a -> a
487 warnPprTrace False file line msg x = x
488 warnPprTrace True file line msg x
489 = trace (show (doc PprDebug)) x
491 doc = sep [hsep [text "WARNING: file", text file, text "line", int line],