module Core.Linker(coreLinker) where import Util.Extra import System.FilePath import Control.Monad import System.Directory import Package import Front import Yhc.Core import Flags ignoreModules :: [String] ignoreModules = ["PreludeBuiltin"] requireModules :: [String] requireModules = ["YHC.Internal"] coreLinker :: PackageData -> FrontData -> [FrontData] -> FilePath -> IO () coreLinker pd startFile inputs output = do cores <- mapM (loadCore . sCoreFile . fFileFlags) inputs newcores <- f (ignoreModules ++ map fModName inputs) (snub $ requireModules ++ concatMap coreImports cores) let allcores = mergeCores rootMod $ cores ++ newcores rootMod = sModuleName (fFileFlags startFile) rootCor = head $ filter ((==) rootMod . coreName) cores rootSet = map coreFuncName $ coreFuncs rootCor rootMain = rootMod ++ ";main" hasMain = rootMain `elem` rootSet putStrLn "Linking..." saveCore output $ coreReachable (["main"|hasMain] ++ rootSet) $ addPrims $ addTuple1 $ (if hasMain then addMain rootMain else id) $ allcores where f done [] = return [] f done (t:odo) | t `elem` done = f done odo | otherwise = do (_,loc) <- getModule pd True "Core linker" t let file = replaceExtension loc "ycr" b <- doesFileExist file when (not b) $ error $ "Core Linker: Failed to find file, " ++ file putStrLn $ "Loading Core for " ++ t c <- loadCore file cs <- f (t:done) (coreImports c ++ odo) return (c:cs) addPrims :: Core -> Core addPrims core = core{coreFuncs = map f coreBytecodePrims ++ coreFuncs core} where f x = CorePrim (primName x) (primArity x) (primName x) "bytecode" True [] addTuple1 :: Core -> Core addTuple1 core = core{coreDatas = tuple1 : coreDatas core} where tuple1 = CoreData "Prelude;1()" ["a"] [CoreCtor "Prelude;1()" [("a",Nothing)]] addMain :: String -> Core -> Core addMain entry core = core{coreFuncs = newfunc : coreFuncs core} where CoreFunc nam args _ = coreFunc core entry newfunc = CoreFunc "main" args (CoreApp (CoreFun entry) (map CoreVar args)) mergeCores :: String -> [Core] -> Core mergeCores modname cores = Core modname [] (concat datas) (concat funcs) where (datas,funcs) = unzip $ map (\x -> (coreDatas x, coreFuncs x)) cores