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
10 {-# OPTIONS -fno-prune-tydecls #-}
11 -- Hopefully temporary; 3.02 complained about not being able
12 -- to see the consructors for ForeignObj
15 Outputable(..), -- Class
17 PprStyle, CodeStyle(..),
18 getPprStyle, withPprStyle, pprDeeper,
19 codeStyle, ifaceStyle, userStyle, debugStyle, asmStyle,
20 ifPprDebug, ifNotPprForUser,
23 interppSP, interpp'SP, pprQuotedList,
26 int, integer, float, double, rational,
27 parens, brackets, braces, quotes, doubleQuotes,
28 semi, comma, colon, dcolon, space, equals, dot,
29 lparen, rparen, lbrack, rbrack, lbrace, rbrace, underscore,
30 (<>), (<+>), hcat, hsep,
35 speakNth, speakNTimes,
37 printSDoc, printErrs, printDump,
38 printForC, printForAsm, printForIface,
40 showSDoc, showSDocDebug, showsPrecSDoc, pprFSAsString,
44 pprPanic, pprPanic#, pprError, pprTrace, assertPprPanic, warnPprTrace,
45 trace, panic, panic#, assertPanic
48 #include "HsVersions.h"
51 import IO ( Handle, hPutChar, hPutStr, stderr, stdout )
52 import CmdLineOpts ( opt_PprStyle_Debug, opt_PprUserLength )
54 import qualified Pretty
55 import Pretty ( Doc, Mode(..), TextDetails(..), fullRender )
62 %************************************************************************
64 \subsection{The @PprStyle@ data type}
66 %************************************************************************
70 = PprUser Depth -- Pretty-print in a way that will
71 -- make sense to the ordinary user;
72 -- must be very close to Haskell
75 | PprDebug -- Standard debugging output
77 | PprInterface -- Interface generation
79 | PprCode CodeStyle -- Print code; either C or assembler
82 data CodeStyle = CStyle -- The format of labels differs for C and assembler
85 data Depth = AllTheWay
86 | PartWay Int -- 0 => stop
89 Orthogonal to the above printing styles are (possibly) some
90 command-line flags that affect printing (often carried with the
91 style). The most likely ones are variations on how much type info is
94 The following test decides whether or not we are actually generating
95 code (either C or assembly), or generating interface files.
97 %************************************************************************
99 \subsection{The @SDoc@ data type}
101 %************************************************************************
104 type SDoc = PprStyle -> Doc
106 withPprStyle :: PprStyle -> SDoc -> SDoc
107 withPprStyle sty d sty' = d sty
109 pprDeeper :: SDoc -> SDoc
110 pprDeeper d (PprUser (PartWay 0)) = Pretty.text "..."
111 pprDeeper d (PprUser (PartWay n)) = d (PprUser (PartWay (n-1)))
112 pprDeeper d other_sty = d other_sty
114 getPprStyle :: (PprStyle -> SDoc) -> SDoc
115 getPprStyle df sty = df sty sty
119 codeStyle :: PprStyle -> Bool
120 codeStyle (PprCode _) = True
123 asmStyle :: PprStyle -> Bool
124 asmStyle (PprCode AsmStyle) = True
125 asmStyle other = False
127 ifaceStyle :: PprStyle -> Bool
128 ifaceStyle PprInterface = True
129 ifaceStyle other = False
131 debugStyle :: PprStyle -> Bool
132 debugStyle PprDebug = True
133 debugStyle other = False
135 userStyle :: PprStyle -> Bool
136 userStyle (PprUser _) = True
137 userStyle other = False
141 ifNotPprForUser :: SDoc -> SDoc -- Returns empty document for User style
142 ifNotPprForUser d sty@(PprUser _) = Pretty.empty
143 ifNotPprForUser d sty = d sty
145 ifPprDebug :: SDoc -> SDoc -- Empty for non-debug style
146 ifPprDebug d sty@PprDebug = d sty
147 ifPprDebug d sty = Pretty.empty
151 printSDoc :: SDoc -> PprStyle -> IO ()
152 printSDoc d sty = printDoc PageMode stdout (d sty)
154 -- I'm not sure whether the direct-IO approach of printDoc
155 -- above is better or worse than the put-big-string approach here
156 printErrs :: SDoc -> IO ()
157 printErrs doc = printDoc PageMode stderr (final_doc user_style)
159 final_doc = doc -- $$ text ""
160 user_style = mkUserStyle (PartWay opt_PprUserLength)
162 printDump :: SDoc -> IO ()
163 printDump doc = printDoc PageMode stderr (final_doc user_style)
165 final_doc = doc $$ text ""
166 user_style = mkUserStyle (PartWay opt_PprUserLength)
167 -- We used to always print in debug style, but I want
168 -- to try the effect of a more user-ish style (unless you
172 -- printForC, printForAsm doe what they sound like
173 printForC :: Handle -> SDoc -> IO ()
174 printForC handle doc = printDoc LeftMode handle (doc (PprCode CStyle))
176 printForAsm :: Handle -> SDoc -> IO ()
177 printForAsm handle doc = printDoc LeftMode handle (doc (PprCode AsmStyle))
179 -- printForIface prints all on one line for interface files.
180 -- It's called repeatedly for successive lines
181 printForIface :: Handle -> SDoc -> IO ()
182 printForIface handle doc = printDoc OneLineMode handle (doc PprInterface)
184 pprCode :: CodeStyle -> SDoc -> SDoc
185 pprCode cs d = withPprStyle (PprCode cs) d
187 -- Can't make SDoc an instance of Show because SDoc is just a function type
188 -- However, Doc *is* an instance of Show
189 -- showSDoc just blasts it out as a string
190 showSDoc :: SDoc -> String
191 showSDoc d = show (d (mkUserStyle AllTheWay))
193 showSDocDebug :: SDoc -> String
194 showSDocDebug d = show (d PprDebug)
196 showsPrecSDoc :: Int -> SDoc -> ShowS
197 showsPrecSDoc p d = showsPrec p (d (mkUserStyle AllTheWay))
199 mkUserStyle depth | opt_PprStyle_Debug = PprDebug
200 | otherwise = PprUser depth
204 empty sty = Pretty.empty
205 text s sty = Pretty.text s
206 char c sty = Pretty.char c
207 ptext s sty = Pretty.ptext s
208 int n sty = Pretty.int n
209 integer n sty = Pretty.integer n
210 float n sty = Pretty.float n
211 double n sty = Pretty.double n
212 rational n sty = Pretty.rational n
214 parens d sty = Pretty.parens (d sty)
215 braces d sty = Pretty.braces (d sty)
216 brackets d sty = Pretty.brackets (d sty)
217 doubleQuotes d sty = Pretty.doubleQuotes (d sty)
219 -- quotes encloses something in single quotes...
220 -- but it omits them if the thing ends in a single quote
221 -- so that we don't get `foo''. Instead we just have foo'.
222 quotes d sty = case show pp_d of
224 other -> Pretty.quotes pp_d
228 semi sty = Pretty.semi
229 comma sty = Pretty.comma
230 colon sty = Pretty.colon
231 equals sty = Pretty.equals
232 space sty = Pretty.space
233 lparen sty = Pretty.lparen
234 rparen sty = Pretty.rparen
235 lbrack sty = Pretty.lbrack
236 rbrack sty = Pretty.rbrack
237 lbrace sty = Pretty.lbrace
238 rbrace sty = Pretty.rbrace
239 dcolon sty = Pretty.ptext SLIT("::")
240 underscore = char '_'
243 nest n d sty = Pretty.nest n (d sty)
244 (<>) d1 d2 sty = (Pretty.<>) (d1 sty) (d2 sty)
245 (<+>) d1 d2 sty = (Pretty.<+>) (d1 sty) (d2 sty)
246 ($$) d1 d2 sty = (Pretty.$$) (d1 sty) (d2 sty)
247 ($+$) d1 d2 sty = (Pretty.$+$) (d1 sty) (d2 sty)
249 hcat ds sty = Pretty.hcat [d sty | d <- ds]
250 hsep ds sty = Pretty.hsep [d sty | d <- ds]
251 vcat ds sty = Pretty.vcat [d sty | d <- ds]
252 sep ds sty = Pretty.sep [d sty | d <- ds]
253 cat ds sty = Pretty.cat [d sty | d <- ds]
254 fsep ds sty = Pretty.fsep [d sty | d <- ds]
255 fcat ds sty = Pretty.fcat [d sty | d <- ds]
257 hang d1 n d2 sty = Pretty.hang (d1 sty) n (d2 sty)
259 punctuate :: SDoc -> [SDoc] -> [SDoc]
261 punctuate p (d:ds) = go d ds
264 go d (e:es) = (d <> p) : go e es
268 %************************************************************************
270 \subsection[Outputable-class]{The @Outputable@ class}
272 %************************************************************************
275 class Outputable a where
280 instance Outputable Bool where
281 ppr True = ptext SLIT("True")
282 ppr False = ptext SLIT("False")
284 instance Outputable Int where
287 instance (Outputable a) => Outputable [a] where
288 ppr xs = brackets (fsep (punctuate comma (map ppr xs)))
290 instance (Outputable a, Outputable b) => Outputable (a, b) where
291 ppr (x,y) = parens (sep [ppr x <> comma, ppr y])
293 instance Outputable a => Outputable (Maybe a) where
294 ppr Nothing = text "Nothing"
295 ppr (Just x) = text "Just" <+> ppr x
297 -- ToDo: may not be used
298 instance (Outputable a, Outputable b, Outputable c) => Outputable (a, b, c) where
300 parens (sep [ppr x <> comma,
304 instance Outputable FastString where
305 ppr fs = text (unpackFS fs) -- Prints an unadorned string,
306 -- no double quotes or anything
308 pprFSAsString :: FastString -> SDoc -- The Char instance of Show prints
309 pprFSAsString fs = text (showList (unpackFS fs) "") -- strings with double quotes and escapes
311 instance Show FastString where
312 showsPrec p fs = showsPrecSDoc p (ppr fs)
316 %************************************************************************
318 \subsection{Other helper functions}
320 %************************************************************************
323 pprCols = (100 :: Int) -- could make configurable
325 printDoc :: Mode -> Handle -> Doc -> IO ()
326 printDoc mode hdl doc
327 = fullRender mode pprCols 1.5 put done doc
329 put (Chr c) next = hPutChar hdl c >> next
330 put (Str s) next = hPutStr hdl s >> next
331 put (PStr s) next = hPutFS hdl s >> next
333 done = hPutChar hdl '\n'
338 interppSP :: Outputable a => [a] -> SDoc
339 interppSP xs = hsep (map ppr xs)
341 interpp'SP :: Outputable a => [a] -> SDoc
342 interpp'SP xs = hsep (punctuate comma (map ppr xs))
344 pprQuotedList :: Outputable a => [a] -> SDoc
345 -- [x,y,z] ==> `x', `y', `z'
346 pprQuotedList xs = hsep (punctuate comma (map (quotes . ppr) xs))
350 %************************************************************************
352 \subsection{Printing numbers verbally}
354 %************************************************************************
356 @speakNth@ converts an integer to a verbal index; eg 1 maps to
360 speakNth :: Int -> SDoc
362 speakNth 1 = ptext SLIT("first")
363 speakNth 2 = ptext SLIT("second")
364 speakNth 3 = ptext SLIT("third")
365 speakNth 4 = ptext SLIT("fourth")
366 speakNth 5 = ptext SLIT("fifth")
367 speakNth 6 = ptext SLIT("sixth")
368 speakNth n = hcat [ int n, text st_nd_rd_th ]
370 st_nd_rd_th | n_rem_10 == 1 = "st"
371 | n_rem_10 == 2 = "nd"
372 | n_rem_10 == 3 = "rd"
375 n_rem_10 = n `rem` 10
379 speakNTimes :: Int {- >=1 -} -> SDoc
380 speakNTimes t | t == 1 = ptext SLIT("once")
381 | t == 2 = ptext SLIT("twice")
382 | otherwise = int t <+> ptext SLIT("times")
386 %************************************************************************
388 \subsection{Error handling}
390 %************************************************************************
393 pprPanic :: String -> SDoc -> a
394 pprError :: String -> SDoc -> a
395 pprTrace :: String -> SDoc -> a -> a
396 pprPanic = pprAndThen panic
397 pprError = pprAndThen error
398 pprTrace = pprAndThen trace
400 pprPanic# heading pretty_msg = panic# (show (doc PprDebug))
402 doc = text heading <+> pretty_msg
404 pprAndThen :: (String -> a) -> String -> SDoc -> a
405 pprAndThen cont heading pretty_msg = cont (show (doc PprDebug))
407 doc = sep [text heading, nest 4 pretty_msg]
409 assertPprPanic :: String -> Int -> SDoc -> a
410 assertPprPanic file line msg
411 = panic (show (doc PprDebug))
413 doc = sep [hsep[text "ASSERT failed! file",
415 text "line", int line],
418 warnPprTrace :: Bool -> String -> Int -> SDoc -> a -> a
419 warnPprTrace False file line msg x = x
420 warnPprTrace True file line msg x
421 = trace (show (doc PprDebug)) x
423 doc = sep [hsep [text "WARNING: file", text file, text "line", int line],