pretty printer

uses ISeq, as described in 'Implementing Functional Languages'. going to try using a style similar to ShowS instead.
This commit is contained in:
crumbtoo
2023-11-09 14:55:03 -07:00
parent 80e55e6437
commit 708e611799
3 changed files with 61 additions and 0 deletions

View File

@@ -2,6 +2,7 @@
module Core where
----------------------------------------------------------------------------------
import Data.Coerce
import Data.Pretty
----------------------------------------------------------------------------------
data Expr = Var Name
@@ -39,6 +40,11 @@ newtype Program = Program [ScDef]
----------------------------------------------------------------------------------
instance Pretty Expr where
prettyPrec _ (Var k) = iStr k
----------------------------------------------------------------------------------
instance Semigroup Program where
(<>) = coerce $ (++) @ScDef

54
src/Data/Pretty.hs Normal file
View File

@@ -0,0 +1,54 @@
module Data.Pretty
( Pretty(..)
, ISeq
, iNil
, iStr
, iAppend
)
where
----------------------------------------------------------------------------------
class Pretty a where
pretty :: a -> String
prettyPrec :: Int -> a -> ISeq
pretty = squash . prettyPrec 0
prettyPrec _ a = iBracket (iStr $ pretty a)
data ISeq where
INil :: ISeq
IStr :: String -> ISeq
IAppend :: ISeq -> ISeq -> ISeq
instance Semigroup ISeq where
(<>) = IAppend
instance Monoid ISeq where
mempty = INil
squash :: ISeq -> String
squash = flatten . pure
flatten :: [ISeq] -> String
flatten (INil : ss) = flatten ss
flatten (IStr s : ss) = s ++ flatten ss
flatten (IAppend r s : ss) = flatten (r : s : ss)
iNil :: ISeq
iNil = INil
iStr :: String -> ISeq
iStr = IStr
iAppend :: ISeq -> ISeq -> ISeq
iAppend = IAppend
iIndent :: ISeq -> ISeq
iIndent = id
iBreak :: ISeq
iBreak = iStr "\n"
iBracket :: ISeq -> ISeq
iBracket s = iStr "(" `iAppend` s `iAppend` iStr ")"