pisigma-0.1.0.2: src/PiSigma/Print.hs
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module PiSigma.Print where
import Control.Monad
import Text.PrettyPrint.ANSI.Leijen
import PiSigma.Syntax
import PiSigma.Evaluation
import PiSigma.Nf
-- * Print class for various types
class Print a where
prt :: Env e => a -> Eval e String
instance Print Val where
prt a = quote [] a >>= prt
instance Print (Clos Term) where
prt a = quote [] a >>= prt
instance Print Ne where
prt a = quote [] a >>= prt
instance Print Term where
prt a = return (displayS (renderPretty 0.8 75 (pretty a)) "")
data Msg = V Val | C (Clos Term) | T Term | S String
instance Print Msg where
prt (V v) = prt v
prt (C c) = prt c
prt (T t) = prt t
prt (S s) = return s
failp :: (Print a, Env e) => [a] -> Eval e b
failp ps = do msg <- foldM (\ msg p -> do s <- prt p
return (msg++s)) "" ps
fail msg
-- * Pretty printer for terms
-- | Context for printing. Determines whether parentheses are
-- required.
type PrintContext = Int
prettyTerm :: PrintContext -> Term -> Doc
prettyTerm _ (Var x) = text x
prettyTerm _ (Let p t) = pretty p <> pretty t
prettyTerm _ Type = text "Type"
prettyTerm c (Q Pi (t1,(n,t2))) =
contextParens c 1 $
group (binding 2 n t1 <$> text "->" <+> prettyTerm 1 t2)
prettyTerm c (Q Sigma (t1,(n,t2))) =
contextParens c 2 $
binding 2 n t1 <+> text "*" <+> prettyTerm 3 t2
prettyTerm _ (Lam (n,t)) =
text "\\" <+> text n <+> text "->" <+> prettyTerm 0 t
prettyTerm c (t1 :. t2) =
group (hang 2 (contextParens c 3 (prettyTerm 3 t1 <$> prettyTerm 4 t2)))
prettyTerm c (Pair (t1,t2)) =
tupled (map (prettyTerm 0) [t1,t2])
prettyTerm _ (Split t1 (n1,(n2,t2))) =
hang 2 (text "split" <+> prettyTerm 0 t1 <+> text "with"
<+> parens (text n1 <> comma <> text n2)
<+> text "->" <$> prettyTerm 0 t2)
prettyTerm _ (Enum ls) = braces (sep (map text ls))
prettyTerm _ (Label l) = text ('\'' : l)
prettyTerm _ (Case t bs) =
hang 2 (text "case" <+> prettyTerm 0 t <+> text "of" <$> branches bs)
prettyTerm c (Lift t) =
contextParens c 5 $
text "^" <> prettyTerm 5 t
prettyTerm _ (Box t) =
brackets (prettyTerm 0 t)
prettyTerm c (Force t) =
contextParens c 3 $
text "!" <> prettyTerm 4 t
prettyEntry :: Entry -> Doc
prettyEntry (Defn n t) =
hang 2 (text n <+> text "=" <$> prettyTerm 0 t <> text ";")
prettyEntry (Decl n t) =
hang 2 (text n <+> text ":" <$> prettyTerm 0 t <> text ";")
binding :: PrintContext -> String -> Term -> Doc
binding c "" t = prettyTerm c t
binding _ n t = parens (text n <+> colon <+> prettyTerm 0 t)
branches :: [(Label,Term)] -> Doc
branches bs = encloseSep lbrace rbrace (text "|") (map branch bs)
where branch (n,t) = text n <+> text "->" <+> prettyTerm 0 t
-- | Prints parens if the current context is higher
-- than a certain limit.
contextParens :: PrintContext -> PrintContext -> Doc -> Doc
contextParens c d p | c > d = parens p
| otherwise = p
instance Pretty Term where
pretty = prettyTerm 0
instance Pretty Entry where
pretty = prettyEntry