futhark-0.25.3: src/Futhark/CodeGen/Backends/GenericPython/AST.hs
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 (Eq, 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]
| Cast PyExp String
| Tuple [PyExp]
| List [PyExp]
| Field PyExp String
| Dict [(PyExp, PyExp)]
| Lambda String PyExp
| None
deriving (Eq, Show)
data PyIdx
= IdxRange PyExp PyExp
| IdxExp PyExp
deriving (Eq, Show)
data PyArg
= ArgKeyword String PyExp
| Arg PyExp
deriving (Eq, 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 (Eq, Show)
data PyExcept = Catch PyExp [PyStmt]
deriving (Eq, Show)
data PyFunDef = Def String [String] [PyStmt]
deriving (Eq, Show)
data PyClassDef = Class String [PyStmt]
deriving (Eq, Show)
newtype PyProg = PyProg [PyStmt]
deriving (Eq, Show)
instance Pretty PyIdx where
pretty (IdxExp e) = pretty e
pretty (IdxRange from to) = pretty from <> ":" <> pretty to
instance Pretty PyArg where
pretty (ArgKeyword k e) = pretty k <> equals <> pretty e
pretty (Arg e) = pretty e
instance Pretty PyExp where
pretty (Integer x) = pretty x
pretty (Bool x) = pretty x
pretty (Float x)
| isInfinite x = if x > 0 then "float('inf')" else "float('-inf')"
| otherwise = pretty x
pretty (String x) = pretty $ show x
pretty (RawStringLiteral s) = "\"\"\"" <> pretty s <> "\"\"\""
pretty (Var n) = pretty $ map (\x -> if x == '\'' then 'm' else x) n
pretty (Field e s) = pretty e <> "." <> pretty s
pretty (BinOp s e1 e2) = parens (pretty e1 <+> pretty s <+> pretty e2)
pretty (UnOp s e) = pretty s <> parens (pretty e)
pretty (Cond e1 e2 e3) = pretty e2 <+> "if" <+> pretty e1 <+> "else" <+> pretty e3
pretty (Cast src bt) =
"ct.cast"
<> parens
( pretty src <> ","
<+> "ct.POINTER" <> parens (pretty bt)
)
pretty (Index src idx) = pretty src <> brackets (pretty idx)
pretty (Call fun exps) = pretty fun <> parens (commasep $ map pretty exps)
pretty (Tuple [dim]) = parens (pretty dim <> ",")
pretty (Tuple dims) = parens (commasep $ map pretty dims)
pretty (List es) = brackets $ commasep $ map pretty es
pretty (Dict kvs) = braces $ commasep $ map ppElem kvs
where
ppElem (k, v) = pretty k <> colon <+> pretty v
pretty (Lambda p e) = "lambda" <+> pretty p <> ":" <+> pretty e
pretty None = "None"
instance Pretty PyStmt where
pretty (If cond [] []) =
"if"
<+> pretty cond
<> ":"
</> indent 2 "pass"
pretty (If cond [] fbranch) =
"if"
<+> pretty cond
<> ":"
</> indent 2 "pass"
</> "else:"
</> indent 2 (stack $ map pretty fbranch)
pretty (If cond tbranch []) =
"if"
<+> pretty cond
<> ":"
</> indent 2 (stack $ map pretty tbranch)
pretty (If cond tbranch fbranch) =
"if"
<+> pretty cond
<> ":"
</> indent 2 (stack $ map pretty tbranch)
</> "else:"
</> indent 2 (stack $ map pretty fbranch)
pretty (Try pystms pyexcepts) =
"try:"
</> indent 2 (stack $ map pretty pystms)
</> stack (map pretty pyexcepts)
pretty (While cond body) =
"while"
<+> pretty cond
<> ":"
</> indent 2 (stack $ map pretty body)
pretty (For i what body) =
"for"
<+> pretty i
<+> "in"
<+> pretty what
<> ":"
</> indent 2 (stack $ map pretty body)
pretty (With what body) =
"with"
<+> pretty what
<> ":"
</> indent 2 (stack $ map pretty body)
pretty (Assign e1 e2) = pretty e1 <+> "=" <+> pretty e2
pretty (AssignOp op e1 e2) = pretty e1 <+> pretty (op ++ "=") <+> pretty e2
pretty (Comment s body) = "#" <> pretty s </> stack (map pretty body)
pretty (Assert e1 e2) = "assert" <+> pretty e1 <> "," <+> pretty e2
pretty (Raise e) = "raise" <+> pretty e
pretty (Exp c) = pretty c
pretty (Return e) = "return" <+> pretty e
pretty Pass = "pass"
pretty (Import from (Just as)) =
"import" <+> pretty from <+> "as" <+> pretty as
pretty (Import from Nothing) =
"import" <+> pretty from
pretty (FunDef d) = pretty d
pretty (ClassDef d) = pretty d
pretty (Escape s) = stack $ map pretty $ T.lines s
instance Pretty PyFunDef where
pretty (Def fname params body) =
"def"
<+> pretty fname
<> parens (commasep $ map pretty params)
<> ":"
</> indent 2 (stack (map pretty body))
instance Pretty PyClassDef where
pretty (Class cname body) =
"class"
<+> pretty cname
<> ":"
</> indent 2 (stack (map pretty body))
instance Pretty PyExcept where
pretty (Catch pyexp stms) =
"except"
<+> pretty pyexp
<+> "as e:"
</> indent 2 (vsep $ map pretty stms)
instance Pretty PyProg where
pretty (PyProg stms) = vsep (map pretty stms)