module Futhark.Compiler.CLI
( compilerMain
, CompilerOption
, CompilerMode(..)
)
where
import Control.Monad
import Data.Maybe
import System.FilePath
import System.Console.GetOpt
import System.IO
import Futhark.Pipeline
import Futhark.Compiler
import Futhark.Representation.AST (Prog)
import Futhark.Representation.SOACS (SOACS)
import Futhark.Util.Options
compilerMain :: cfg
-> [CompilerOption cfg]
-> String
-> String
-> Pipeline SOACS lore
-> (cfg -> CompilerMode -> FilePath -> Prog lore -> FutharkM ())
-> String
-> [String]
-> IO ()
compilerMain cfg cfg_opts name desc pipeline doIt prog args = do
hSetEncoding stdout utf8
hSetEncoding stderr utf8
mainWithOptions (newCompilerConfig cfg) (commandLineOptions ++ map wrapOption cfg_opts)
"options... program" inspectNonOptions prog args
where inspectNonOptions [file] config = Just $ compile config file
inspectNonOptions _ _ = Nothing
compile config filepath =
runCompilerOnProgram (futharkConfig config)
pipeline (action config filepath) filepath
action config filepath =
Action { actionName = name
, actionDescription = desc
, actionProcedure =
doIt (compilerConfig config) (compilerMode config) $
outputFilePath filepath config
}
type CompilerOption cfg = OptDescr (Either (IO ()) (cfg -> cfg))
type CoreCompilerOption cfg = OptDescr (Either
(IO ())
(CompilerConfig cfg -> CompilerConfig cfg))
commandLineOptions :: [CoreCompilerOption cfg]
commandLineOptions =
[ Option "o" []
(ReqArg (\filename -> Right $ \config -> config { compilerOutput = Just filename })
"FILE")
"Name of the compiled binary."
, Option "v" ["verbose"]
(OptArg (Right . incVerbosity) "FILE")
"Print verbose output on standard error; wrong program to FILE."
, Option [] ["library"]
(NoArg $ Right $ \config -> config { compilerMode = ToLibrary })
"Generate a library instead of an executable."
, Option [] ["executable"]
(NoArg $ Right $ \config -> config { compilerMode = ToExecutable })
"Generate an executable instead of a library (set by default)."
, Option [] ["Werror"]
(NoArg $ Right $ \config -> config { compilerWerror = True })
"Treat warnings as errors."
, Option [] ["safe"]
(NoArg $ Right $ \config -> config { compilerSafe = True })
"Ignore 'unsafe' in code."
]
wrapOption :: CompilerOption cfg -> CoreCompilerOption cfg
wrapOption = fmap wrap
where wrap f = do
g <- f
return $ \cfg -> cfg { compilerConfig = g (compilerConfig cfg) }
incVerbosity :: Maybe FilePath -> CompilerConfig cfg -> CompilerConfig cfg
incVerbosity file cfg =
cfg { compilerVerbose = (v, file `mplus` snd (compilerVerbose cfg)) }
where v = case fst $ compilerVerbose cfg of
NotVerbose -> Verbose
Verbose -> VeryVerbose
VeryVerbose -> VeryVerbose
data CompilerConfig cfg =
CompilerConfig { compilerOutput :: Maybe FilePath
, compilerVerbose :: (Verbosity, Maybe FilePath)
, compilerMode :: CompilerMode
, compilerWerror :: Bool
, compilerSafe :: Bool
, compilerConfig :: cfg
}
data CompilerMode = ToLibrary | ToExecutable deriving (Eq, Ord, Show)
newCompilerConfig :: cfg -> CompilerConfig cfg
newCompilerConfig x = CompilerConfig { compilerOutput = Nothing
, compilerVerbose = (NotVerbose, Nothing)
, compilerMode = ToExecutable
, compilerWerror = False
, compilerSafe = False
, compilerConfig = x
}
outputFilePath :: FilePath -> CompilerConfig cfg -> FilePath
outputFilePath srcfile =
fromMaybe (srcfile `replaceExtension` "") . compilerOutput
futharkConfig :: CompilerConfig cfg -> FutharkConfig
futharkConfig config =
newFutharkConfig { futharkVerbose = compilerVerbose config
, futharkWerror = compilerWerror config
, futharkSafe = compilerSafe config
}