595 lines
20 KiB
Idris
595 lines
20 KiB
Idris
module Quox.Syntax.Term.Pretty
|
|
|
|
import Quox.Syntax.Term.Base
|
|
import Quox.Syntax.Term.Subst
|
|
import Quox.Context
|
|
import Quox.Pretty
|
|
|
|
import Data.Vect
|
|
import Derive.Prelude
|
|
|
|
%default total
|
|
%language ElabReflection
|
|
|
|
|
|
export
|
|
prettyUniverse : {opts : _} -> Universe -> Eff Pretty (Doc opts)
|
|
prettyUniverse = hl Universe . text . show
|
|
|
|
|
|
export
|
|
prettyTerm : {opts : _} -> BContext d -> BContext n -> Term d n ->
|
|
Eff Pretty (Doc opts)
|
|
|
|
export
|
|
prettyElim : {opts : _} -> BContext d -> BContext n -> Elim d n ->
|
|
Eff Pretty (Doc opts)
|
|
|
|
private
|
|
BTelescope : Nat -> Nat -> Type
|
|
BTelescope = Telescope' BindName
|
|
|
|
|
|
private
|
|
subscript : String -> String
|
|
subscript = pack . map sub . unpack where
|
|
sub : Char -> Char
|
|
sub c = case c of
|
|
'0' => '₀'; '1' => '₁'; '2' => '₂'; '3' => '₃'; '4' => '₄'
|
|
'5' => '₅'; '6' => '₆'; '7' => '₇'; '8' => '₈'; '9' => '₉'; _ => c
|
|
|
|
private
|
|
superscript : String -> String
|
|
superscript = pack . map sup . unpack where
|
|
sup : Char -> Char
|
|
sup c = case c of
|
|
'0' => '⁰'; '1' => '¹'; '2' => '²'; '3' => '³'; '4' => '⁴'
|
|
'5' => '⁵'; '6' => '⁶'; '7' => '⁷'; '8' => '⁸'; '9' => '⁹'; _ => c
|
|
|
|
|
|
private
|
|
PiBind : Nat -> Nat -> Type
|
|
PiBind d n = (Qty, BindName, Term d n)
|
|
|
|
private
|
|
pbname : PiBind d n -> BindName
|
|
pbname (_, x, _) = x
|
|
|
|
private
|
|
record SplitPi d n where
|
|
constructor MkSplitPi
|
|
{0 inner : Nat}
|
|
binds : Telescope (PiBind d) n inner
|
|
cod : Term d inner
|
|
|
|
private
|
|
splitPi : Telescope (PiBind d) n n' -> Term d n' -> SplitPi d n
|
|
splitPi binds (Pi qty arg res _) =
|
|
splitPi (binds :< (qty, res.name, arg)) $
|
|
assert_smaller res $ pushSubsts' res.term
|
|
splitPi binds cod = MkSplitPi {binds, cod}
|
|
|
|
private
|
|
prettyPiBind1 : {opts : _} ->
|
|
Qty -> BindName -> BContext d -> BContext n -> Term d n ->
|
|
Eff Pretty (Doc opts)
|
|
prettyPiBind1 pi (BN Unused _) dnames tnames s =
|
|
hcat <$> sequence
|
|
[prettyQty pi, dotD,
|
|
withPrec Arg $ assert_total prettyTerm dnames tnames s]
|
|
prettyPiBind1 pi x dnames tnames s = hcat <$> sequence
|
|
[prettyQty pi, dotD,
|
|
hl Delim $ text "(",
|
|
hsep <$> sequence
|
|
[prettyTBind x, hl Delim $ text ":",
|
|
withPrec Outer $ assert_total prettyTerm dnames tnames s],
|
|
hl Delim $ text ")"]
|
|
|
|
private
|
|
prettyPiBinds : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
Telescope (PiBind d) n n' ->
|
|
Eff Pretty (SnocList (Doc opts))
|
|
prettyPiBinds _ _ [<] = pure [<]
|
|
prettyPiBinds dnames tnames (binds :< (q, x, t)) =
|
|
let tnames' = tnames . map pbname binds in
|
|
[|prettyPiBinds dnames tnames binds :<
|
|
prettyPiBind1 q x dnames tnames' t|]
|
|
|
|
|
|
private
|
|
SigBind : Nat -> Nat -> Type
|
|
SigBind d n = (BindName, Term d n)
|
|
|
|
private
|
|
record SplitSig d n where
|
|
constructor MkSplitSig
|
|
{0 inner : Nat}
|
|
binds : Telescope (SigBind d) n inner
|
|
last : Term d inner
|
|
|
|
private
|
|
splitSig : Telescope (SigBind d) n n' -> Term d n' -> SplitSig d n
|
|
splitSig binds (Sig fst snd _) =
|
|
splitSig (binds :< (snd.name, fst)) $
|
|
assert_smaller snd $ pushSubsts' snd.term
|
|
splitSig binds last = MkSplitSig {binds, last}
|
|
|
|
private
|
|
prettySigBind1 : {opts : _} ->
|
|
BindName -> BContext d -> BContext n -> Term d n ->
|
|
Eff Pretty (Doc opts)
|
|
prettySigBind1 (BN Unused _) dnames tnames s =
|
|
withPrec InTimes $ assert_total prettyTerm dnames tnames s
|
|
prettySigBind1 x dnames tnames s = hcat <$> sequence
|
|
[hl Delim $ text "(",
|
|
hsep <$> sequence
|
|
[prettyTBind x, hl Delim $ text ":",
|
|
withPrec Outer $ assert_total prettyTerm dnames tnames s],
|
|
hl Delim $ text ")"]
|
|
|
|
private
|
|
prettySigBinds : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
Telescope (SigBind d) n n' ->
|
|
Eff Pretty (SnocList (Doc opts))
|
|
prettySigBinds _ _ [<] = pure [<]
|
|
prettySigBinds dnames tnames (binds :< (x, t)) =
|
|
let tnames' = tnames . map fst binds in
|
|
[|prettySigBinds dnames tnames binds :<
|
|
prettySigBind1 x dnames tnames' t|]
|
|
|
|
|
|
private
|
|
prettyTypeLine : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
DScopeTerm d n ->
|
|
Eff Pretty (Doc opts)
|
|
prettyTypeLine dnames tnames (S _ (N body)) =
|
|
withPrec Arg (prettyTerm dnames tnames body)
|
|
prettyTypeLine dnames tnames (S [< i] (Y body)) =
|
|
parens =<< do
|
|
i' <- prettyDBind i
|
|
ty' <- withPrec Outer $ prettyTerm (dnames :< i) tnames body
|
|
pure $ sep [hsep [i', !darrowD], ty']
|
|
|
|
|
|
private
|
|
data NameSort = T | D
|
|
%runElab derive "NameSort" [Eq]
|
|
|
|
private
|
|
NameChunks : Type
|
|
NameChunks = SnocList (NameSort, SnocList BindName)
|
|
|
|
private
|
|
record SplitLams d n where
|
|
constructor MkSplitLams
|
|
{0 dinner, ninner : Nat}
|
|
dnames : BTelescope d dinner
|
|
tnames : BTelescope n ninner
|
|
chunks : NameChunks
|
|
body : Term dinner ninner
|
|
|
|
private
|
|
splitLams : Term d n -> SplitLams d n
|
|
splitLams s = go [<] [<] [<] (pushSubsts' s)
|
|
where
|
|
push : NameSort -> BindName -> NameChunks -> NameChunks
|
|
push s y [<] = [< (s, [< y])]
|
|
push s y (xss :< (s', xs)) =
|
|
if s == s' then xss :< (s', xs :< y)
|
|
else xss :< (s', xs) :< (s, [< y])
|
|
|
|
go : BTelescope d d' -> BTelescope n n' ->
|
|
SnocList (NameSort, SnocList BindName) ->
|
|
Term d' n' -> SplitLams d n
|
|
go dnames tnames chunks (Lam b _) =
|
|
go dnames (tnames :< b.name) (push T b.name chunks) $
|
|
assert_smaller b $ pushSubsts' b.term
|
|
go dnames tnames chunks (DLam b _) =
|
|
go (dnames :< b.name) tnames (push D b.name chunks) $
|
|
assert_smaller b $ pushSubsts' b.term
|
|
go dnames tnames chunks s =
|
|
MkSplitLams dnames tnames chunks s
|
|
|
|
|
|
private
|
|
splitTuple : SnocList (Term d n) -> Term d n -> SnocList (Term d n)
|
|
splitTuple ss p@(Pair t1 t2 _) =
|
|
splitTuple (ss :< t1) $ assert_smaller p $ pushSubsts' t2
|
|
splitTuple ss t = ss :< t
|
|
|
|
|
|
private
|
|
prettyTArg : {opts : _} -> BContext d -> BContext n ->
|
|
Term d n -> Eff Pretty (Doc opts)
|
|
prettyTArg dnames tnames s =
|
|
withPrec Arg $ assert_total prettyTerm dnames tnames s
|
|
|
|
private
|
|
prettyDArg : {opts : _} -> BContext d -> Dim d -> Eff Pretty (Doc opts)
|
|
prettyDArg dnames p =
|
|
map (text "@" <+>) $ withPrec Arg $ prettyDim dnames p
|
|
|
|
private
|
|
splitApps : Elim d n -> (Elim d n, List (Either (Dim d) (Term d n)))
|
|
splitApps e = go [] (pushSubsts' e)
|
|
where
|
|
go : List (Either (Dim d) (Term d n)) -> Elim d n ->
|
|
(Elim d n, List (Either (Dim d) (Term d n)))
|
|
go xs e@(App f s _) =
|
|
go (Right s :: xs) $ assert_smaller e $ pushSubsts' f
|
|
go xs e@(DApp f p _) =
|
|
go (Left p :: xs) $ assert_smaller e $ pushSubsts' f
|
|
go xs s = (s, xs)
|
|
|
|
private
|
|
prettyDTApps : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
Elim d n -> List (Either (Dim d) (Term d n)) ->
|
|
Eff Pretty (Doc opts)
|
|
prettyDTApps dnames tnames f xs = do
|
|
f <- withPrec Arg $ assert_total prettyElim dnames tnames f
|
|
xs <- for xs $ either (prettyDArg dnames) (prettyTArg dnames tnames)
|
|
parensIfM App =<< prettyAppD f xs
|
|
|
|
|
|
private
|
|
record CaseArm opts d n where
|
|
constructor MkCaseArm
|
|
{0 dinner, ninner : Nat}
|
|
pat : Doc opts
|
|
dbinds : BTelescope d dinner -- 🍴
|
|
tbinds : BTelescope n ninner
|
|
body : Term dinner ninner
|
|
|
|
parameters {opts : LayoutOpts} (dnames : BContext d) (tnames : BContext n)
|
|
private
|
|
prettyCaseArm : CaseArm opts d n -> Eff Pretty (Doc opts)
|
|
prettyCaseArm (MkCaseArm pat dbinds tbinds body) = do
|
|
body <- withPrec Outer $ assert_total
|
|
prettyTerm (dnames . dbinds) (tnames . tbinds) body
|
|
header <- (pat <++>) <$> darrowD
|
|
pure $ hsep [header, body] <|> vsep [header, !(indentD body)]
|
|
|
|
private
|
|
prettyCaseBody : List (CaseArm opts d n) -> Eff Pretty (Doc opts)
|
|
prettyCaseBody xs =
|
|
braces . separateTight !semiD =<< traverse prettyCaseArm xs
|
|
|
|
private
|
|
prettyCompPat : {opts : _} -> DimConst -> BindName -> Eff Pretty (Doc opts)
|
|
prettyCompPat e x = [|prettyDimConst e <++> prettyDBind x|]
|
|
|
|
private
|
|
prettyCompArm : {opts : _} -> BContext d -> BContext n ->
|
|
DimConst -> DScopeTerm d n -> Eff Pretty (Doc opts)
|
|
prettyCompArm dnames tnames e s = prettyCaseArm dnames tnames $
|
|
MkCaseArm !(prettyCompPat e s.name) [< s.name] [<] s.term
|
|
|
|
private
|
|
layoutComp : {opts : _} ->
|
|
(typq : List (Doc opts)) -> (val, r : Doc opts) ->
|
|
(arms : List (Doc opts)) -> Eff Pretty (Doc opts)
|
|
layoutComp typq val r arms = do
|
|
comp <- compD; lb <- hl Delim "{"; rb <- hl Delim "}"
|
|
ind <- askAt INDENT
|
|
pure $ ifMultiline
|
|
(hsep $ concat {t = List} [[comp], typq, [val, r, lb], arms, [rb]]) $
|
|
(comp <++>
|
|
vsep [sep typq, val, r <++> lb, indent ind $ vsep arms, rb]) <|>
|
|
(vsep $ (comp ::) $ map (indent ind) $ concat {t = List}
|
|
[typq, [val, r <++> lb], map (indent ind) arms, [rb]])
|
|
|
|
|
|
export
|
|
prettyTag : {opts : _} -> String -> Eff Pretty (Doc opts)
|
|
prettyTag tag = hl Tag $ text $ "'" ++ quoteTag tag
|
|
|
|
export
|
|
prettyEnum : {opts : _} -> List String -> Eff Pretty (Doc opts)
|
|
prettyEnum cases =
|
|
tightBraces =<<
|
|
fillSeparateTight !commaD <$>
|
|
traverse (hl Tag . Doc.text . quoteTag) cases
|
|
|
|
private
|
|
prettyCaseRet : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
ScopeTerm d n -> Eff Pretty (Doc opts)
|
|
prettyCaseRet dnames tnames body = withPrec Outer $ case body of
|
|
S _ (N tm) => assert_total prettyTerm dnames tnames tm
|
|
S [< x] (Y tm) => do
|
|
header <- [|prettyTBind x <++> darrowD|]
|
|
body <- assert_total prettyTerm dnames (tnames :< x) tm
|
|
pure $ hsep [header, body] <|> vsep [header, !(indentD body)]
|
|
|
|
private
|
|
prettyCase_ : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
Doc opts -> Elim d n -> ScopeTerm d n -> List (CaseArm opts d n) ->
|
|
Eff Pretty (Doc opts)
|
|
prettyCase_ dnames tnames intro head ret body = do
|
|
head <- assert_total prettyElim dnames tnames head
|
|
ret <- prettyCaseRet dnames tnames ret
|
|
body <- prettyCaseBody dnames tnames body
|
|
parensIfM Outer $ sep [intro <++> head, !returnD <++> ret, !ofD <++> body]
|
|
|
|
private
|
|
prettyCase : {opts : _} ->
|
|
BContext d -> BContext n ->
|
|
Qty -> Elim d n -> ScopeTerm d n -> List (CaseArm opts d n) ->
|
|
Eff Pretty (Doc opts)
|
|
prettyCase dnames tnames qty head ret body =
|
|
prettyCase_ dnames tnames ![|caseD <+> prettyQty qty|] head ret body
|
|
|
|
|
|
private
|
|
isDefaultDir : Dim d -> Dim d -> Bool
|
|
isDefaultDir (K Zero _) (K One _) = True
|
|
isDefaultDir _ _ = False
|
|
|
|
|
|
-- [fixme] use telescopes in Scoped
|
|
private
|
|
toTel : BContext s -> BTelescope n (s + n)
|
|
toTel [<] = [<]
|
|
toTel (ctx :< x) = toTel ctx :< x
|
|
|
|
private
|
|
prettyTyCasePat : {opts : _} ->
|
|
(k : TyConKind) -> BContext (arity k) ->
|
|
Eff Pretty (Doc opts)
|
|
prettyTyCasePat KTYPE [<] = typeD
|
|
prettyTyCasePat KPi [< a, b] =
|
|
parens . hsep =<< sequence [prettyTBind a, arrowD, prettyTBind b]
|
|
prettyTyCasePat KSig [< a, b] =
|
|
parens . hsep =<< sequence [prettyTBind a, timesD, prettyTBind b]
|
|
prettyTyCasePat KW [< a, b] =
|
|
parens . hsep =<< sequence [prettyTBind a, triD, prettyTBind b]
|
|
prettyTyCasePat KEnum [<] = hl Syntax $ text "{}"
|
|
prettyTyCasePat KEq [< a0, a1, a, l, r] =
|
|
hsep <$> sequence (eqD :: map prettyTBind [a0, a1, a, l, r])
|
|
prettyTyCasePat KNat [<] = natD
|
|
prettyTyCasePat KBOX [< a] = bracks =<< prettyTBind a
|
|
|
|
|
|
prettyLambda : {opts : _} -> BContext d -> BContext n ->
|
|
Term d n -> Eff Pretty (Doc opts)
|
|
prettyLambda dnames tnames s =
|
|
parensIfM Outer =<< do
|
|
let MkSplitLams {dnames = ds, tnames = ts, chunks, body} = splitLams s
|
|
hangDSingle !(header chunks)
|
|
!(assert_total prettyTerm (dnames . ds) (tnames . ts) body)
|
|
where
|
|
introChar : NameSort -> Eff Pretty (Doc opts)
|
|
introChar T = lamD
|
|
introChar D = dlamD
|
|
|
|
prettyBind : NameSort -> BindName -> Eff Pretty (Doc opts)
|
|
prettyBind T = prettyTBind
|
|
prettyBind D = prettyDBind
|
|
|
|
header1 : NameSort -> List BindName -> Eff Pretty (Doc opts)
|
|
header1 s xs = hsep <$> sequence
|
|
[introChar s, sep <$> traverse (prettyBind s) xs, darrowD]
|
|
|
|
header : NameChunks -> Eff Pretty (Doc opts)
|
|
header cs = sep <$> traverse (\(s, xs) => header1 s (toList xs)) (toList cs)
|
|
|
|
|
|
prettyDisp : {opts : _} -> Universe -> Eff Pretty (Maybe (Doc opts))
|
|
prettyDisp 0 = pure Nothing
|
|
prettyDisp u = map Just $ hl Universe =<<
|
|
ifUnicode (text $ superscript $ show u) (text $ "^" ++ show u)
|
|
|
|
|
|
prettyTerm dnames tnames (TYPE l _) =
|
|
case !(askAt FLAVOR) of
|
|
Unicode => do
|
|
star <- hl Syntax "★"
|
|
level <- hl Universe $ text $ superscript $ show l
|
|
pure $ hcat [star, level]
|
|
Ascii => [|hl Syntax "Type" <++> hl Universe (text $ show l)|]
|
|
|
|
prettyTerm dnames tnames (Pi qty arg res _) =
|
|
parensIfM Outer =<< do
|
|
let MkSplitPi {binds, cod} = splitPi [< (qty, res.name, arg)] res.term
|
|
arr <- arrowD
|
|
lines <- map (<++> arr) <$> prettyPiBinds dnames tnames binds
|
|
let tnames = tnames . map pbname binds
|
|
cod <- withPrec Outer $ prettyTerm dnames tnames (assert_smaller res cod)
|
|
pure $ sepSingle $ toList $ lines :< cod
|
|
|
|
prettyTerm dnames tnames s@(Lam {}) =
|
|
prettyLambda dnames tnames s
|
|
|
|
prettyTerm dnames tnames (Sig fst snd _) =
|
|
parensIfM Times =<< do
|
|
let MkSplitSig {binds, last} = splitSig [< (snd.name, fst)] snd.term
|
|
times <- timesD
|
|
lines <- map (<++> times) <$> prettySigBinds dnames tnames binds
|
|
let tnames = tnames . map Builtin.fst binds
|
|
last <- withPrec InTimes $
|
|
prettyTerm dnames tnames (assert_smaller snd last)
|
|
pure $ sepSingle $ toList $ lines :< last
|
|
|
|
prettyTerm dnames tnames p@(Pair fst snd _) =
|
|
parens =<< do
|
|
let elems = splitTuple [< fst] snd
|
|
lines <- for elems $ \t =>
|
|
withPrec Outer $ prettyTerm dnames tnames $ assert_smaller p t
|
|
pure $ separateTight !commaD lines
|
|
|
|
prettyTerm dnames tnames (W a b _) = do
|
|
parensIfM W =<< do
|
|
left <- prettySigBind1 b.name dnames tnames a
|
|
right <- withPrec InW $
|
|
prettyTerm dnames (tnames :< b.name) (assert_smaller b b.term)
|
|
pure $ sep [hsep [left, !triD], right]
|
|
|
|
prettyTerm dnames tnames (Sup root sub _) = do
|
|
parensIfM Sup =<< do
|
|
left <- withPrec InSup $ prettyTerm dnames tnames root
|
|
right <- withPrec InSup $ prettyTerm dnames tnames sub
|
|
pure $
|
|
hsep [left, !diamondD, right] <|>
|
|
vsep [hsep [left, !diamondD], !(indentD right)]
|
|
|
|
prettyTerm dnames tnames (Enum cases _) =
|
|
prettyEnum $ SortedSet.toList cases
|
|
|
|
prettyTerm dnames tnames (Tag tag _) =
|
|
prettyTag tag
|
|
|
|
prettyTerm dnames tnames (Eq (S _ (N ty)) l r _) =
|
|
parensIfM Eq =<< do
|
|
l <- withPrec InEq $ prettyTerm dnames tnames l
|
|
r <- withPrec InEq $ prettyTerm dnames tnames r
|
|
ty <- withPrec InEq $ prettyTerm dnames tnames ty
|
|
pure $ sep [l <++> !eqndD, r <++> !colonD, ty]
|
|
|
|
prettyTerm dnames tnames (Eq ty l r _) =
|
|
parensIfM Arg =<< do
|
|
ty <- prettyTypeLine dnames tnames ty
|
|
l <- withPrec Arg $ prettyTerm dnames tnames l
|
|
r <- withPrec Arg $ prettyTerm dnames tnames r
|
|
prettyAppD !eqD [ty, l, r]
|
|
|
|
prettyTerm dnames tnames s@(DLam {}) =
|
|
prettyLambda dnames tnames s
|
|
|
|
prettyTerm dnames tnames (Nat _) = natD
|
|
prettyTerm dnames tnames (Zero _) = hl Syntax "0"
|
|
prettyTerm dnames tnames (Succ p _) = do
|
|
s <- succD
|
|
either (succ s) prettyNat =<< tryToNat s p
|
|
where
|
|
succ : Doc opts -> Doc opts -> Eff Pretty (Doc opts)
|
|
succ s t = prettyAppD s [t]
|
|
|
|
tryToNat : Doc opts -> Term d n -> Eff Pretty (Either (Doc opts) Nat)
|
|
tryToNat s t with (pushSubsts' t)
|
|
_ | Zero _ = pure $ Right 0
|
|
_ | Succ d _ = bitraverse (succ s) (pure . S) =<<
|
|
tryToNat s (assert_smaller t d)
|
|
_ | t' = map Left . withPrec Arg $
|
|
prettyTerm dnames tnames $ assert_smaller t t'
|
|
|
|
prettyNat : Nat -> Eff Pretty (Doc opts)
|
|
prettyNat = hl Syntax . text . show . S
|
|
|
|
prettyTerm dnames tnames (BOX qty ty _) =
|
|
bracks . hcat =<<
|
|
sequence [prettyQty qty, dotD,
|
|
withPrec Outer $ prettyTerm dnames tnames ty]
|
|
|
|
prettyTerm dnames tnames (Box val _) =
|
|
bracks =<< withPrec Outer (prettyTerm dnames tnames val)
|
|
|
|
prettyTerm dnames tnames (E e) = prettyElim dnames tnames e
|
|
|
|
prettyTerm dnames tnames t0@(CloT (Sub t ph)) =
|
|
prettyTerm dnames tnames $ assert_smaller t0 $ pushSubstsWith' id ph t
|
|
|
|
prettyTerm dnames tnames t0@(DCloT (Sub t ph)) =
|
|
prettyTerm dnames tnames $ assert_smaller t0 $ pushSubstsWith' ph id t
|
|
|
|
prettyElim dnames tnames (F x u _) = do
|
|
x <- prettyFree x
|
|
u <- prettyDisp u
|
|
pure $ maybe x (x <+>) u
|
|
|
|
prettyElim dnames tnames (B i _) =
|
|
prettyTBind $ tnames !!! i
|
|
|
|
prettyElim dnames tnames e@(App {}) =
|
|
let (f, xs) = splitApps e in
|
|
prettyDTApps dnames tnames f xs
|
|
|
|
prettyElim dnames tnames (CasePair qty pair ret body _) = do
|
|
let [< x, y] = body.names
|
|
pat <- parens . hsep =<< sequence
|
|
[[|prettyTBind x <+> commaD|], prettyTBind y]
|
|
prettyCase dnames tnames qty pair ret
|
|
[MkCaseArm pat [<] [< x, y] body.term]
|
|
|
|
prettyElim dnames tnames (CaseW qty qtyIH tree ret body _) = do
|
|
let [< t, r, ih] = body.names
|
|
pat0 <- hsep <$> sequence [prettyTBind t, diamondD, prettyTBind r]
|
|
ihpat <- map hcat $ sequence [prettyQty qtyIH, dotD, prettyTBind ih]
|
|
pat <- if ih.name == Unused
|
|
then pure pat0
|
|
else pure $ hsep [pat0 <+> !commaD, ihpat]
|
|
let arm = MkCaseArm pat [<] [< t, r, ih] body.term
|
|
prettyCase dnames tnames qty tree ret [arm]
|
|
|
|
prettyElim dnames tnames (CaseEnum qty tag ret arms _) = do
|
|
arms <- for (SortedMap.toList arms) $ \(tag, body) =>
|
|
pure $ MkCaseArm !(prettyTag tag) [<] [<] body
|
|
prettyCase dnames tnames qty tag ret arms
|
|
|
|
prettyElim dnames tnames (CaseNat qty qtyIH nat ret zero succ _) = do
|
|
let zarm = MkCaseArm !zeroD [<] [<] zero
|
|
[< p, ih] = succ.names
|
|
spat0 <- [|succD <++> prettyTBind p|]
|
|
ihpat0 <- map hcat $ sequence [prettyQty qtyIH, dotD, prettyTBind ih]
|
|
spat <- if ih.name == Unused
|
|
then pure spat0
|
|
else pure $ hsep [spat0 <+> !commaD, ihpat0]
|
|
let sarm = MkCaseArm spat [<] [< p, ih] succ.term
|
|
prettyCase dnames tnames qty nat ret [zarm, sarm]
|
|
|
|
prettyElim dnames tnames (CaseBox qty box ret body _) = do
|
|
pat <- bracks =<< prettyTBind body.name
|
|
let arm = MkCaseArm pat [<] [< body.name] body.term
|
|
prettyCase dnames tnames qty box ret [arm]
|
|
|
|
prettyElim dnames tnames e@(DApp {}) =
|
|
let (f, xs) = splitApps e in
|
|
prettyDTApps dnames tnames f xs
|
|
|
|
prettyElim dnames tnames (Ann tm ty _) =
|
|
parensIfM Outer =<<
|
|
hangDSingle !(withPrec AnnL [|prettyTerm dnames tnames tm <++> annD|])
|
|
!(withPrec Outer (prettyTerm dnames tnames ty))
|
|
|
|
prettyElim dnames tnames (Coe ty p q val _) =
|
|
parensIfM App =<<
|
|
if isDefaultDir p q then do
|
|
ty <- prettyTypeLine dnames tnames ty
|
|
val <- prettyTArg dnames tnames val
|
|
prettyAppD !coeD [ty, val]
|
|
else do
|
|
ty <- prettyTypeLine dnames tnames ty
|
|
p <- prettyDArg dnames p
|
|
q <- prettyDArg dnames q
|
|
val <- prettyTArg dnames tnames val
|
|
prettyAppD !coeD [ty, sep [p, q], val]
|
|
|
|
prettyElim dnames tnames e@(Comp ty p q val r zero one _) =
|
|
parensIfM App =<< do
|
|
ty <- prettyTypeLine dnames tnames $ assert_smaller e $ SN ty
|
|
pq <- sep <$> sequence [prettyDArg dnames p, prettyDArg dnames q]
|
|
val <- prettyTArg dnames tnames val
|
|
r <- prettyDArg dnames r
|
|
arm0 <- [|prettyCompArm dnames tnames Zero zero <+> semiD|]
|
|
arm1 <- prettyCompArm dnames tnames One one
|
|
ind <- askAt INDENT
|
|
if isDefaultDir p q
|
|
then layoutComp [ty] val r [arm0, arm1]
|
|
else layoutComp [ty, pq] val r [arm0, arm1]
|
|
|
|
prettyElim dnames tnames (TypeCase ty ret arms def _) = do
|
|
arms <- for (toList arms) $ \(k ** body) => do
|
|
pat <- prettyTyCasePat k body.names
|
|
pure $ MkCaseArm pat [<] (toTel body.names) body.term
|
|
let darm = MkCaseArm !undD [<] [<] def
|
|
prettyCase_ dnames tnames !typecaseD ty (SN ret) $ arms ++ [darm]
|
|
|
|
prettyElim dnames tnames e0@(CloE (Sub e ph)) =
|
|
prettyElim dnames tnames $ assert_smaller e0 $ pushSubstsWith' id ph e
|
|
|
|
prettyElim dnames tnames e0@(DCloE (Sub e ph)) =
|
|
prettyElim dnames tnames $ assert_smaller e0 $ pushSubstsWith' ph id e
|