{-# LANGUAGE FlexibleContexts #-}

-- | @futhark py@
module Futhark.CLI.Python (main) where

import Control.Monad.IO.Class
import qualified Futhark.CodeGen.Backends.SequentialPython as SequentialPy
import Futhark.Compiler.CLI
import Futhark.Passes
import System.Directory
import System.FilePath

-- | Run @futhark py@
main :: String -> [String] -> IO ()
main :: String -> [String] -> IO ()
main = ()
-> [CompilerOption ()]
-> String
-> String
-> Pipeline SOACS SeqMem
-> (FutharkConfig
    -> () -> CompilerMode -> String -> Prog SeqMem -> FutharkM ())
-> String
-> [String]
-> IO ()
forall cfg lore.
cfg
-> [CompilerOption cfg]
-> String
-> String
-> Pipeline SOACS lore
-> (FutharkConfig
    -> cfg -> CompilerMode -> String -> Prog lore -> FutharkM ())
-> String
-> [String]
-> IO ()
compilerMain
  ()
  []
  String
"Compile sequential Python"
  String
"Generate sequential Python code from optimised Futhark program."
  Pipeline SOACS SeqMem
sequentialCpuPipeline
  ((FutharkConfig
  -> () -> CompilerMode -> String -> Prog SeqMem -> FutharkM ())
 -> String -> [String] -> IO ())
-> (FutharkConfig
    -> () -> CompilerMode -> String -> Prog SeqMem -> FutharkM ())
-> String
-> [String]
-> IO ()
forall a b. (a -> b) -> a -> b
$ \FutharkConfig
fcfg () CompilerMode
mode String
outpath Prog SeqMem
prog -> do
    let class_name :: Maybe String
class_name =
          case CompilerMode
mode of
            CompilerMode
ToLibrary -> String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ String -> String
takeBaseName String
outpath
            CompilerMode
ToExecutable -> Maybe String
forall a. Maybe a
Nothing
    String
pyprog <- FutharkConfig -> FutharkM (Warnings, String) -> FutharkM String
forall a. FutharkConfig -> FutharkM (Warnings, a) -> FutharkM a
handleWarnings FutharkConfig
fcfg (FutharkM (Warnings, String) -> FutharkM String)
-> FutharkM (Warnings, String) -> FutharkM String
forall a b. (a -> b) -> a -> b
$ Maybe String -> Prog SeqMem -> FutharkM (Warnings, String)
forall (m :: * -> *).
MonadFreshNames m =>
Maybe String -> Prog SeqMem -> m (Warnings, String)
SequentialPy.compileProg Maybe String
class_name Prog SeqMem
prog

    case CompilerMode
mode of
      CompilerMode
ToLibrary ->
        IO () -> FutharkM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> FutharkM ()) -> IO () -> FutharkM ()
forall a b. (a -> b) -> a -> b
$ String -> String -> IO ()
writeFile (String
outpath String -> String -> String
`addExtension` String
"py") String
pyprog
      CompilerMode
ToExecutable -> IO () -> FutharkM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> FutharkM ()) -> IO () -> FutharkM ()
forall a b. (a -> b) -> a -> b
$ do
        String -> String -> IO ()
writeFile String
outpath String
pyprog
        Permissions
perms <- IO Permissions -> IO Permissions
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Permissions -> IO Permissions)
-> IO Permissions -> IO Permissions
forall a b. (a -> b) -> a -> b
$ String -> IO Permissions
getPermissions String
outpath
        String -> Permissions -> IO ()
setPermissions String
outpath (Permissions -> IO ()) -> Permissions -> IO ()
forall a b. (a -> b) -> a -> b
$ Bool -> Permissions -> Permissions
setOwnerExecutable Bool
True Permissions
perms