mello-0.2.0: src/Mello/Print.hs
{-# LANGUAGE UndecidableInstances #-}
module Mello.Print
( ToSexp (..)
, toSexpDoc
, toSexpText
)
where
import Bowtie.Anno (Anno (..))
import Bowtie.Fix (Fix (..))
import Bowtie.Memo (Memo, memoVal)
import Data.Scientific (Scientific)
import Data.Text (Text)
import Data.Text qualified as T
import Mello.Syntax (Atom (..), Sexp (..), Sym, pattern SexpAtom)
import Prettyprinter (Doc, defaultLayoutOptions, layoutSmart, pretty)
import Prettyprinter.Render.Text (renderStrict)
class ToSexp a where
toSexp :: a -> Sexp
instance ToSexp Sexp where
toSexp = id
instance (Functor f, ToSexp (f Sexp)) => ToSexp (Fix f) where
toSexp = toSexp . fmap toSexp . unFix
instance (ToSexp s) => ToSexp (Anno k s) where
toSexp = toSexp . annoVal
instance (Functor f, ToSexp (f Sexp)) => ToSexp (Memo f k) where
toSexp = toSexp . fmap toSexp . memoVal
instance ToSexp Atom where
toSexp = SexpAtom
instance ToSexp Sym where
toSexp = SexpAtom . AtomSym
instance ToSexp Integer where
toSexp = SexpAtom . AtomInt
instance ToSexp Int where
toSexp = toSexp . fromIntegral @Int @Integer
instance ToSexp Scientific where
toSexp = SexpAtom . AtomSci
instance ToSexp Text where
toSexp = SexpAtom . AtomStr
instance ToSexp String where
toSexp = toSexp . T.pack
instance ToSexp Char where
toSexp = SexpAtom . AtomChar
toSexpDoc :: (ToSexp a) => a -> Doc ann
toSexpDoc = pretty . toSexp
toSexpText :: (ToSexp a) => a -> Text
toSexpText = renderStrict . layoutSmart defaultLayoutOptions . toSexpDoc