hoq-0.1.0.0: src/Syntax/ErrorDoc.hs
{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
module Syntax.ErrorDoc
( EMsg, EDoc
, Pretty(..), Pretty1(..), epretty
, enull, (<>), (<+>), ($$)
, emsg, emsgL, emsgLC
, erender, erenderWithFilename
) where
import qualified Text.PrettyPrint as P
data EMsg f = EMsg (Maybe Int) (Maybe Int) String (EDoc f)
data EDoc f = EDoc P.Doc | ENull | ETerm (f (EDoc f)) | EAbove (EDoc f) (EDoc f) | EBeside (EDoc f) Bool (EDoc f)
class Functor f => Pretty1 f where
pretty1 :: f P.Doc -> P.Doc
instance Pretty1 f => Show (EDoc f) where
show = P.render . edocToDoc
class Pretty a f where
pretty :: a -> EDoc f
instance Pretty P.Doc f where
pretty = EDoc
instance Pretty String f where
pretty = etext
instance (Pretty a f, Pretty b f) => Pretty (Either a b) f where
pretty (Left a) = pretty a
pretty (Right b) = pretty b
etext :: String -> EDoc f
etext "" = enull
etext s = EDoc (P.text s)
epretty :: f (EDoc f) -> EDoc f
epretty = ETerm
eprettyDoc :: Functor f => f P.Doc -> EDoc f
eprettyDoc = ETerm . fmap EDoc
eprettyStr :: Functor f => f String -> EDoc f
eprettyStr = ETerm . fmap etext
enull :: EDoc f
enull = ENull
infixl 6 <>, <+>
infixl 5 $$
(<>) :: EDoc f -> EDoc f -> EDoc f
d1 <> d2 = EBeside d1 False d2
(<+>) :: EDoc f -> EDoc f -> EDoc f
d1 <+> d2 = EBeside d1 True d2
($$) :: EDoc f -> EDoc f -> EDoc f
($$) = EAbove
emsg :: String -> EDoc f -> EMsg f
emsg = EMsg Nothing Nothing
emsgL :: Int -> String -> EDoc f -> EMsg f
emsgL l = EMsg (Just l) Nothing
emsgLC :: (Int,Int) -> String -> EDoc f -> EMsg f
emsgLC (l,c) = EMsg (Just l) (Just c)
erender :: Pretty1 f => EMsg f -> String
erender (EMsg l c s d) = P.render (msgToDoc Nothing l c s d)
erenderWithFilename :: Pretty1 f => String -> EMsg f -> String
erenderWithFilename fn (EMsg l c s d) = P.render (msgToDoc (Just fn) l c s d)
msgToDoc :: Pretty1 f => Maybe String -> Maybe Int -> Maybe Int -> String -> EDoc f -> P.Doc
msgToDoc Nothing l c "" d =
maybe P.empty (\ln -> P.text $ show ln ++ ":") l P.<>
maybe P.empty (\cn -> P.text $ show cn ++ ":") c P.<+>
edocToDoc d
msgToDoc fn l c s d = P.hang (
maybe P.empty (\s -> P.text $ s ++ ":") fn P.<>
maybe P.empty (\ln -> P.text $ show ln ++ ":") l P.<>
maybe P.empty (\cn -> P.text $ show cn ++ ":") c P.<+> P.text s) 4 (edocToDoc d)
edocToDoc :: Pretty1 f => EDoc f -> P.Doc
edocToDoc ENull = P.empty
edocToDoc (EDoc d) = d
edocToDoc (EBeside d1 False d2) = edocToDoc d1 P.<> edocToDoc d2
edocToDoc (EBeside d1 True d2) = edocToDoc d1 P.<+> edocToDoc d2
edocToDoc (EAbove d1 d2) = edocToDoc d1 P.$+$ edocToDoc d2
edocToDoc (ETerm e) = pretty1 (fmap edocToDoc e)