{-# LANGUAGE ViewPatterns #-} module Syntax.Pretty where import Syntax import Data.Text ( Text ) import qualified Data.Text as T import Elaboration.Monad type Prec = Int domainPrec, funcPrec, argPrec :: Int domainPrec = 3 argPrec = 2 funcPrec = 1 showWithPrec :: [Text] -> Int -> Term -> ShowS showWithPrec names p (App Ex x y) = showParen (p >= argPrec) $ showWithPrec names funcPrec x . showChar ' ' . showWithPrec names argPrec y showWithPrec names p (App Im x _) = showWithPrec names p x showWithPrec _ _ Type = showString "Type" showWithPrec _ _ Top = showString "⊤" showWithPrec _ _ Unit = showString "()" -- Reflexivity showWithPrec _ _ Refl = showString "refl" -- Casting showWithPrec _ _ Coe = showString "coe" -- Congruence (x == y → f x == f y) showWithPrec _ _ Cong = showString "cong" -- Symmetry showWithPrec _ _ Sym = showString "sym" showWithPrec _ _ (Meta (MV i)) = showChar '?' . shows i showWithPrec _ _ (NewMeta (MV i) _) = showChar '?' . shows i showWithPrec names _ (Bv i) = if i < 0 then showString "α" else showString (T.unpack (names !! i)) showWithPrec names _ (Proj1 x) = showWithPrec names funcPrec x . showString ".1" showWithPrec names _ (Proj2 x) = showWithPrec names funcPrec x . showString ".2" showWithPrec names p (Lam i t e) = showParen (p >= funcPrec) $ showChar 'λ' . showsPlicity i id (showString (T.unpack t)) . showString " → " . showWithPrec (t:names) 0 e showWithPrec names p (Pi Ex (T.unpack -> "_") d r) = showParen (p >= argPrec) $ showWithPrec names domainPrec d . showString " -> " . showWithPrec (T.singleton '_':names) 0 r showWithPrec names p (Pi i n d r) = showParen (p >= argPrec) $ showsPlicity i (showParen True) ( showString (T.unpack n) . showString " : " . showWithPrec names 0 d ) . showString " -> " . showWithPrec (n:names) 0 r showWithPrec names p (Sigma (T.unpack -> "_") d r) = showParen (p >= argPrec) $ showWithPrec names domainPrec d . showString " × " . showWithPrec (T.singleton '_':names) 0 r showWithPrec names p (Sigma n d r) = showParen (p >= argPrec) $ showParen True ( showString (T.unpack n) . showString " : " . showWithPrec names 0 d ) . showString " × " . showWithPrec (n:names) 0 r showWithPrec names _ (Pair a b) = showParen True $ showWithPrec names 0 a . showString " , " . showWithPrec names 0 b showWithPrec names p (Id _ b c) = showParen (p >= funcPrec) $ showWithPrec names argPrec b . showString " == " . showWithPrec names argPrec c showWithPrec names p (Let x t d e) = showParen (p >= funcPrec) $ showString "let\n" . showString (" " ++ T.unpack x) . showString " : " . showWithPrec names 0 t . showChar '\n' . showString (" " ++ T.unpack x ++ " = ") . showWithPrec names 0 d . showString ";\n" . showWithPrec (x:names) 0 e showTerm :: Int -> Term -> ShowS showTerm = showWithPrec (iterate (`T.snoc` '\'') (T.pack "x")) showsPlicity :: Plicity -> (ShowS -> ShowS) -> ShowS -> ShowS showsPlicity Ex f k = f k showsPlicity Im _ k = showChar '{' . k . showChar '}' showElabError :: ElabError -> ShowS showElabError (NotInScope t) = showString "Variable not in scope: " . shows t showElabError (NotFunction names t) = showString "Type is not a function type: " . showWithPrec (names ++ exes) 0 t where exes = iterate (`T.snoc` '\'') (T.pack "x") showElabError (NotEqual names a b) = showString "Types are not equal:" . showString "\n * " . showWithPrec (names ++ exes) 0 a . showString "\n vs" . showString "\n * " . showWithPrec (names ++ exes) 0 b where exes = iterate (`T.snoc` '\'') (T.pack "x") showElabError (CantSolveMeta ns q t) = showString "Equation has no (unique) solution: " . showString "\n " . showWithPrec (ns ++ exes) 0 q . showString " ≡? " . showWithPrec (ns ++ exes) 0 t where exes = iterate (`T.snoc` '\'') (T.pack "x")