    module Futhark.CodeGen.Backends.GenericPython.AST
      ( PyExp (..),
        PyIdx (..),
        PyArg (..),
        PyStmt (..),
        module Language.Futhark.Core,
        PyProg (..),
        PyExcept (..),
        PyFunDef (..),
        PyClassDef (..),
      )
    where

    import Data.Text qualified as T
    import Futhark.Util.Pretty
    import Language.Futhark.Core

    data UnOp
      = -- | Boolean negation.
        Not
      | -- | Bitwise complement.
        Complement
      | -- | Numerical negation.
        Negate
      | -- | Absolute/numerical value.
        Abs
      deriving (UnOp -> UnOp -> Bool
    (UnOp -> UnOp -> Bool) -> (UnOp -> UnOp -> Bool) -> Eq UnOp
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: UnOp -> UnOp -> Bool
    == :: UnOp -> UnOp -> Bool
    $c/= :: UnOp -> UnOp -> Bool
    /= :: UnOp -> UnOp -> Bool
    Eq, Int -> UnOp -> ShowS
    [UnOp] -> ShowS
    UnOp -> String
    (Int -> UnOp -> ShowS)
    -> (UnOp -> String) -> ([UnOp] -> ShowS) -> Show UnOp
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> UnOp -> ShowS
    showsPrec :: Int -> UnOp -> ShowS
    $cshow :: UnOp -> String
    show :: UnOp -> String
    $cshowList :: [UnOp] -> ShowS
    showList :: [UnOp] -> ShowS
    Show)

    data PyExp
      = Integer Integer
      | Bool Bool
      | Float Double
      | String T.Text
      | RawStringLiteral T.Text
      | Var String
      | BinOp String PyExp PyExp
      | UnOp String PyExp
      | Cond PyExp PyExp PyExp
      | Index PyExp PyIdx
      | Call PyExp [PyArg]
      | Tuple [PyExp]
      | List [PyExp]
      | Field PyExp String
      | Dict [(PyExp, PyExp)]
      | Lambda String PyExp
      | None
      deriving (PyExp -> PyExp -> Bool
    (PyExp -> PyExp -> Bool) -> (PyExp -> PyExp -> Bool) -> Eq PyExp
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyExp -> PyExp -> Bool
    == :: PyExp -> PyExp -> Bool
    $c/= :: PyExp -> PyExp -> Bool
    /= :: PyExp -> PyExp -> Bool
    Eq, Int -> PyExp -> ShowS
    [PyExp] -> ShowS
    PyExp -> String
    (Int -> PyExp -> ShowS)
    -> (PyExp -> String) -> ([PyExp] -> ShowS) -> Show PyExp
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyExp -> ShowS
    showsPrec :: Int -> PyExp -> ShowS
    $cshow :: PyExp -> String
    show :: PyExp -> String
    $cshowList :: [PyExp] -> ShowS
    showList :: [PyExp] -> ShowS
    Show)

    data PyIdx
      = IdxRange PyExp PyExp
      | IdxExp PyExp
      deriving (PyIdx -> PyIdx -> Bool
    (PyIdx -> PyIdx -> Bool) -> (PyIdx -> PyIdx -> Bool) -> Eq PyIdx
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyIdx -> PyIdx -> Bool
    == :: PyIdx -> PyIdx -> Bool
    $c/= :: PyIdx -> PyIdx -> Bool
    /= :: PyIdx -> PyIdx -> Bool
    Eq, Int -> PyIdx -> ShowS
    [PyIdx] -> ShowS
    PyIdx -> String
    (Int -> PyIdx -> ShowS)
    -> (PyIdx -> String) -> ([PyIdx] -> ShowS) -> Show PyIdx
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyIdx -> ShowS
    showsPrec :: Int -> PyIdx -> ShowS
    $cshow :: PyIdx -> String
    show :: PyIdx -> String
    $cshowList :: [PyIdx] -> ShowS
    showList :: [PyIdx] -> ShowS
    Show)

    data PyArg
      = ArgKeyword String PyExp
      | Arg PyExp
      deriving (PyArg -> PyArg -> Bool
    (PyArg -> PyArg -> Bool) -> (PyArg -> PyArg -> Bool) -> Eq PyArg
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyArg -> PyArg -> Bool
    == :: PyArg -> PyArg -> Bool
    $c/= :: PyArg -> PyArg -> Bool
    /= :: PyArg -> PyArg -> Bool
    Eq, Int -> PyArg -> ShowS
    [PyArg] -> ShowS
    PyArg -> String
    (Int -> PyArg -> ShowS)
    -> (PyArg -> String) -> ([PyArg] -> ShowS) -> Show PyArg
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyArg -> ShowS
    showsPrec :: Int -> PyArg -> ShowS
    $cshow :: PyArg -> String
    show :: PyArg -> String
    $cshowList :: [PyArg] -> ShowS
    showList :: [PyArg] -> ShowS
    Show)

    data PyStmt
      = If PyExp [PyStmt] [PyStmt]
      | Try [PyStmt] [PyExcept]
      | While PyExp [PyStmt]
      | For String PyExp [PyStmt]
      | With PyExp [PyStmt]
      | Assign PyExp PyExp
      | AssignOp String PyExp PyExp
      | Comment String [PyStmt]
      | Assert PyExp PyExp
      | Raise PyExp
      | Exp PyExp
      | Return PyExp
      | Pass
      | -- Definition-like statements.
        Import String (Maybe String)
      | FunDef PyFunDef
      | ClassDef PyClassDef
      | -- Some arbitrary string of Python code.
        Escape T.Text
      deriving (PyStmt -> PyStmt -> Bool
    (PyStmt -> PyStmt -> Bool)
    -> (PyStmt -> PyStmt -> Bool) -> Eq PyStmt
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyStmt -> PyStmt -> Bool
    == :: PyStmt -> PyStmt -> Bool
    $c/= :: PyStmt -> PyStmt -> Bool
    /= :: PyStmt -> PyStmt -> Bool
    Eq, Int -> PyStmt -> ShowS
    [PyStmt] -> ShowS
    PyStmt -> String
    (Int -> PyStmt -> ShowS)
    -> (PyStmt -> String) -> ([PyStmt] -> ShowS) -> Show PyStmt
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyStmt -> ShowS
    showsPrec :: Int -> PyStmt -> ShowS
    $cshow :: PyStmt -> String
    show :: PyStmt -> String
    $cshowList :: [PyStmt] -> ShowS
    showList :: [PyStmt] -> ShowS
    Show)

    data PyExcept = Catch PyExp [PyStmt]
      deriving (PyExcept -> PyExcept -> Bool
    (PyExcept -> PyExcept -> Bool)
    -> (PyExcept -> PyExcept -> Bool) -> Eq PyExcept
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyExcept -> PyExcept -> Bool
    == :: PyExcept -> PyExcept -> Bool
    $c/= :: PyExcept -> PyExcept -> Bool
    /= :: PyExcept -> PyExcept -> Bool
    Eq, Int -> PyExcept -> ShowS
    [PyExcept] -> ShowS
    PyExcept -> String
    (Int -> PyExcept -> ShowS)
    -> (PyExcept -> String) -> ([PyExcept] -> ShowS) -> Show PyExcept
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyExcept -> ShowS
    showsPrec :: Int -> PyExcept -> ShowS
    $cshow :: PyExcept -> String
    show :: PyExcept -> String
    $cshowList :: [PyExcept] -> ShowS
    showList :: [PyExcept] -> ShowS
    Show)

    data PyFunDef = Def String [String] [PyStmt]
      deriving (PyFunDef -> PyFunDef -> Bool
    (PyFunDef -> PyFunDef -> Bool)
    -> (PyFunDef -> PyFunDef -> Bool) -> Eq PyFunDef
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyFunDef -> PyFunDef -> Bool
    == :: PyFunDef -> PyFunDef -> Bool
    $c/= :: PyFunDef -> PyFunDef -> Bool
    /= :: PyFunDef -> PyFunDef -> Bool
    Eq, Int -> PyFunDef -> ShowS
    [PyFunDef] -> ShowS
    PyFunDef -> String
    (Int -> PyFunDef -> ShowS)
    -> (PyFunDef -> String) -> ([PyFunDef] -> ShowS) -> Show PyFunDef
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyFunDef -> ShowS
    showsPrec :: Int -> PyFunDef -> ShowS
    $cshow :: PyFunDef -> String
    show :: PyFunDef -> String
    $cshowList :: [PyFunDef] -> ShowS
    showList :: [PyFunDef] -> ShowS
    Show)

    data PyClassDef = Class String [PyStmt]
      deriving (PyClassDef -> PyClassDef -> Bool
    (PyClassDef -> PyClassDef -> Bool)
    -> (PyClassDef -> PyClassDef -> Bool) -> Eq PyClassDef
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyClassDef -> PyClassDef -> Bool
    == :: PyClassDef -> PyClassDef -> Bool
    $c/= :: PyClassDef -> PyClassDef -> Bool
    /= :: PyClassDef -> PyClassDef -> Bool
    Eq, Int -> PyClassDef -> ShowS
    [PyClassDef] -> ShowS
    PyClassDef -> String
    (Int -> PyClassDef -> ShowS)
    -> (PyClassDef -> String)
    -> ([PyClassDef] -> ShowS)
    -> Show PyClassDef
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyClassDef -> ShowS
    showsPrec :: Int -> PyClassDef -> ShowS
    $cshow :: PyClassDef -> String
    show :: PyClassDef -> String
    $cshowList :: [PyClassDef] -> ShowS
    showList :: [PyClassDef] -> ShowS
    Show)

    newtype PyProg = PyProg [PyStmt]
      deriving (PyProg -> PyProg -> Bool
    (PyProg -> PyProg -> Bool)
    -> (PyProg -> PyProg -> Bool) -> Eq PyProg
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PyProg -> PyProg -> Bool
    == :: PyProg -> PyProg -> Bool
    $c/= :: PyProg -> PyProg -> Bool
    /= :: PyProg -> PyProg -> Bool
    Eq, Int -> PyProg -> ShowS
    [PyProg] -> ShowS
    PyProg -> String
    (Int -> PyProg -> ShowS)
    -> (PyProg -> String) -> ([PyProg] -> ShowS) -> Show PyProg
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PyProg -> ShowS
    showsPrec :: Int -> PyProg -> ShowS
    $cshow :: PyProg -> String
    show :: PyProg -> String
    $cshowList :: [PyProg] -> ShowS
    showList :: [PyProg] -> ShowS
    Show)

    instance Pretty PyIdx where
      pretty :: forall ann. PyIdx -> Doc ann
    pretty (IdxExp PyExp
    e) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e
      pretty (IdxRange PyExp
    from PyExp
    to) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    from Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":" Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    to

    instance Pretty PyArg where
      pretty :: forall ann. PyArg -> Doc ann
    pretty (ArgKeyword String
    k PyExp
    e) = String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    k Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    forall ann. Doc ann
    equals Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e
      pretty (Arg PyExp
    e) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e

    instance Pretty PyExp where
      pretty :: forall ann. PyExp -> Doc ann
    pretty (Integer Integer
    x) = Integer -> Doc ann
    forall ann. Integer -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty Integer
    x
      pretty (Bool Bool
    x) = Bool -> Doc ann
    forall ann. Bool -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty Bool
    x
      pretty (Float Double
    x)
        | Double -> Bool
    forall a. RealFloat a => a -> Bool
    isInfinite Double
    x = if Double
    x Double -> Double -> Bool
    forall a. Ord a => a -> a -> Bool
    > Double
    0 then Doc ann
    "float('inf')" else Doc ann
    "float('-inf')"
        | Bool
    otherwise = Double -> Doc ann
    forall ann. Double -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty Double
    x
      pretty (String Text
    x) = String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty (String -> Doc ann) -> String -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    forall a. Show a => a -> String
    show Text
    x
      pretty (RawStringLiteral Text
    s) = Doc ann
    "\"\"\"" Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Text -> Doc ann
    forall ann. Text -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty Text
    s Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    "\"\"\""
      pretty (Var String
    n) = String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty (String -> Doc ann) -> String -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map (\Char
    x -> if Char
    x Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\'' then Char
    'm' else Char
    x) String
    n
      pretty (Field PyExp
    e String
    s) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    "." Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    s
      pretty (BinOp String
    s PyExp
    e1 PyExp
    e2) = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    parens (PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e1 Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    s Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e2)
      pretty (UnOp String
    s PyExp
    e) = String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    s Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    parens (PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e)
      pretty (Cond PyExp
    e1 PyExp
    e2 PyExp
    e3) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e2 Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    "if" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e1 Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    "else" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e3
      pretty (Index PyExp
    src PyIdx
    idx) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    src Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    brackets (PyIdx -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyIdx -> Doc ann
    pretty PyIdx
    idx)
      pretty (Call PyExp
    fun [PyArg]
    exps) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    fun Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    parens ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyArg -> Doc ann) -> [PyArg] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyArg -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyArg -> Doc ann
    pretty [PyArg]
    exps)
      pretty (Tuple [PyExp
    dim]) = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    parens (PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    dim Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ",")
      pretty (Tuple [PyExp]
    dims) = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    parens ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyExp -> Doc ann) -> [PyExp] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty [PyExp]
    dims)
      pretty (List [PyExp]
    es) = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    brackets (Doc ann -> Doc ann) -> Doc ann -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ [Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyExp -> Doc ann) -> [PyExp] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty [PyExp]
    es
      pretty (Dict [(PyExp, PyExp)]
    kvs) = Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    braces (Doc ann -> Doc ann) -> Doc ann -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ [Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ ((PyExp, PyExp) -> Doc ann) -> [(PyExp, PyExp)] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map (PyExp, PyExp) -> Doc ann
    forall {a} {a} {ann}. (Pretty a, Pretty a) => (a, a) -> Doc ann
    ppElem [(PyExp, PyExp)]
    kvs
        where
          ppElem :: (a, a) -> Doc ann
    ppElem (a
    k, a
    v) = a -> Doc ann
    forall ann. a -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty a
    k Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    forall ann. Doc ann
    colon Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> a -> Doc ann
    forall ann. a -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty a
    v
      pretty (Lambda String
    p PyExp
    e) = Doc ann
    "lambda" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    p Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e
      pretty PyExp
    None = Doc ann
    "None"

    instance Pretty PyStmt where
      pretty :: forall ann. PyStmt -> Doc ann
    pretty (If PyExp
    cond [] []) =
        Doc ann
    "if"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    cond
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 Doc ann
    "pass"
      pretty (If PyExp
    cond [] [PyStmt]
    fbranch) =
        Doc ann
    "if"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    cond
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 Doc ann
    "pass"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Doc ann
    "else:"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    fbranch)
      pretty (If PyExp
    cond [PyStmt]
    tbranch []) =
        Doc ann
    "if"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    cond
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    tbranch)
      pretty (If PyExp
    cond [PyStmt]
    tbranch [PyStmt]
    fbranch) =
        Doc ann
    "if"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    cond
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    tbranch)
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Doc ann
    "else:"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    fbranch)
      pretty (Try [PyStmt]
    pystms [PyExcept]
    pyexcepts) =
        Doc ann
    "try:"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    pystms)
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> [Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ((PyExcept -> Doc ann) -> [PyExcept] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyExcept -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExcept -> Doc ann
    pretty [PyExcept]
    pyexcepts)
      pretty (While PyExp
    cond [PyStmt]
    body) =
        Doc ann
    "while"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    cond
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    body)
      pretty (For String
    i PyExp
    what [PyStmt]
    body) =
        Doc ann
    "for"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    i
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    "in"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    what
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    body)
      pretty (With PyExp
    what [PyStmt]
    body) =
        Doc ann
    "with"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    what
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    body)
      pretty (Assign PyExp
    e1 PyExp
    e2) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e1 Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    "=" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e2
      pretty (AssignOp String
    op PyExp
    e1 PyExp
    e2) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e1 Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty (String
    op String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "=") Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e2
      pretty (Comment String
    s [PyStmt]
    body) = Doc ann
    "#" Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    s Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> [Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ((PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    body)
      pretty (Assert PyExp
    e1 PyExp
    e2) = Doc ann
    "assert" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e1 Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    "," Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e2
      pretty (Raise PyExp
    e) = Doc ann
    "raise" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e
      pretty (Exp PyExp
    c) = PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    c
      pretty (Return PyExp
    e) = Doc ann
    "return" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    e
      pretty PyStmt
    Pass = Doc ann
    "pass"
      pretty (Import String
    from (Just String
    as)) =
        Doc ann
    "import" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    from Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    "as" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    as
      pretty (Import String
    from Maybe String
    Nothing) =
        Doc ann
    "import" Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    from
      pretty (FunDef PyFunDef
    d) = PyFunDef -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyFunDef -> Doc ann
    pretty PyFunDef
    d
      pretty (ClassDef PyClassDef
    d) = PyClassDef -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyClassDef -> Doc ann
    pretty PyClassDef
    d
      pretty (Escape Text
    s) = [Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (Text -> Doc ann) -> [Text] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map Text -> Doc ann
    forall ann. Text -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty ([Text] -> [Doc ann]) -> [Text] -> [Doc ann]
    forall a b. (a -> b) -> a -> b
    $ Text -> [Text]
    T.lines Text
    s

    instance Pretty PyFunDef where
      pretty :: forall ann. PyFunDef -> Doc ann
    pretty (Def String
    fname [String]
    params [PyStmt]
    body) =
        Doc ann
    "def"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    fname
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann
    parens ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    commasep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (String -> Doc ann) -> [String] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty [String]
    params)
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ((PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    body))

    instance Pretty PyClassDef where
      pretty :: forall ann. PyClassDef -> Doc ann
    pretty (Class String
    cname [PyStmt]
    body) =
        Doc ann
    "class"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> String -> Doc ann
    forall ann. String -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    pretty String
    cname
          Doc ann -> Doc ann -> Doc ann
    forall a. Semigroup a => a -> a -> a
    <> Doc ann
    ":"
            Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    stack ((PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    body))

    instance Pretty PyExcept where
      pretty :: forall ann. PyExcept -> Doc ann
    pretty (Catch PyExp
    pyexp [PyStmt]
    stms) =
        Doc ann
    "except"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> PyExp -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyExp -> Doc ann
    pretty PyExp
    pyexp
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    <+> Doc ann
    "as e:"
          Doc ann -> Doc ann -> Doc ann
    forall ann. Doc ann -> Doc ann -> Doc ann
    </> Int -> Doc ann -> Doc ann
    forall ann. Int -> Doc ann -> Doc ann
    indent Int
    2 ([Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    vsep ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
    forall a b. (a -> b) -> a -> b
    $ (PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    stms)

    instance Pretty PyProg where
      pretty :: forall ann. PyProg -> Doc ann
    pretty (PyProg [PyStmt]
    stms) = [Doc ann] -> Doc ann
    forall a. [Doc a] -> Doc a
    vsep ((PyStmt -> Doc ann) -> [PyStmt] -> [Doc ann]
    forall a b. (a -> b) -> [a] -> [b]
    map PyStmt -> Doc ann
    forall a ann. Pretty a => a -> Doc ann
    forall ann. PyStmt -> Doc ann
    pretty [PyStmt]
    stms)