module Helium.Main.CompileUtils
( module Helium.Main.CompileUtils
, Option(..)
, splitFilePath, combinePathAndFile
, when, unless
, exitWith, ExitCode(..), exitSuccess, getArgs
, module Helium.ModuleSystem.ImportEnvironment
, Module(..)
) where
import Helium.Main.Args(Option(..))
import Helium.StaticAnalysis.Messages.Messages(HasMessage)
import Helium.StaticAnalysis.Messages.HeliumMessages(sortAndShowMessages)
import Control.Monad
import Helium.Utils.Utils(splitFilePath, combinePathAndFile)
import System.Exit
import System.Environment(getArgs)
import Helium.Utils.Logger
import Helium.ModuleSystem.ImportEnvironment
import Helium.Syntax.UHA_Syntax(Module(..))
import Data.Maybe
import Lvm.Path(searchPathMaybe)
import System.FilePath (joinPath)
import System.Process(system)
type Phase err a = IO (Either [err] a)
type CompileOptions = ([Option], String, [String])
(===>) :: Phase err1 a -> (a -> Phase err2 b) -> Phase (Either err1 err2) b
p ===> f =
p >>= either (return . Left . map Left)
(f >=> return . either (Left . map Right) Right)
doPhaseWithExit :: HasMessage err => Int -> ([err] -> String) -> CompileOptions -> Phase err a -> IO a
doPhaseWithExit nrOfMsgs code (options, fullName, doneModules) phase =
do result <- phase
case result of
Left errs ->
do sendLog (code errs) fullName doneModules options
showErrorsAndExit errs nrOfMsgs
Right a ->
return a
sendLog :: String -> String -> [String] -> [Option] -> IO ()
sendLog code fullName modules =
logger code (Just (modules,fullName))
enterNewPhase :: String -> [Option] -> IO ()
enterNewPhase phase options =
when (Verbose `elem` options) $
putStrLn (phase ++ "...")
showErrorsAndExit :: HasMessage a => [a] -> Int -> IO b
showErrorsAndExit errors maximumNumber = do
let someErrors = take maximumNumber errors
showMessages someErrors
when (number > maximumNumber) $
putStrLn "(...)\n"
putStrLn ("Compilation failed with " ++ show number ++
" error" ++ (if number == 1 then "" else "s"))
exitWith (ExitFailure 1)
where
number = length errors
showMessages :: HasMessage a => [a] -> IO ()
showMessages =
putStr . sortAndShowMessages
makeCoreLib :: String -> String -> IO ()
makeCoreLib basepath name =
do
let bps = [basepath]
maybeFullName <- searchPathMaybe bps ".lvm" name
case maybeFullName of
Just _ -> return ()
Nothing -> do
maybeCoreName <- searchPathMaybe bps ".core" name
case maybeCoreName of
Just _ -> sys ("coreasm " ++ joinPath [basepath, name])
Nothing -> do
putStr
( "Cannot find "
++ name ++ ".core in \n"
++ basepath)
exitWith (ExitFailure 1)
sys :: String -> IO ()
sys s = do
_ <- system s
return ()
checkExistence :: [String] -> String -> IO ()
checkExistence path name =
do
maybeLocation <- resolve path name
when (isNothing maybeLocation) $ do
putStr
( "Cannot find "
++ name
++ ".hs (or .lvm) in search path:\n"
++ unlines (map ("\t" ++) path)
++ "Use the -P option to add paths to the search path.\n"
)
exitWith (ExitFailure 1)
resolve :: [String] -> String -> IO (Maybe String)
resolve path name =
do maybeFullName <- searchPathMaybe path ".hs" name
case maybeFullName of
Just fullName -> return (Just fullName)
Nothing -> searchPathMaybe path ".lvm" name