tock-mirror/fco2/Main.hs
2007-04-12 16:55:26 +00:00

78 lines
1.8 KiB
Haskell

-- | Driver for the compiler.
module Main where
import List
import System
import System.Console.GetOpt
import System.IO
import Pass
import PrettyShow
import Parse
import SimplifyExprs
import Unnest
import GenerateC
passes :: [(String, Pass)]
passes =
[ ("Simplify expressions", simplifyExprs)
, ("Flatten nested declarations", unnest)
]
data Flag = ParseOnly | Verbose
deriving (Eq, Show)
options :: [OptDescr Flag]
options =
[ Option [] ["parse-only"] (NoArg ParseOnly) "only parse input file"
, Option ['v'] ["verbose"] (NoArg Verbose) "show more detail about what's going on"
]
getOpts :: [String] -> IO ([Flag], [String])
getOpts argv =
case getOpt RequireOrder options argv of
(o,n,[] ) -> return (o,n)
(_,_,errs) -> error (concat errs ++ usageInfo header options)
where header = "Usage: fco [OPTION...] SOURCEFILE"
numberedListing :: String -> String
numberedListing s = concat $ intersperse "\n" $ [(show n) ++ ": " ++ s | (n, s) <- zip [1..] (lines s)]
main :: IO ()
main = do
argv <- getArgs
(opts, args) <- getOpts argv
let fn = case args of
[fn] -> fn
_ -> error "Must specify a single input file"
let progress = if Verbose `elem` opts then hPutStrLn stderr else (\s -> return ())
progress $ "Options: " ++ (show opts)
progress $ "Compiling " ++ fn
progress ""
progress "{{{ Preprocessor"
preprocessed <- readSource fn
progress $ numberedListing preprocessed
progress "}}}"
progress "{{{ Parser"
(ast, state) <- parseSource preprocessed fn
progress $ pshow ast
progress $ pshow state
progress "}}}"
if ParseOnly `elem` opts then
putStrLn $ show ast
else do
(ast', state') <- runPass (runPasses progress passes) ast state
progress "{{{ Generate C"
c <- generateC state' ast'
putStr c
progress "}}}"
progress "Done"