module Main (main) where import System.Console.GetOpt import System.Environment import System.IO import System.Exit import Control.Monad import Safe --import Il.Lexer --import Il.Parser --import Il.Analyzer --import Il.Typechecker import C.Analyzer import Analyzer import Prelude hiding (lex) data Action = AAdvice | ADefaultRecommend | ARecommend | ACompile | AInline deriving (Eq) instance Show Action where show AAdvice = "advice (-a)" show ADefaultRecommend = show ARecommend show ARecommend = "recommend (-r)" show ACompile = "compile (-c)" show AInline = "inline (-i)" data Options = Options { optVerbose :: Bool , optOutput :: String -> IO () , optAction :: Action } checkArgs :: Options -> Action -> IO () checkArgs (Options { optAction = ADefaultRecommend }) _ = return () checkArgs (Options { optAction = action }) oldAction | action == oldAction = return () checkArgs (Options { optAction = action }) oldAction = error $ (show action) ++ " incompatible with " ++ (show oldAction) options :: [ OptDescr (Options -> IO Options) ] options = [ Option "o" ["output"] (ReqArg (\arg opt -> writeFile arg "" >> return opt { optOutput = appendFile arg }) "file") "Output file" , Option "r" ["recommend"] (NoArg (\opt -> checkArgs opt ARecommend >> return opt { optAction = ARecommend })) "Give recommendations about the data structure in the supplied code (default)" , Option "a" ["advice"] (NoArg (\opt -> checkArgs opt AAdvice >> return opt { optAction = AAdvice })) "Give advice about the data structure in the supplied code" , Option "c" ["compile"] (NoArg (\opt -> checkArgs opt ACompile >> return opt { optAction = ACompile })) "Compile the code with recommended structure linked" , Option "i" ["inline"] (NoArg (\opt -> checkArgs opt AInline >> return opt { optAction = AInline })) "Inline the code implementing the recommended structure in the supplied code" , Option "v" ["verbose"] (NoArg (\opt -> return opt { optVerbose = True })) "Enable verbose messages" , Option "h" ["help"] (NoArg (\_ -> do prg <- getProgName hPutStrLn stderr (usageInfo prg options) exitSuccess)) "Show help" ] main :: IO () main = do args <- getArgs case getOpt RequireOrder options args of (actions, files, []) -> do let startOptions = Options { optVerbose = False , optOutput = putStr , optAction = ARecommend } opts <- foldl (>>=) (return startOptions) actions let Options { optVerbose = verbose , optOutput = output , optAction = action } = opts -- contents <- readFile (head files) --FIXME generalize with all files -- let ast = analyzeIl.parse.lex $ contents dsis <- analyzeC $ headNote "no input files" files   case action of AAdvice -> printAdviceFromAnalysis output dsis ADefaultRecommend -> printRecommendationFromAnalysis output dsis ARecommend -> printRecommendationFromAnalysis output dsis ACompile -> putStrLn "Not implemented yet" AInline -> putStrLn "Not implemented yet" exitSuccess (_, nonOptions, errors) -> do unless (errors == []) (putStrLn "Command line errors:") mapM_ (\s -> putStrLn ('\t' : s)) errors unless (nonOptions == []) (putStrLn "Command line non-options present:") mapM_ (\s -> putStrLn ('\t' : s)) nonOptions exitFailure