noise-0.0.1: src-cli/Main.hs
{-# LANGUAGE TupleSections #-}
import Control.Applicative
import qualified System.Environment as Env
import qualified System.Console.GetOpt as Opt
import qualified System.IO as IO
import qualified Text.Noise.Error as Error
import qualified Text.Noise.Parser as Parser
import qualified Text.Noise.Compiler as Compiler
import qualified Text.Noise.Renderer as Renderer
import qualified Text.Noise.SourceRange as SourceRange
main :: IO ()
main = do
(flags, files, errors) <- getOptions
runWithOptions flags files errors
runWithOptions :: [Flag] -> [String] -> [String] -> IO ()
runWithOptions [] files [] = do
(sourceName, source) <- case files of
[file] -> (file,) <$> readFile file
[] -> ("-",) <$> getContents
_ -> ioError (userError "multiple input files")
case Parser.parse sourceName source of
Left err -> printErr err
Right ast -> case Compiler.compile ast of
Left err -> printErr err
Right doc -> putStr (Renderer.render doc)
where printErr err = IO.hPutStrLn IO.stderr (showError err)
runWithOptions _ _ _ = putStr helpText
showError :: (Error.Error a) => a -> String
showError err = sourceName ++ ":" ++ line ++ ":" ++ column ++ ": " ++ message
where message = Error.message err
range = SourceRange.rangeInSource err
line = show (SourceRange.startLine range)
column = show (SourceRange.startColumn range)
sourceName = SourceRange.sourceName range
data Flag = Help
optionsSpec :: [Opt.OptDescr Flag]
optionsSpec =
[ Opt.Option "h" ["help"] (Opt.NoArg Help) "Print this help text."
]
getOptions :: IO ([Flag], [String], [String])
getOptions = Opt.getOpt Opt.Permute optionsSpec <$> Env.getArgs
helpText :: String
helpText = Opt.usageInfo "Usage: noise [file]" optionsSpec