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:
parent
7cee4e46fc
commit
c17cf0ce38
68
Main.hs
68
Main.hs
|
@ -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
|
||||||
|
|
||||||
|
|
30
Makefile.am
30
Makefile.am
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user