Added the first attempt at getting Tock to do an all-in-one compile, from occam/Rain all the way through into an executable binary

This commit is contained in:
Neil Brown 2007-10-08 21:18:07 +00:00
parent 7cee4e46fc
commit c17cf0ce38
3 changed files with 75 additions and 25 deletions

68
Main.hs
View File

@ -24,9 +24,12 @@ import Control.Monad.State
import List
import System
import System.Console.GetOpt
import System.Exit
import System.IO
import System.Process
import AnalyseAsm
import CompilerCommands
import CompState
import Errors
import GenerateC
@ -53,7 +56,7 @@ type OptFunc = CompState -> IO CompState
options :: [OptDescr OptFunc]
options =
[ Option [] ["mode"] (ReqArg optMode "MODE") "select mode (options: parse, compile, post-c)"
[ Option [] ["mode"] (ReqArg optMode "MODE") "select mode (options: parse, compile, post-c, full)"
, Option [] ["backend"] (ReqArg optBackend "BACKEND") "code-generating backend (options: c, cppcsp)"
, Option [] ["frontend"] (ReqArg optFrontend "FRONTEND") "language frontend (options: occam, rain)"
, Option ['v'] ["verbose"] (NoArg $ optVerbose) "be more verbose (use multiple times for more detail)"
@ -66,6 +69,7 @@ optMode s ps
"parse" -> return ModeParse
"compile" -> return ModeCompile
"post-c" -> return ModePostC
"full" -> return ModeFull
_ -> dieIO (Nothing, "Unknown mode: " ++ s)
return $ ps { csMode = mode }
@ -111,33 +115,65 @@ main = do
let operation
= case csMode initState of
ModeParse -> compile fn
ModeCompile -> compile fn
ModePostC -> postCAnalyse fn
ModeParse -> useOutputOptions (compile ModeParse fn)
ModeCompile -> useOutputOptions (compile ModeCompile fn)
ModePostC -> useOutputOptions (postCAnalyse fn)
-- TODO Delete the temporary files when we're done
-- TODO make sure the temporary files are deleted if, for some reason, the C/C++ compiler should fail:
-- First, compile the file into C/C++:
ModeFull -> do (tempPath,tempHandle) <- liftIO $ openTempFile "." "tock-temp"
compile ModeCompile fn tempHandle
liftIO $ hClose tempHandle
optsPS <- get
destBin <- case csOutputFile optsPS of
"-" -> error "Must specify an output file when using full-compile mode"
file -> return file
-- Then, compile the C/C++:
case csBackend optsPS of
BackendC -> do exec $ cCommand tempPath (tempPath ++ ".o")
exec $ cAsmCommand tempPath (tempPath ++ ".s")
(tempPathPost, tempHandlePost) <- liftIO $ openTempFile "." "tock-temp-post"
postCAnalyse (tempPath ++ ".s") tempHandlePost
liftIO $ hClose tempHandlePost
exec $ krocLinkCommand tempPath tempPathPost destBin
BackendCPPCSP -> exec $ cxxCommand tempPath destBin
-- Run the compiler.
v <- evalStateT (runErrorT operation) initState
case v of
Left e -> dieIO e
Right r -> return ()
where
exec :: String -> PassM ()
exec cmd = do progress $ "Executing command: " ++ cmd
p <- liftIO $ runCommand cmd
exitCode <- liftIO $ waitForProcess p
case exitCode of
ExitSuccess -> return ()
ExitFailure n -> error $ "Command \"" ++ cmd ++ "\" failed, exiting with code: " ++ show n
-- | Write the output to the file the user wanted.
writeOutput :: String -> PassM ()
writeOutput output
-- | Picks out the handle from the options and passes it to the function:
useOutputOptions :: (Handle -> PassM ()) -> PassM ()
useOutputOptions func
= do optsPS <- get
case csOutputFile optsPS of
"-" -> liftIO $ putStr output
"-" -> func stdout
file ->
do progress $ "Writing output file " ++ file
f <- liftIO $ openFile file WriteMode
liftIO $ hPutStr f output
func f
liftIO $ hClose f
-- | Compile a file.
-- This is written in the PassM monad -- as are most of the things it calls --
-- because then it's very easy to pass the state around.
compile :: String -> PassM ()
compile fn
compile :: CompMode -> String -> Handle -> PassM ()
compile mode fn outHandle
= do optsPS <- get
debug "{{{ Parse"
@ -151,7 +187,7 @@ compile fn
showWarnings
output <-
case csMode optsPS of
case mode of
ModeParse -> return $ show ast1
ModeCompile ->
do progress "Passes:"
@ -179,13 +215,13 @@ compile fn
showWarnings
writeOutput output
liftIO $ hPutStr outHandle output
progress "Done"
-- | Analyse an assembly file.
postCAnalyse :: String -> PassM ()
postCAnalyse fn
postCAnalyse :: String -> Handle -> PassM ()
postCAnalyse fn outHandle
= do asm <- liftIO $ readFile fn
progress "Analysing assembly"
@ -193,5 +229,5 @@ postCAnalyse fn
showWarnings
writeOutput output
liftIO $ hPutStr outHandle output

View File

@ -1,8 +1,3 @@
AM_CFLAGS = @gnu89_inline@ -O2 -g -Wall `kroc --cflags` `kroc --ccincpath`
AM_CXXFLAGS = -O2 -g -Wall -ggdb3 -I.
GHC_OPTS = \
-fglasgow-exts \
-fallow-undecidable-instances \
@ -11,22 +6,41 @@ GHC_OPTS = \
-fwarn-type-defaults \
-icommon -itransformations -ifrontends -ibackends
tock:
tock: $(BUILT_SOURCES) $(tock_SOURCES)
@MKDIR_P@ obj
ghc $(GHC_OPTS) -o tock --make Main -odir obj -hidir obj
#The order of the -main-is and --make flags is important here:
tocktest:
tocktest: $(BUILT_SOURCES) $(tocktest_SOURCES)
@MKDIR_P@ obj
ghc $(GHC_OPTS) -o tocktest -main-is TestMain --make TestMain -odir obj -hidir obj
TOCK_CFLAGS = @gnu89_inline@ -O2 -g -Wall `kroc --cflags` `kroc --ccincpath`
TOCK_CXXFLAGS = -O2 -g -Wall -ggdb3 -I.
CompilerCommands.hs: Makefile
echo -e 'module CompilerCommands where\n' > CompilerCommands.hs
echo -e '--This file is auto-generated by Makefile.am\n' >> CompilerCommands.hs
echo -e 'cCommand :: String -> String -> String\n' >> CompilerCommands.hs
echo -e 'cCommand inp out = "$(CC) $(TOCK_CFLAGS) -x c -c -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs
echo -e 'cAsmCommand :: String -> String -> String\n' >> CompilerCommands.hs
echo -e 'cAsmCommand inp out = "$(CC) $(TOCK_CFLAGS) -x c -S -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs
echo -e 'krocLinkCommand :: String -> String -> String -> String\n'
echo -e 'krocLinkCommand fileA fileB out = "kroc -o " ++ out ++ " kroc-wrapper.occ " ++ fileA ++ " " ++ fileB ++ " kroc-wrapper-c.o -lcif"\n' >> CompilerCommands.hs
echo -e 'cxxCommand :: String -> String -> String\n' >> CompilerCommands.hs
echo -e 'cxxCommand inp out = "$(CXX) $(TOCK_CXXFLAGS) -x c++ -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs
frontends/LexOccam.hs: frontends/LexOccam.x
alex frontends/LexOccam.x
frontends/LexRain.hs: frontends/LexRain.x
alex frontends/LexRain.x
BUILT_SOURCES = frontends/LexOccam.hs frontends/LexRain.hs
BUILT_SOURCES = frontends/LexOccam.hs frontends/LexRain.hs CompilerCommands.hs
CLEANFILES = $(BUILT_SOURCES)
tock_SOURCES = transformations/SimplifyExprs.hs transformations/SimplifyTypes.hs

View File

@ -32,7 +32,7 @@ import Errors
import Metadata
-- | Modes that Tock can run in.
data CompMode = ModeParse | ModeCompile | ModePostC
data CompMode = ModeParse | ModeCompile | ModePostC | ModeFull
deriving (Show, Data, Typeable, Eq)
-- | Backends that Tock can use.