module UHC.Light.Compiler.EHC.BuildFunction.Run
( module UHC.Light.Compiler.EHC.BuildFunction
, bcall
, bderef )
where
import UHC.Light.Compiler.EHC.BuildFunction
import UHC.Light.Compiler.EHC.Common
import UHC.Light.Compiler.EHC.CompileRun
import UHC.Light.Compiler.EHC.CompileUnit
import UHC.Light.Compiler.EHC.FileSuffMp
import UHC.Light.Compiler.EHC.ASTHandler
import UHC.Light.Compiler.EHC.ASTHandler.Instances
import UHC.Util.Lens
import Data.Typeable
import qualified Data.Map as Map
import Control.Monad.State
import System.Directory
import UHC.Light.Compiler.Base.PackageDatabase
bcall :: forall res m . (Typeable res) => EHCCompileRunner m => BFun' res -> EHCompilePhaseT m res
bcall bfun = do
bcache <- getl $ st ^* bstateCache
mbCachedRes <- lkup bfun bcache
case mbCachedRes of
Just res -> return res
_ -> do
start
res <- case bfun of
EcuOfName modNm -> do
bcall $ EcuOfNameAndPath Nothing (modNm, Nothing)
EHCOptsOf modNm -> do
fmap (panicJust "EHCOptsOf") $ bderef (BRef_EHCOpts modNm)
EcuOfNameAndPath mbPrev (modNm,mbFp) -> do
opts <- bcall $ EHCOptsOf modNm
let isTopModule = isJust mbFp
searchPath = ehcOptImportFileLocPath opts
adaptFileSuffMp = if isTopModule then (fileSuffMpHsNoSuff ++) else id
fileSuffMpHs <- fmap (map tup123to12 . adaptFileSuffMp) $ getl $ crStateInfo ^* crsiFileSuffMp
let searchPath' = prevSearchInfoAdaptedSearchPath mbPrev searchPath
fpsFound <- cpFindFilesForFPathInLocations (fileLocSearch opts) tup123to1 False fileSuffMpHs searchPath' (Just modNm) mbFp
when (ehcOptVerbosity opts >= VerboseDebug) $ liftIO $ do
putStrLn $ show modNm ++ ": " ++ show (fmap fpathToStr mbFp) ++ ": " ++ show (map fpathToStr fpsFound)
putStrLn $ "searchPath: " ++ show searchPath'
when isTopModule
(cpUpdCU modNm (ecuSetIsTopMod True))
bmemo $ BRef_ECU modNm
fmap (panicJust "EcuOfNameAndPath") $ cpMbCU modNm
FPathSearchForFile suff fn -> do
let fp = mkTopLevelFPath suff fn
modNm = mkHNm $ fpathBase fp
breturn (modNm, fp)
ASTFromFile mf@(modNm,_) asttype skey tkey -> case asthandlerLookup asttype of
Just (hdlr :: ASTHandler' res) -> case astsuffixLookup skey $ _asthdlrSuffixRel hdlr of
Just suffinfo -> do
ecu <- bcall $ EcuOfNameAndPath Nothing mf
let ref = BRef_AST modNm asttype skey tkey
return Nothing
_ -> return Nothing
_ -> return Nothing
ModfTimeOfFile modNm asttype skey tkey -> case (asthandlerLookup' asttype $ \hdlr -> do
suffinfo <- astsuffixLookup skey $ _asthdlrSuffixRel hdlr
lens <- Map.lookup tkey $ _astsuffinfoModfTimeMp suffinfo
return (_astsuffinfoSuff suffinfo, lens)
) of
Just (suff, lens) -> do
cr <- get
let (ecu,_,opts,fp) = crBaseInfo modNm cr
tm opts ecu ((lens ^=) . Just) (fpathSetSuff suff fp)
_ -> return Nothing
where
tm opts ecu store fp = do
let n = fpathToStr fp
nExists <- liftIO $ doesFileExist n
when (ehcOptVerbosity opts >= VerboseDebug) $ liftIO $ putStrLn ("meta info of: " ++ show (ecuModNm ecu) ++ ", file: " ++ n ++ ", exists: " ++ show nExists)
if nExists
then do
t <- liftIO $ fpathGetModificationTime fp
when (ehcOptVerbosity opts >= VerboseDebug) $ liftIO $ putStrLn ("time stamp of: " ++ show (ecuModNm ecu) ++ ", time: " ++ show t)
cpUpdCU modNm $ store t
return $ Just t
else return Nothing
_ -> panic $ "BuildFunction.Run.bcall: not implemented: " ++ show bfun
end
return res
where
st = crStateInfo ^* crsiBState
start = st ^* bstateCallStack =$: (BFun bfun :)
end = st ^* bstateCallStack =$: tail
bmemo :: Typeable f => f res -> EHCompilePhaseT m ()
bmemo res = do
(BFun bfun : _) <- getl $ st ^* bstateCallStack
case cast bfun of
Just bfun -> st ^* bstateCache =$: bcacheInsert bfun res
_ -> panic $ "BuildFunction.Run.bcall.bmemo: " ++ show bfun
breturn :: res -> EHCompilePhaseT m res
breturn res = do
bmemo (Identity res)
return res
lkup :: BFun' res -> BCache -> EHCompilePhaseT m (Maybe res)
lkup bfun bcache =
case bcacheLookup bfun bcache of
Just (res :: Identity res) -> return $ Just $ runIdentity res
_ -> case bcacheLookup bfun bcache of
Just (ref :: BRef res) -> bderef ref
_ -> return Nothing
bderef' :: forall res m . (Typeable res, EHCCompileRunner m) => BRef res -> EHCompilePhaseT m (Maybe res, Maybe (res -> EHCompilePhaseT m ()))
bderef' bref = do
cr <- get
case bref of
BRef_ECU modNm -> return (crMbCU modNm cr, Just $ \ecu -> cpUpdCU modNm (const ecu))
BRef_EHCOpts modNm -> return (Just choose, Nothing)
where opts = cr ^. crStateInfo ^. crsiOpts
choose = maybe opts id $ crMbCU modNm cr >>= ecuMbOpts
BRef_AST modNm asttype skey tkey -> case asthandlerLookup asttype of
Just (hdlr :: ASTHandler' res) -> case astsuffixLookup skey $ _asthdlrSuffixRel hdlr of
Just suffinfo -> case Map.lookup tkey $ _astsuffinfoASTLensMp suffinfo of
Just l -> do
ecu <- bcall $ EcuOfName modNm
return (ecu ^. l, Just $ \ast -> cpUpdCU modNm $ l ^= Just ast)
_ -> return (Nothing, Nothing)
_ -> return (Nothing, Nothing)
_ -> return (Nothing, Nothing)
bderef :: forall res m . (Typeable res, EHCCompileRunner m) => BRef res -> EHCompilePhaseT m (Maybe res)
bderef bref = fmap fst $ bderef' bref