zwirn-0.1.0.0: src/Zwirn/Language/Pretty.hs
{-# LANGUAGE FlexibleInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Zwirn.Language.Pretty
( ppterm,
ppscheme,
ppTermHasType,
)
where
{-
Pretty.hs - pretty printer for the AST and the types
Copyright (C) 2023, Martin Gius
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}
import Data.List (intercalate)
import Data.Text (unpack)
import Text.PrettyPrint
import Zwirn.Language.Syntax
import Zwirn.Language.TypeCheck.Constraint
import Zwirn.Language.TypeCheck.Types
import Prelude hiding ((<>))
parensIf :: Bool -> Doc -> Doc
parensIf True = parens
parensIf False = id
class Pretty p where
ppr :: Int -> p -> Doc
instance Pretty Name where
ppr _ x = text $ unpack x
instance Pretty Type where
ppr p (TypeArr a b) = parensIf (isArrow a) (ppr p a) <+> text "->" <+> ppr p b
where
isArrow TypeArr {} = True
isArrow _ = False
ppr p (TypeVar a) = ppr p a
ppr _ (TypeCon a) = text $ unpack a
instance Pretty Predicate where
ppr p (IsIn c t) = text (unpack c) <+> ppr p t
instance Pretty [Predicate] where
ppr p ps = parensIf (length ps > 1) (hcat (punctuate comma (map (ppr p) ps)))
instance Pretty (Qualified Type) where
ppr p (Qual [] t) = ppr p t
ppr p (Qual ps t) = ppr p ps <+> text "=>" <+> ppr p t
instance Pretty Scheme where
ppr p (Forall _ t) = ppr p t
instance Pretty Term where
ppr _ (TVar _ x) = text $ unpack x
ppr _ TRest = text "~"
ppr _ (TText _ x) = text $ unpack x
ppr _ (TNum _ x) = double $ read $ unpack x
ppr p (TRepeat t (Just i)) = ppr p t <> text "!" <> int i
ppr p (TRepeat t Nothing) = ppr p t <> text "!"
ppr p (TSeq [t]) = ppr p t
ppr p (TSeq ts) = brackets (hcat (punctuate space (map (ppr p) ts)))
ppr p (TAlt ts) = text "<" <> hcat (punctuate space (map (ppr p) ts)) <> text ">"
ppr p (TChoice _ ts) = brackets (hcat $ punctuate (text "|") (map (ppr p) ts))
ppr p (TStack ts) = brackets (hcat $ punctuate comma (map (ppr p) ts))
ppr p (TPoly t1 t2) = ppr p t1 <> text "%" <> ppr p t2
ppr p (TApp t1 t2) = parensIf (p > 0) (ppr (p + 1) t1 <+> ppr p t2)
ppr p (TInfix t1 n t2) = ppr p t1 <+> text (unpack n) <+> ppr p t2
ppr p (TBracket t) = parens (ppr p t)
ppr p (TLambda vs t) = text "\\" <> hcat (punctuate space $ map (text . unpack) vs) <+> text "->" <+> ppr p t
ppr p (TSectionL t n) = ppr p t <+> text (unpack n)
ppr p (TSectionR n t) = text (unpack n) <+> ppr p t
ppr p (TEnum Run x y) = brackets (ppr p x <+> text ".." <+> ppr p y)
ppr p (TEnumThen Alt x y z) = text "<" <> (ppr p x <+> ppr p y <+> text ".." <+> ppr p z) <> text ">"
ppr p (TEnum Alt x y) = text "<" <> (ppr p x <+> text ".." <+> ppr p y) <> text ">"
ppr p (TEnumThen Run x y z) = brackets (ppr p x <+> ppr p y <+> text ".." <+> ppr p z)
ppr p (TEnum Cord x y) = brackets (ppr p x <+> text ", .." <+> ppr p y)
ppr p (TEnumThen Cord x y z) = brackets (ppr p x <+> text "," <+> ppr p y <+> text ".." <+> ppr p z)
ppr p (TEnum Choice x y) = brackets (ppr p x <+> text "| .. " <+> ppr p y)
ppr p (TEnumThen Choice x y z) = brackets (ppr p x <+> text "|" <+> ppr p y <+> text ".." <+> ppr p z)
instance Pretty (Term, Scheme) where
ppr p (t, s) = ppr p t <+> text "::" <+> ppr p s
pptype :: Type -> String
pptype = render . ppr 0
ppscheme :: Scheme -> String
ppscheme = render . ppr 0
ppterm :: Term -> String
ppterm = render . ppr 0
ppTermHasType :: (Term, Scheme) -> String
ppTermHasType = render . ppr 0
instance Show TypeError where
show (UnificationFail a b) =
concat ["Cannot unify types: \n\t", pptype a, " ~ ", pptype b]
show (UnificationMismatch as bs) =
concat ["Cannot unify types: \n\t", intercalate "," $ map pptype as, " ~ ", intercalate "," $ map pptype bs]
show (InfiniteType a b) =
concat ["Cannot construct the infinite type: ", unpack a, " = ", pptype b]
show (Ambigious cs) =
concat ["Cannot not match expected type: '" ++ pptype a ++ "' with actual type: '" ++ pptype b ++ "'\n" | (a, b) <- cs]
show (UnboundVariable a) = "Not in scope: " ++ unpack a
show (NoInstance (IsIn c x)) = "No instance for " ++ unpack c ++ " " ++ pptype x