Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/nhc98/src/greencard/PrettyUtils.lhs

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


%
% Copyright (C) 1997 Thomas Nordin and Alastair Reid
%
\begin{code}

module PrettyUtils
	( textline	
        , indent	
        , around	
	, joinedBy, sepdBy
	, vsep, hsepMap, hcatMap, vsepMap, vcatMap
        , commaList, semiList, ppList
	, ppParen

	-- Haskell constructs
	, ppTuple, ppApply, ppRecord
	, ppBind, ppReturn
	, ppCase, ppCases, ppIf

	-- C constructs
	, ppCIf, ppAssign, ppCDeclare, ppCDecl, ppCast, ppBlock, ppStruct
	) where

import Pretty
import List ( intersperse )
import Maybe ( maybeToList )


textline :: [String] -> Doc
textline = hsep . map text

indent :: Doc -> Doc
indent = nest 2

around :: (String, String) -> Doc -> Doc
(a, b) `around` d =  text a <> d <> text b

joinedBy :: [Doc] -> (Doc -> Doc -> Doc) -> Doc
[] `joinedBy` sep = empty
xs `joinedBy` sep = foldr1 sep xs

sepdBy :: [Doc] -> Doc -> Doc
ds `sepdBy` sep = hcat (intersperse sep ds)

hsepMap, hcatMap, vcatMap, vsepMap :: (a -> Doc) -> [a] -> Doc
hsepMap pp xs = hsep (map pp xs)
hcatMap pp xs = hcat (map pp xs)
vcatMap pp xs = vcat (map pp xs)
vsepMap pp xs = vsep (map pp xs)

vsep :: [Doc] -> Doc 
vsep ds = ds `joinedBy` ($+$)

--($+$) :: Doc -> Doc -> Doc
--d1 $+$ d2 = d1 $$ text "" $$ d2

commaList :: [Doc] -> Doc
commaList ds = ds `sepdBy` comma

semiList :: [Doc] -> Doc
semiList ds = ds `sepdBy` semi

ppList :: Doc -> Doc -> [Doc] -> Doc
ppList sep = foldr (\a as -> a <> sep <> as)

ppTuple :: [Doc] -> Doc
ppTuple ds = parens (commaList ds)

ppApply :: Doc -> [Doc] -> Doc
ppApply d ds = ppParen (not (null ds)) ((d:ds) `sepdBy` space)

ppRecord :: Doc -> [Doc] -> [Doc] -> Doc
ppRecord c fs vs 
  = c <> braces (commaList (zipWith (\f v -> f <> equals <> v) fs vs))

-- inspired by Prelude.showParen
ppParen :: Bool -> Doc -> Doc
ppParen True  = parens
ppParen False = id

ppBind :: Doc -> (Doc, Doc) -> Doc
ppBind m (pat, k) = m <> text " >>= \\ " <> pat <> text " ->" $$ k

ppReturn :: Doc -> Doc
ppReturn x = ppApply (text "return") [parens x]

\end{code}

\begin{code}

ppCase :: Doc -> Doc -> (Doc -> Doc)
ppCase v d b = text "case" <+> v <+> text "of {" <+> d <+> text "->" $$ b <> text "}"

ppIf :: Doc -> Doc -> Doc -> Doc
ppIf cond t e 
  =  text "if" <+> cond
  $$ text "then" <+> t
  $$ text "else" <+> e

\end{code}

\begin{code}

ppCases :: Doc -> [(Doc, Doc)] -> Doc
ppCases exp alts = 
  text "case" <+> exp <+> text "of" <+> 
  braces (semiList [ pat <+> text "->" <+> body | (pat, body) <- alts ])

\end{code}

Print:

  if (..) {..} 
  else if (..) {..}
  ..
  else if (..) {..}
  else {..}

\begin{code}

ppCIf :: [(Doc,Doc)] -> Maybe Doc -> Doc
ppCIf xs mbe = (map mkIf xs ++ map braces (maybeToList mbe)) `joinedBy` mkElse
 where
  mkIf (c,s) = text "if" <+> parens c <+> braces s
  d1 `mkElse` d2 = d1 $$ text "else" <+> d2
                  
\end{code}

Print a C assignment, C declaration (with initialisation), C cast, ...

\begin{code}

ppAssign :: String -> Doc -> Doc
ppAssign lhs rhs = text lhs <+> equals <+> rhs <> semi

ppCDeclare :: Doc -> Doc -> Doc -> Doc
ppCDeclare ty var init = ty <+> var <+> equals <+> init <> semi

ppCDecl :: String -> String -> Doc
ppCDecl t n = text t <+> text n <> semi

ppCast :: Doc -> Doc -> Doc
ppCast ty expr = parens (parens ty <+> expr)

ppBlock :: Doc -> Doc
ppBlock d = ("do {", "} while(0);") `around` (indent d)

ppStruct :: [Doc] -> Doc
ppStruct ds = braces (commaList ds)

\end{code}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].