fnotation-0.2.0.0: src/FNotation/Pretty.hs
module FNotation.Pretty where
import Diagnostician
import FNotation.Config
import FNotation.Kinds (Kind)
import FNotation.Names
import FNotation.Trees
import Prettyprinter
data PrevPrec
= LeftOf Prec
| RightOf Prec
| Top
| Bot
tighter :: Prec -> PrevPrec -> Bool
tighter _ Top = True
tighter _ Bot = False
tighter (Prec b a) (LeftOf (Prec b' a'))
| b > b' = True
| b < b' = False
| a == AssocL && a' == AssocL = True
| otherwise = False
tighter (Prec b a) (RightOf (Prec b' a'))
| b > b' = True
| b < b' = False
| a == AssocR && a' == AssocR = True
| otherwise = False
looser :: Prec -> PrevPrec -> Bool
looser p p' = not $ tighter p p'
type ConfigArg = (?config :: ConfTable Prec, ?lconfig :: ConfTable Kind)
prtTop :: (ConfigArg) => NtnGeneric a -> DDoc
prtTop = prt Top
precApp :: Prec
precApp = Prec 100 AssocL
par :: Bool -> DDoc -> DDoc
par True d = enclose "(" ")" d
par False d = d
prt :: (ConfigArg) => PrevPrec -> NtnGeneric a -> DDoc
prt p = \case
Juxt n n' ->
par (looser precApp p) $
prt (LeftOf precApp) n <+> prt (RightOf precApp) n'
Infix l n r ->
let mp' = case n of
Ident x _ -> confTableLookup ?config x.last
Keyword x _ -> confTableLookup ?config x.last
_ -> Nothing
p' = maybe (Prec 50 AssocL) id mp'
in par (looser p' p) (prt (LeftOf p') l <+> prt Bot n <+> prt (RightOf p') r)
Block x hd stmts _ ->
vsep $
[dpretty x <> maybe mempty ((" " <>) . prtTop) hd]
++ [indent 2 $ prtTop stmt | stmt <- stmts]
++ ["end"]
MDecl ms x n _ -> hsep (dpretty <$> (ms ++ [x])) <+> prtTop n
Ident x _ | Bot <- p -> dprettyOpWithKinds ?lconfig x
Ident x _ -> dprettyWithKinds ?lconfig x
Keyword x _ -> dpretty x
Field x _ -> "." <> dprettyWithKinds ?lconfig x
Tag x _ -> "'" <> dprettyWithKinds ?lconfig x
Int i _ -> pretty i
String x _ -> "\"" <> pretty x <> "\""
Tuple ns _ -> list $ prtTop <$> ns
Error _ -> "<error>"
dprettyWithConfigs :: ConfTable Prec -> ConfTable Kind -> NtnGeneric a -> DDoc
dprettyWithConfigs config lconfig n = let ?config = config; ?lconfig = lconfig in prtTop n