SJW/src/Main.hs

76 lines
2.2 KiB
Haskell

{-# LANGUAGE NamedFieldPuns #-}
module Main where
import qualified Compiler (main)
import Context (CodePath(..), Context (..), Path(..))
import Control.Applicative (many, optional)
import Control.Monad.RWS (evalRWST)
import qualified Data.Map as Map (empty)
import Data.Text (Text)
import qualified Data.Text as Text (unpack)
import Data.Version (showVersion)
import qualified Module (parse)
import Options.Applicative (
Parser, execParser, fullDesc, info, header, help, helper, long, metavar
, option, short, str, strArgument, strOption, value
)
import qualified Paths_SJW as SJW (version)
import System.IO (stderr, hPutStrLn)
data Config = Config {
includes :: [FilePath]
, mainIs :: String
, outputFile :: FilePath
, target :: FilePath
} deriving (Show)
configParser :: Parser Config
configParser = Config
<$> many (strOption (
long "include"
<> short 'I'
<> metavar "PACKAGE"
<> help "Include this package during compilation"
))
<*> strOption (
long "main-is"
<> short 'm'
<> metavar "MODULE_NAME"
<> help "The name of the main module containing the code to run"
<> value "Main"
)
<*> strOption (
long "output"
<> short 'o'
<> metavar "OUTPUT_PATH"
<> help "The path where to create the compiled script (stdout if \"-\" or if the option is missing)"
<> value "-"
)
<*> strArgument (
metavar "SOURCE_DIR"
<> help "The path where to look for the sources"
)
getConfig :: IO Config
getConfig = execParser $
info
(helper <*> configParser)
(fullDesc <> header ("SJW v" ++ showVersion SJW.version))
runCompiler :: Config -> IO (Text, [String])
runCompiler (Config {includes, mainIs, target}) =
flip (evalRWST Compiler.main) Map.empty $ Context {
codePaths = CodePath (target : includes)
, mainModule = read mainIs
}
main :: IO ()
main = do
config@(Config {outputFile}) <- getConfig
(sourceCode, logs) <- runCompiler config
mapM_ (hPutStrLn stderr) logs
output outputFile . Text.unpack $ sourceCode
where
output "-" = putStr
output fileName = writeFile fileName