-- | Code generation for sequential Python.
module Futhark.CodeGen.Backends.SequentialPython
  ( compileProg,
  )
where

import Control.Monad
import Data.Text qualified as T
import Futhark.CodeGen.Backends.GenericPython qualified as GenericPython
import Futhark.CodeGen.Backends.GenericPython.AST
import Futhark.CodeGen.ImpCode.Sequential qualified as Imp
import Futhark.CodeGen.ImpGen.Sequential qualified as ImpGen
import Futhark.IR.SeqMem
import Futhark.MonadFreshNames

-- | Compile the program to Python.
compileProg ::
  (MonadFreshNames m) =>
  GenericPython.CompilerMode ->
  String ->
  Prog SeqMem ->
  m (ImpGen.Warnings, T.Text)
compileProg :: forall (m :: * -> *).
MonadFreshNames m =>
CompilerMode -> [Char] -> Prog SeqMem -> m (Warnings, Text)
compileProg CompilerMode
mode [Char]
class_name =
  Prog SeqMem -> m (Warnings, Program)
forall (m :: * -> *).
MonadFreshNames m =>
Prog SeqMem -> m (Warnings, Program)
ImpGen.compileProg
    (Prog SeqMem -> m (Warnings, Program))
-> ((Warnings, Program) -> m (Warnings, Text))
-> Prog SeqMem
-> m (Warnings, Text)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (Program -> m Text) -> (Warnings, Program) -> m (Warnings, Text)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> (Warnings, a) -> f (Warnings, b)
traverse
      ( CompilerMode
-> [Char]
-> Constructor
-> [PyStmt]
-> [PyStmt]
-> Operations Sequential ()
-> ()
-> [PyStmt]
-> [Option]
-> Program
-> m Text
forall (m :: * -> *) op s.
MonadFreshNames m =>
CompilerMode
-> [Char]
-> Constructor
-> [PyStmt]
-> [PyStmt]
-> Operations op s
-> s
-> [PyStmt]
-> [Option]
-> Definitions op
-> m Text
GenericPython.compileProg
          CompilerMode
mode
          [Char]
class_name
          Constructor
GenericPython.emptyConstructor
          [PyStmt]
imports
          [PyStmt]
forall {a}. [a]
defines
          Operations Sequential ()
operations
          ()
          []
          []
      )
  where
    imports :: [PyStmt]
imports =
      [ [Char] -> Maybe [Char] -> PyStmt
Import [Char]
"sys" Maybe [Char]
forall a. Maybe a
Nothing,
        [Char] -> Maybe [Char] -> PyStmt
Import [Char]
"numpy" (Maybe [Char] -> PyStmt) -> Maybe [Char] -> PyStmt
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"np",
        [Char] -> Maybe [Char] -> PyStmt
Import [Char]
"ctypes" (Maybe [Char] -> PyStmt) -> Maybe [Char] -> PyStmt
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"ct",
        [Char] -> Maybe [Char] -> PyStmt
Import [Char]
"time" Maybe [Char]
forall a. Maybe a
Nothing
      ]
    defines :: [a]
defines = []
    operations :: GenericPython.Operations Imp.Sequential ()
    operations :: Operations Sequential ()
operations =
      Operations Sequential ()
forall op s. Operations op s
GenericPython.defaultOperations
        { opsCompiler :: OpCompiler Sequential ()
GenericPython.opsCompiler = CompilerM Sequential () () -> OpCompiler Sequential ()
forall a b. a -> b -> a
const (CompilerM Sequential () () -> OpCompiler Sequential ())
-> CompilerM Sequential () () -> OpCompiler Sequential ()
forall a b. (a -> b) -> a -> b
$ () -> CompilerM Sequential () ()
forall a. a -> CompilerM Sequential () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (),
          opsCopy :: Copy Sequential ()
GenericPython.opsCopy = Copy Sequential ()
copySequentialMemory
        }

copySequentialMemory :: GenericPython.Copy Imp.Sequential ()
copySequentialMemory :: Copy Sequential ()
copySequentialMemory PyExp
destmem PyExp
destidx Space
DefaultSpace PyExp
srcmem PyExp
srcidx Space
DefaultSpace PyExp
nbytes PrimType
_bt =
  PyExp
-> PyExp -> PyExp -> PyExp -> PyExp -> CompilerM Sequential () ()
forall op s.
PyExp -> PyExp -> PyExp -> PyExp -> PyExp -> CompilerM op s ()
GenericPython.copyMemoryDefaultSpace PyExp
destmem PyExp
destidx PyExp
srcmem PyExp
srcidx PyExp
nbytes
copySequentialMemory PyExp
_ PyExp
_ Space
destspace PyExp
_ PyExp
_ Space
srcspace PyExp
_ PrimType
_ =
  [Char] -> CompilerM Sequential () ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> CompilerM Sequential () ())
-> [Char] -> CompilerM Sequential () ()
forall a b. (a -> b) -> a -> b
$ [Char]
"Cannot copy to " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Space -> [Char]
forall a. Show a => a -> [Char]
show Space
destspace [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" from " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Space -> [Char]
forall a. Show a => a -> [Char]
show Space
srcspace