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 List
import System import System
import System.Console.GetOpt import System.Console.GetOpt
import System.Exit
import System.IO import System.IO
import System.Process
import AnalyseAsm import AnalyseAsm
import CompilerCommands
import CompState import CompState
import Errors import Errors
import GenerateC import GenerateC
@ -53,7 +56,7 @@ type OptFunc = CompState -> IO CompState
options :: [OptDescr OptFunc] options :: [OptDescr OptFunc]
options = 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 [] ["backend"] (ReqArg optBackend "BACKEND") "code-generating backend (options: c, cppcsp)"
, Option [] ["frontend"] (ReqArg optFrontend "FRONTEND") "language frontend (options: occam, rain)" , Option [] ["frontend"] (ReqArg optFrontend "FRONTEND") "language frontend (options: occam, rain)"
, Option ['v'] ["verbose"] (NoArg $ optVerbose) "be more verbose (use multiple times for more detail)" , Option ['v'] ["verbose"] (NoArg $ optVerbose) "be more verbose (use multiple times for more detail)"
@ -66,6 +69,7 @@ optMode s ps
"parse" -> return ModeParse "parse" -> return ModeParse
"compile" -> return ModeCompile "compile" -> return ModeCompile
"post-c" -> return ModePostC "post-c" -> return ModePostC
"full" -> return ModeFull
_ -> dieIO (Nothing, "Unknown mode: " ++ s) _ -> dieIO (Nothing, "Unknown mode: " ++ s)
return $ ps { csMode = mode } return $ ps { csMode = mode }
@ -111,9 +115,31 @@ main = do
let operation let operation
= case csMode initState of = case csMode initState of
ModeParse -> compile fn ModeParse -> useOutputOptions (compile ModeParse fn)
ModeCompile -> compile fn ModeCompile -> useOutputOptions (compile ModeCompile fn)
ModePostC -> postCAnalyse 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. -- Run the compiler.
v <- evalStateT (runErrorT operation) initState v <- evalStateT (runErrorT operation) initState
@ -121,23 +147,33 @@ main = do
Left e -> dieIO e Left e -> dieIO e
Right r -> return () Right r -> return ()
-- | Write the output to the file the user wanted. where
writeOutput :: String -> PassM () exec :: String -> PassM ()
writeOutput output 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
-- | Picks out the handle from the options and passes it to the function:
useOutputOptions :: (Handle -> PassM ()) -> PassM ()
useOutputOptions func
= do optsPS <- get = do optsPS <- get
case csOutputFile optsPS of case csOutputFile optsPS of
"-" -> liftIO $ putStr output "-" -> func stdout
file -> file ->
do progress $ "Writing output file " ++ file do progress $ "Writing output file " ++ file
f <- liftIO $ openFile file WriteMode f <- liftIO $ openFile file WriteMode
liftIO $ hPutStr f output func f
liftIO $ hClose f liftIO $ hClose f
-- | Compile a file. -- | Compile a file.
-- This is written in the PassM monad -- as are most of the things it calls -- -- 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. -- because then it's very easy to pass the state around.
compile :: String -> PassM () compile :: CompMode -> String -> Handle -> PassM ()
compile fn compile mode fn outHandle
= do optsPS <- get = do optsPS <- get
debug "{{{ Parse" debug "{{{ Parse"
@ -151,7 +187,7 @@ compile fn
showWarnings showWarnings
output <- output <-
case csMode optsPS of case mode of
ModeParse -> return $ show ast1 ModeParse -> return $ show ast1
ModeCompile -> ModeCompile ->
do progress "Passes:" do progress "Passes:"
@ -179,13 +215,13 @@ compile fn
showWarnings showWarnings
writeOutput output liftIO $ hPutStr outHandle output
progress "Done" progress "Done"
-- | Analyse an assembly file. -- | Analyse an assembly file.
postCAnalyse :: String -> PassM () postCAnalyse :: String -> Handle -> PassM ()
postCAnalyse fn postCAnalyse fn outHandle
= do asm <- liftIO $ readFile fn = do asm <- liftIO $ readFile fn
progress "Analysing assembly" progress "Analysing assembly"
@ -193,5 +229,5 @@ postCAnalyse fn
showWarnings 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 = \ GHC_OPTS = \
-fglasgow-exts \ -fglasgow-exts \
-fallow-undecidable-instances \ -fallow-undecidable-instances \
@ -11,22 +6,41 @@ GHC_OPTS = \
-fwarn-type-defaults \ -fwarn-type-defaults \
-icommon -itransformations -ifrontends -ibackends -icommon -itransformations -ifrontends -ibackends
tock: tock: $(BUILT_SOURCES) $(tock_SOURCES)
@MKDIR_P@ obj @MKDIR_P@ obj
ghc $(GHC_OPTS) -o tock --make Main -odir obj -hidir obj ghc $(GHC_OPTS) -o tock --make Main -odir obj -hidir obj
#The order of the -main-is and --make flags is important here: #The order of the -main-is and --make flags is important here:
tocktest: tocktest: $(BUILT_SOURCES) $(tocktest_SOURCES)
@MKDIR_P@ obj @MKDIR_P@ obj
ghc $(GHC_OPTS) -o tocktest -main-is TestMain --make TestMain -odir obj -hidir 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 frontends/LexOccam.hs: frontends/LexOccam.x
alex frontends/LexOccam.x alex frontends/LexOccam.x
frontends/LexRain.hs: frontends/LexRain.x frontends/LexRain.hs: frontends/LexRain.x
alex 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) CLEANFILES = $(BUILT_SOURCES)
tock_SOURCES = transformations/SimplifyExprs.hs transformations/SimplifyTypes.hs tock_SOURCES = transformations/SimplifyExprs.hs transformations/SimplifyTypes.hs

View File

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