module Copilot.Compile.C99
( compile
, c99DirName
, c99FileRoot
, module Copilot.Compile.C99.Params
) where
import qualified Copilot.Core as Core
import Copilot.Compile.Header.C99 (genC99Header)
import Copilot.Compile.C99.MetaTable (allocMetaTable)
import Copilot.Compile.C99.Params
import Copilot.Compile.C99.Phases (schedulePhases)
import Copilot.Compile.C99.PrePostCode (preCode, postCode)
import Language.Atom (Atom)
import qualified Language.Atom as Atom
import Data.Char (toUpper)
import Control.Monad (when, unless)
import System.Directory ( doesDirectoryExist
, createDirectory
, removeDirectoryRecursive
, renameFile
, removeFile)
c99DirName :: String
c99DirName = "copilot-c99-codegen"
c99FileRoot :: String
c99FileRoot = "copilot"
compile :: Params -> Core.Spec -> IO ()
compile params spec0 = do
b <- doesDirectoryExist dirName
when b $ do putStrLn "Directory exists. Delete? [y/N]:"
input <- getLine
if (map toUpper input == "Y")
then (removeDirectoryRecursive dirName) >> build
else putStrLn "Ok, nothing done. Terminating."
unless b build
where
build = do
createDirectory dirName
(schedule, _, _, _, _) <- Atom.compile programName atomDefaults atomProgram
when (verbose params) $ putStrLn (Atom.reportSchedule schedule)
genC99Header (prefix params) dirName spec
mv ".c"
removeFile (programName ++ ".h")
mv ext = renameFile p (dirName ++ "/" ++ p)
where p = programName ++ ext
dirName = withPrefix (prefix params) c99DirName
spec :: Core.Spec
spec = Core.makeTags spec0
programName :: String
programName = withPrefix (prefix params) c99FileRoot
atomDefaults :: Atom.Config
atomDefaults =
Atom.defaults
{ Atom.cCode = \ _ _ _ ->
(preCode params spec, postCode params spec) }
atomProgram :: Atom ()
atomProgram =
do
meta <- allocMetaTable spec
schedulePhases params meta spec