rail-compiler-editor-0.3.0.0: src/RailCompiler-command/Main.hs
{- |
Module : Main.hs
Description : .
Maintainer : (c) Christopher Pockrandt, Nicolas Lehmann, Tobias Kranz
License : MIT
Stability : stable
Entrypoint of the rail2llvm-compiler. Contains main-function.
See also:
--https://www.haskell.org/ghc/docs/7.8.2/html/libraries/base-4.7.0.0/System-Console-GetOpt.html
--http://leiffrenzel.de/papers/commandline-options-in-haskell.html (Outdated!)
-}
module Main( main ) where
-- imports --
import System.Environment
import System.Exit
import System.Console.GetOpt
import Data.Maybe( fromMaybe )
import InterfaceDT as IDT
import qualified Preprocessor as PreProc
import qualified Lexer
import qualified SyntacticalAnalysis as SynAna
import qualified SemanticalAnalysis as SemAna
import qualified IntermediateCode as InterCode
import qualified Backend
-- defining the option settings for the main-function
data Options = Options {
optInput :: IO String,
optOutput :: String -> IO (),
optASTOutput :: String -> IO (),
compile :: Bool,
impAST :: Bool,
expAST :: Bool
}
-- default Options
defaultOptions :: Options
defaultOptions = Options {
optInput = getContents,
optOutput = putStr,
optASTOutput = putStr,
compile = False,
impAST = False,
expAST = False
}
-- usageInfo
options :: [OptDescr (Options -> IO Options)]
options = [
--Option ['V'] ["version"] (NoArg showVersion) "show version number",
Option "h" ["help" ] (NoArg showHelp ) "display Help Text",
Option "i" ["input" ] (ReqArg setInput "FILE" ) "input file (don't set to use stdin')",
Option "o" ["output" ] (ReqArg setOutput "FILE" ) "output file (don't set to use stdout')",
Option "c" ["compile" ] (NoArg setCompile ) "compile 'rail' to 'llvm'",
Option [ ] ["exportAST"] (OptArg setExpAST "FILE" ) "export frontend AST (don't offer a File to use stdout) \n(dont set with --importAST)",
Option [ ] ["importAST"] (NoArg setImpAST ) "import frontend AST and compile to llvm\nautosets -c \n(set input via -i; (dont set with --exportAST)\n\nset -c with --exportAST and get both: the AST and the llvm code"
]
-- output for the help-function
showHelp _ = do
putStrLn "rail2llvm--haskell-compiler (development version)"
putStr "https://github.com/SWP-Ubau-SoSe2014-Haskell/SWPSoSe14\n\n"
putStr $ usageInfo "Usage: main [OPTION...]" options
exitSuccess
-- options-getter for optional output for exprotAST
getOut (Just arg) = writeFile arg
getOut Nothing = putStr
-- options-setters
setInput arg opt = return opt { optInput = readFile arg }
setOutput arg opt = return opt { optOutput = writeFile arg }
setExpAST arg opt = return opt { optASTOutput = getOut arg, expAST = True}
setImpAST opt = return opt { impAST = True, compile = True }
setCompile opt = return opt { compile = True }
-- main-function --
main = do args <- getArgs
let (actions,nonOpts,msgs) = getOpt RequireOrder options args
-- intercept errors
if msgs /= []
then error $ concat msgs ++ usageInfo "Usage: main [OPTION...]" options
-- unrecognized arguments error
else if nonOpts /= []
then error $ "unrecognized arguments: " ++ unwords nonOpts ++ "\nUsage: For basic information, try the `--help' option."
else do opts <- foldl (>>=) (return defaultOptions) actions
-- option aliases
let Options { optInput = input, optOutput = output, optASTOutput = outputAST, compile = cmpl, impAST = imp, expAST = exp} = opts
inputWithoutIO <- input
-- importAST and exportAST can't be set together (error)
if imp && exp
then do error "No export of the imported AST (Usage: For basic information, try the `--help' option.)'"
exitSuccess
-- compile a file
else if cmpl
then do let transform (IBO x) = x
-- compile an imported AST to a LLVM-file
if imp
then transform (Backend.process . InterCode.process . SemAna.process . SynAna.process . Lexer.toAST $ inputWithoutIO) >>= output
-- compile a RAIL-file to an AST as an export-file
else if exp
then do outputAST (Lexer.fromAST . Lexer.process . PreProc.process $ IIP inputWithoutIO)
transform (Backend.process . InterCode.process . SemAna.process . SynAna.process . Lexer.process . PreProc.process $ IIP inputWithoutIO) >>= output
-- compile a RAIL-file to a LLVM-file
else transform (Backend.process . InterCode.process . SemAna.process . SynAna.process . Lexer.process . PreProc.process $ IIP inputWithoutIO) >>= output
-- exportAST (without compiling it to llvm)
else if exp
then outputAST (Lexer.fromAST . Lexer.process . PreProc.process $ IIP inputWithoutIO)
-- missing argument error
else error "Error. Set atleast -c or --importAST or --exportAST."