{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Safe #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | The Synolon concrete syntax (@.syn@) pretty-printer (doc/synolon.md §3.4,
--   §9): the process declarations, and the program that embeds Eidos datatypes
--   and definitions (printed by "ReWire.Eidos.Pretty", as are the
--   expressions inside blocks). "ReWire.Synolon.Parse" is the other half of
--   the round-trip contract: @parse . pretty@ is the identity modulo
--   annotations, and @pretty . parse . pretty == pretty@ is a tested
--   fixpoint.
--
--   The 'Block' instance is normative beyond printing: the alpha-equal
--   block merge of "ReWire.Synolon.Transform" keys blocks on this rendering
--   of their canonically renumbered form, so what it prints (parameter
--   binders, commands with their binders and right-hand sides, the
--   terminator with its target labels) decides which blocks merge, and so
--   the state count of every device.
module ReWire.Synolon.Pretty
      ( prettyProgram
      , ppProgram, ppProc, ppCell, ppBlock, ppCmd, ppTerm, ppTAlt, ppAtomE
      ) where

import ReWire.Eidos.Pretty (ppDataDefn, ppDefn, ppExp, ppTy, ppId, ppBinder, ppOcc')
import ReWire.Pretty (Doc, Pretty (pretty), text, vsep, hsep, nest, align, parens, punctuate, comma, semi, space, (<+>), prettyPrint')
import ReWire.Synolon.Syntax

import Data.List (intersperse)
import Data.Text (Text)

-- | Render a whole program in the .syn concrete syntax.
prettyProgram :: Program -> Text
prettyProgram :: Program -> Text
prettyProgram = Doc (ZonkAny 0) -> Text
forall ann. Doc ann -> Text
prettyPrint' (Doc (ZonkAny 0) -> Text)
-> (Program -> Doc (ZonkAny 0)) -> Program -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Program -> Doc (ZonkAny 0)
forall an. Program -> Doc an
ppProgram


-- | @proc P : ty ~> ty clock? { state* entry block* }@.
ppProc :: Proc -> Doc an
ppProc :: forall an. Proc -> Doc an
ppProc (Proc Annote
_ Text
n Ty
it Ty
ot Maybe Text
clk [Cell]
cells Block
entry [(Id, Block)]
blocks) = [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep
      [ Int -> Doc an -> Doc an
forall ann. Int -> Doc ann -> Doc ann
nest Int
6 (Doc an -> Doc an) -> Doc an -> Doc an
forall a b. (a -> b) -> a -> b
$ [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ (Text -> Doc an
forall ann. Text -> Doc ann
text Text
"proc" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
ppOcc' Text
n Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
":" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Ty -> Doc an
forall an. Ty -> Doc an
ppTy Ty
it Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"~>" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Ty -> Doc an
forall an. Ty -> Doc an
ppTy Ty
ot Doc an -> Doc an -> Doc an
forall a. Semigroup a => a -> a -> a
<> Doc an -> (Text -> Doc an) -> Maybe Text -> Doc an
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Doc an
forall a. Monoid a => a
mempty Text -> Doc an
forall ann. Text -> Doc ann
ppClock Maybe Text
clk Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"{")
                      Doc an -> [Doc an] -> [Doc an]
forall a. a -> [a] -> [a]
: (Cell -> Doc an) -> [Cell] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Cell -> Doc an
forall an. Cell -> Doc an
ppCell [Cell]
cells
                      [Doc an] -> [Doc an] -> [Doc an]
forall a. Semigroup a => a -> a -> a
<> [Block -> Doc an
forall an. Block -> Doc an
ppEntry Block
entry]
                      [Doc an] -> [Doc an] -> [Doc an]
forall a. Semigroup a => a -> a -> a
<> ((Id, Block) -> Doc an) -> [(Id, Block)] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map ((Id -> Block -> Doc an) -> (Id, Block) -> Doc an
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Id -> Block -> Doc an
forall an. Id -> Block -> Doc an
ppBlock) [(Id, Block)]
blocks
      , Text -> Doc an
forall ann. Text -> Doc ann
text Text
"}"
      ]
      where ppClock :: Text -> Doc an
            ppClock :: forall ann. Text -> Doc ann
ppClock Text
c = Doc an
forall ann. Doc ann
space Doc an -> Doc an -> Doc an
forall a. Semigroup a => a -> a -> a
<> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"@" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"clock" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
ppOcc' Text
c

ppCell :: Cell -> Doc an
ppCell :: forall an. Cell -> Doc an
ppCell (Cell Annote
_ Text
s Ty
t Maybe Exp
e0) = Text -> Doc an
forall ann. Text -> Doc ann
text Text
"state" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
ppOcc' Text
s Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
":" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Ty -> Doc an
forall an. Ty -> Doc an
ppTy Ty
t
      Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
":=" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> (Exp -> Doc an) -> Maybe Exp -> Doc an
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> Doc an
forall ann. Text -> Doc ann
text Text
"undef") Exp -> Doc an
forall an. Exp -> Doc an
ppExp Maybe Exp
e0 Doc an -> Doc an -> Doc an
forall a. Semigroup a => a -> a -> a
<> Doc an
forall ann. Doc ann
semi

ppEntry :: Block -> Doc an
ppEntry :: forall an. Block -> Doc an
ppEntry Block
b = [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep [ Int -> Doc an -> Doc an
forall ann. Int -> Doc ann -> Doc ann
nest Int
6 (Doc an -> Doc an) -> Doc an -> Doc an
forall a b. (a -> b) -> a -> b
$ [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ Text -> Doc an
forall ann. Text -> Doc ann
text Text
"entry {" Doc an -> [Doc an] -> [Doc an]
forall a. a -> [a] -> [a]
: Block -> [Doc an]
forall an. Block -> [Doc an]
ppBlockBody Block
b, Text -> Doc an
forall ann. Text -> Doc ann
text Text
"}" ]

ppBlock :: Id -> Block -> Doc an
ppBlock :: forall an. Id -> Block -> Doc an
ppBlock Id
l Block
b = [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep
      [ Int -> Doc an -> Doc an
forall ann. Int -> Doc ann -> Doc ann
nest Int
6 (Doc an -> Doc an) -> Doc an -> Doc an
forall a b. (a -> b) -> a -> b
$ [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ (Text -> Doc an
forall ann. Text -> Doc ann
text Text
"block" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Id -> Doc an
forall an. Id -> Doc an
ppId Id
l Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
parens ([Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
hsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ Doc an -> [Doc an] -> [Doc an]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc an
forall ann. Doc ann
comma ([Doc an] -> [Doc an]) -> [Doc an] -> [Doc an]
forall a b. (a -> b) -> a -> b
$ (Id -> Doc an) -> [Id] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Doc an
forall an. Id -> Doc an
ppBinder ([Id] -> [Doc an]) -> [Id] -> [Doc an]
forall a b. (a -> b) -> a -> b
$ Block -> [Id]
blkParams Block
b) Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"{")
                      Doc an -> [Doc an] -> [Doc an]
forall a. a -> [a] -> [a]
: Block -> [Doc an]
forall an. Block -> [Doc an]
ppBlockBody Block
b
      , Text -> Doc an
forall ann. Text -> Doc ann
text Text
"}"
      ]

ppBlockBody :: Block -> [Doc an]
ppBlockBody :: forall an. Block -> [Doc an]
ppBlockBody Block
b = (Cmd -> Doc an) -> [Cmd] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Cmd -> Doc an
forall an. Cmd -> Doc an
ppCmd (Block -> [Cmd]
blkCmds Block
b) [Doc an] -> [Doc an] -> [Doc an]
forall a. Semigroup a => a -> a -> a
<> [Term -> Doc an
forall an. Term -> Doc an
ppTerm (Term -> Doc an) -> Term -> Doc an
forall a b. (a -> b) -> a -> b
$ Block -> Term
blkTerm Block
b]

ppCmd :: Cmd -> Doc an
ppCmd :: forall an. Cmd -> Doc an
ppCmd = \ case
      CmdBind Annote
_ Id
x Exp
e -> Id -> Doc an
forall an. Id -> Doc an
ppId Id
x Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"::" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Ty -> Doc an
forall an. Ty -> Doc an
ppTy (Sig -> Ty
sigTy (Sig -> Ty) -> Sig -> Ty
forall a b. (a -> b) -> a -> b
$ Id -> Sig
idSig Id
x) Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"<-" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
align (Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e) Doc an -> Doc an -> Doc an
forall a. Semigroup a => a -> a -> a
<> Doc an
forall ann. Doc ann
semi
      CmdGet Annote
_ Id
x Text
s  -> Id -> Doc an
forall an. Id -> Doc an
ppId Id
x Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"::" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Ty -> Doc an
forall an. Ty -> Doc an
ppTy (Sig -> Ty
sigTy (Sig -> Ty) -> Sig -> Ty
forall a b. (a -> b) -> a -> b
$ Id -> Sig
idSig Id
x) Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"<-" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"get" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
ppOcc' Text
s Doc an -> Doc an -> Doc an
forall a. Semigroup a => a -> a -> a
<> Doc an
forall ann. Doc ann
semi
      CmdPut Annote
_ Text
s Exp
a  -> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"put" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
ppOcc' Text
s Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc an
forall an. Exp -> Doc an
ppAtomE Exp
a Doc an -> Doc an -> Doc an
forall a. Semigroup a => a -> a -> a
<> Doc an
forall ann. Doc ann
semi

ppTerm :: Term -> Doc an
ppTerm :: forall an. Term -> Doc an
ppTerm = \ case
      Pause Annote
_ Exp
a Id
l [Exp]
args -> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"pause" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc an
forall an. Exp -> Doc an
ppAtomE Exp
a Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"->" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Id -> Doc an
forall an. Id -> Doc an
ppId Id
l
            Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
parens ([Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
hsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ Doc an -> [Doc an] -> [Doc an]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc an
forall ann. Doc ann
comma ([Doc an] -> [Doc an]) -> [Doc an] -> [Doc an]
forall a b. (a -> b) -> a -> b
$ (Exp -> Doc an) -> [Exp] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> Doc an
forall an. Exp -> Doc an
ppAtomE [Exp]
args)
      Goto Annote
_ Id
l [Exp]
args    -> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"goto" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Id -> Doc an
forall an. Id -> Doc an
ppId Id
l
            Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
parens ([Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
hsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ Doc an -> [Doc an] -> [Doc an]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc an
forall ann. Doc ann
comma ([Doc an] -> [Doc an]) -> [Doc an] -> [Doc an]
forall a b. (a -> b) -> a -> b
$ (Exp -> Doc an) -> [Exp] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Exp -> Doc an
forall an. Exp -> Doc an
ppAtomE [Exp]
args)
      Halt Annote
_ Exp
a         -> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"halt" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc an
forall an. Exp -> Doc an
ppAtomE Exp
a
      TCase Annote
_ Exp
a [TAlt]
alts   -> [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep
            [ Int -> Doc an -> Doc an
forall ann. Int -> Doc ann -> Doc ann
nest Int
6 (Doc an -> Doc an) -> Doc an -> Doc an
forall a b. (a -> b) -> a -> b
$ [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ (Text -> Doc an
forall ann. Text -> Doc ann
text Text
"case" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Exp -> Doc an
forall an. Exp -> Doc an
ppAtomE Exp
a Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"of" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"{")
                            Doc an -> [Doc an] -> [Doc an]
forall a. a -> [a] -> [a]
: Doc an -> [Doc an] -> [Doc an]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc an
forall ann. Doc ann
semi ((TAlt -> Doc an) -> [TAlt] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map TAlt -> Doc an
forall an. TAlt -> Doc an
ppTAlt [TAlt]
alts)
            , Text -> Doc an
forall ann. Text -> Doc ann
text Text
"}"
            ]

ppTAlt :: TAlt -> Doc an
ppTAlt :: forall an. TAlt -> Doc an
ppTAlt (TAlt Annote
_ AltCon
c [Id]
xs Term
t) = case AltCon
c of
      AltCon
DefaultAlt -> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"_" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"->" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
align (Term -> Doc an
forall an. Term -> Doc an
ppTerm Term
t)
      DataAlt Text
d  -> [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
hsep (Text -> Doc an
forall ann. Text -> Doc ann
ppOcc' Text
d Doc an -> [Doc an] -> [Doc an]
forall a. a -> [a] -> [a]
: (Id -> Doc an) -> [Id] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Doc an
forall an. Id -> Doc an
ppBinder [Id]
xs) Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"->" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
align (Term -> Doc an
forall an. Term -> Doc an
ppTerm Term
t)
      LitAlt Integer
n   -> Integer -> Doc an
forall ann. Integer -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty Integer
n Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc an
forall ann. Text -> Doc ann
text Text
"->" Doc an -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
align (Term -> Doc an
forall an. Term -> Doc an
ppTerm Term
t)

-- | An expression in an atom position of the machine grammar: the
--   already-atom-shaped forms (variables, literals, constructor and
--   primitive occurrences, which self-parenthesize) print as themselves;
--   anything else parenthesizes (the parser's atom production admits a
--   parenthesized expression).
ppAtomE :: Exp -> Doc an
ppAtomE :: forall an. Exp -> Doc an
ppAtomE Exp
e = case Exp
e of
      Var {}     -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      LitStr {}  -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      LitInt {}  -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      LitList {} -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      LitVec {}  -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      Con {}     -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      Prim {}    -> Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e
      Exp
_          -> Doc an -> Doc an
forall ann. Doc ann -> Doc ann
parens (Doc an -> Doc an) -> Doc an -> Doc an
forall a b. (a -> b) -> a -> b
$ Exp -> Doc an
forall an. Exp -> Doc an
ppExp Exp
e


-- | A whole program: datatypes, definitions, and processes, separated by
--   blank lines.
ppProgram :: Program -> Doc an
ppProgram :: forall an. Program -> Doc an
ppProgram (Program [DataDefn]
datas [Defn]
defns [Proc]
procs) = [Doc an] -> Doc an
forall ann. [Doc ann] -> Doc ann
vsep ([Doc an] -> Doc an) -> [Doc an] -> Doc an
forall a b. (a -> b) -> a -> b
$ Doc an -> [Doc an] -> [Doc an]
forall a. a -> [a] -> [a]
intersperse (Text -> Doc an
forall ann. Text -> Doc ann
text Text
"") ([Doc an] -> [Doc an]) -> [Doc an] -> [Doc an]
forall a b. (a -> b) -> a -> b
$
      (DataDefn -> Doc an) -> [DataDefn] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map DataDefn -> Doc an
forall an. DataDefn -> Doc an
ppDataDefn [DataDefn]
datas
      [Doc an] -> [Doc an] -> [Doc an]
forall a. Semigroup a => a -> a -> a
<> (Defn -> Doc an) -> [Defn] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Defn -> Doc an
forall an. Defn -> Doc an
ppDefn [Defn]
defns
      [Doc an] -> [Doc an] -> [Doc an]
forall a. Semigroup a => a -> a -> a
<> (Proc -> Doc an) -> [Proc] -> [Doc an]
forall a b. (a -> b) -> [a] -> [b]
map Proc -> Doc an
forall an. Proc -> Doc an
ppProc [Proc]
procs

---
--- Pretty instances (the Eidos types keep theirs in ReWire.Eidos.Pretty).
---

instance Pretty Block where
      pretty :: forall an. Block -> Doc an
pretty Block
b = [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann
parens ([Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
hsep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> [Doc ann] -> [Doc ann]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc ann
forall ann. Doc ann
comma ([Doc ann] -> [Doc ann]) -> [Doc ann] -> [Doc ann]
forall a b. (a -> b) -> a -> b
$ (Id -> Doc ann) -> [Id] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Doc ann
forall an. Id -> Doc an
ppBinder ([Id] -> [Doc ann]) -> [Id] -> [Doc ann]
forall a b. (a -> b) -> a -> b
$ Block -> [Id]
blkParams Block
b) Doc ann -> [Doc ann] -> [Doc ann]
forall a. a -> [a] -> [a]
: Block -> [Doc ann]
forall an. Block -> [Doc an]
ppBlockBody Block
b

instance Pretty Proc where
      pretty :: forall an. Proc -> Doc an
pretty = Proc -> Doc ann
forall an. Proc -> Doc an
ppProc

instance Pretty Program where
      pretty :: forall an. Program -> Doc an
pretty = Program -> Doc ann
forall an. Program -> Doc an
ppProgram