content: \begin{code}
  module Language where
  import Data.Text.Prettyprint.Doc as PP
  
  newtype Literal = Literal { unLiteral :: String } deriving(Ord, Eq)
  instance Pretty Literal where
    pretty = pretty . unLiteral
  
  data BinOp = Plus | Multiply | L | And
  instance Pretty BinOp where
    pretty Plus = pretty "+"
    pretty Multiply = pretty "*"
    pretty L = pretty "<"
    pretty And = pretty "&&"
  
  data Expr a = EBinOp a (Expr a) BinOp (Expr a) |
                    EInt a Int |
                    ELiteral a Literal
  
  instance Pretty (Expr a) where
    pretty (EBinOp _ l op r) = pretty "(" <+> pretty op <+>
                               pretty l <+> pretty r <+> pretty ")"
    pretty (EInt _ i) = pretty i
    pretty (ELiteral _ lit) = pretty lit
  
  type Expr' = Expr ()
  
  data Stmt a = If a (Expr a) (Block a) (Block a) |
                While a (Expr a) (Block a) |
                Assign a Literal (Expr a) |
                Define a Literal |
                Return a (Expr a)
  type Block a = [Stmt a]
  
  
  nestDepth :: Int
  nestDepth = 4
  
  instance Pretty (Stmt a) where
    pretty (If _ cond then' else') = pretty "if" <+> pretty cond <+>
                                    PP.braces (nest 4 (pretty then')) <+>
                                    PP.braces (nest 4 (pretty else'))
  
    pretty (While _ cond body) = pretty "while" <+> pretty cond <+> PP.braces (nest 4 (pretty body))
    pretty (Assign _ lhs rhs) = pretty "assign" <+> pretty lhs <+> pretty ":=" <+> pretty rhs
    pretty (Define _ lit) = pretty "define" <+> pretty lit
    pretty (Return _ expr) = pretty "return" <+> pretty expr
  
  type Stmt' = Stmt ()
  
  
  newtype Program a = Program [Stmt a]
  type Program' = Program ()
  
  instance Pretty (Program a) where
    pretty (Program stmts) = vcat (map pretty stmts)
  \end{code}
  