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)