[new CompNode based compilation driver that works on recursive decent.
John Meacham <john@repetae.net>**20080213035225] hunk ./FrontEnd/FrontEnd.hs 34
-    (res,_,_) <- findModule fs ifunc (doModules func)
-    return res
+    compileModules fs ifunc (doModules func)
hunk ./Ho/Build.hs 4
-    findModule,
+    compileModules,
hunk ./Ho/Build.hs 121
-    | ModLibrary String
+    | ModLibrary String HoHash
hunk ./Ho/Build.hs 189
+            fn <- shortenPath fn
hunk ./Ho/Build.hs 228
-    = CompLibrary String
-    | CompHo      HoHeader Ho
+    = CompHo   (Maybe String)  HoHeader Ho
hunk ./Ho/Build.hs 230
+    | CompPhony
+    | CompCollected CollectedHo CompUnit
+
+class ProvidesModules a where
+    providesModules :: a -> [Module]
+    providesModules _ = []
+
+instance ProvidesModules HoHeader where
+    providesModules hoh = fsts $ hohDepends hoh
+
+instance ProvidesModules CompUnit where
+    providesModules (CompHo _ hoh _)   = providesModules hoh
+    providesModules (CompSources ss) = concatMap providesModules ss
+    providesModules CompPhony        = []
+    providesModules (CompCollected _ cu) = providesModules cu
+
+instance ProvidesModules SourceCode where
+    providesModules SourceParsed { sourceModule = mod } = [hsModuleName mod]
+    providesModules SourceRaw    { sourceModName = n } = [n]
+
hunk ./Ho/Build.hs 254
-    f (CompLibrary s) = s
-    f (CompHo _ _) = "ho"
+    f (CompHo (Just s) _ _) = s
+    f (CompHo _ _ _) = "ho"
hunk ./Ho/Build.hs 259
+-- | this walks the loaded modules and ho files, discarding out of
+-- date ho files and organizing modules into their binding groups.
+-- the result is an acyclic graph where the nodes are ho files, sets
+-- of mutually recursive modules, or libraries.
+-- there is a strict ordering of
+-- source >= ho >= library
+-- in terms of dependencies
+
hunk ./Ho/Build.hs 284
-            rr <- Map.lookup m mods  >>= readIORef
+            rr <- readIORef $ maybe (error $ "toCompUnitGraph: " ++ show m) id (Map.lookup m mods)
hunk ./Ho/Build.hs 307
+                    fp <- shortenPath fp
hunk ./Ho/Build.hs 311
-                        modifyIORef cug_ref ((h,(hohModDepends hoh,CompHo hoh ho)):)
+                        modifyIORef cug_ref ((h,(hohModDepends hoh,CompHo Nothing hoh ho)):)
hunk ./Ho/Build.hs 318
+        cdep (_,hash) | hash == MD5.emptyHash = return ()
hunk ./Ho/Build.hs 329
-findModule :: [Either Module String]                                -- ^ Either a module or filename to find
-              -> (CollectedHo -> Ho -> IO CollectedHo)              -- ^ Process initial ho loaded from file
-              -> (CollectedHo -> [HsModule] -> IO (CollectedHo,Ho)) -- ^ Process set of mutually recursive modules to produce final Ho
-              -> IO (CollectedHo,[(Module,MD5.Hash)],Ho)            -- ^ (Final accumulated ho,just the ho read to satisfy this command)
-findModule need ifunc func  = do
-    done_ref <- newIORef mempty
+compileModules :: [Either Module String]                             -- ^ Either a module or filename to find
+               -> (CollectedHo -> Ho -> IO CollectedHo)              -- ^ Process initial ho loaded from file
+               -> (CollectedHo -> [HsModule] -> IO (CollectedHo,Ho)) -- ^ Process set of mutually recursive modules to produce final Ho
+               -> IO CollectedHo                                     -- ^ Final accumulated ho
+
+compileModules need ifunc func = do
+    (cho,_,_) <- findModule need ifunc func
+    return cho
hunk ./Ho/Build.hs 338
-    unless (null $ optHls options) $ putVerboseLn $ "Loading libraries:" <+> show (optHls options)
+
+
+
+-- this takes a list of modules or files to load, and produces a compunit graph
+loadModules :: [String]                 -- ^ libraries to load
+            -> [Either Module String]   -- ^ a list of modules or filenames
+            -> IO ([Module],CompUnitGraph)         -- ^ the resulting acyclic graph of compilation units
+loadModules libs need = do
+    done_ref <- newIORef mempty
+    unless (null libs) $ putVerboseLn $ "Loading libraries:" <+> show libs
hunk ./Ho/Build.hs 351
-            --putErrLn $ "Error loading library file: " ++ fn
hunk ./Ho/Build.hs 354
-        modifyIORef done_ref (modEncountered_u $ Map.union (Map.fromList [ (m,ModLibrary n') | (m,_) <- hohDepends hoh]))
+        modifyIORef done_ref (modEncountered_u $ Map.union (Map.fromList [ (m,ModLibrary n' (hohHash hoh)) | (m,_) <- hohDepends hoh]))
hunk ./Ho/Build.hs 359
+    done <- readIORef done_ref
+    let needed = (ms1 ++ lefts need)
+    cug <- toCompUnitGraph done needed
+    return (needed,cug)
hunk ./Ho/Build.hs 364
-    let roots = ms1 ++ lefts need
hunk ./Ho/Build.hs 365
-    done <- readIORef done_ref
-    cug <- toCompUnitGraph done roots
---    mapM_ (putStrLn . showCUnit) cug
+data CompNode = CompNode HoHash [CompNode] (IORef CompUnit)
+
+processCug :: CompUnitGraph -> IO [CompNode]
+processCug cug = mdo
+    let mmap = Map.fromList xs
+        lup x = maybe (error $ "processCug: " ++ show x) id (Map.lookup x mmap)
+        f (h,(ds,cu)) = do
+            cur <- newIORef cu
+            return $ (h,CompNode h (map lup ds) cur)
+    xs <- mapM f cug
+    return $ snds xs
+
+mkPhonyCompNode :: [Module] -> [CompNode] -> IO CompNode
+mkPhonyCompNode need cs = do
+    xs <- forM cs $ \cn@(CompNode _ _ cu) -> readIORef cu >>= \u -> return $ if null $ providesModules u `intersect` need then [] else [cn]
+    let hash = MD5.md5String $ show [ h | CompNode h _ _ <- concat xs ]
+    CompNode hash (concat xs) `fmap` newIORef CompPhony
+
+findModule :: [Either Module String]                                -- ^ Either a module or filename to find
+              -> (CollectedHo -> Ho -> IO CollectedHo)              -- ^ Process initial ho loaded from file
+              -> (CollectedHo -> [HsModule] -> IO (CollectedHo,Ho)) -- ^ Process set of mutually recursive modules to produce final Ho
+              -> IO (CollectedHo,[(Module,MD5.Hash)],Ho)            -- ^ (Final accumulated ho,just the ho read to satisfy this command)
+findModule need ifunc func  = do
+    (needed,cug) <- loadModules (optHls options) need
+    cnodes <- processCug cug
+    rnode <- mkPhonyCompNode needed cnodes
+
+    let f (CompNode hh deps ref) = readIORef ref >>= \cn -> case cn of
+            CompCollected ch _ -> return ch
+            CompPhony -> do
+                xs <- mconcat `fmap` mapM f deps
+                writeIORef ref (CompCollected xs CompPhony)
+                return xs
+            CompHo _ _ ho -> do
+                cho <- mconcat `fmap` mapM f deps
+                cho <- ifunc cho ho
+                writeIORef ref (CompCollected cho cn)
+                return cho
+            CompSources sc -> do
+                let hdep = [ h | CompNode h _ _ <- deps]
+                cho <- mconcat `fmap` mapM f deps
+                modules <- forM sc $ \x -> case x of
+                    SourceParsed { sourceHash = h,sourceModule = mod } -> return (h,mod)
+                    SourceRaw { sourceHash = h,sourceLBS = lbs, sourceFP = fp } -> do
+                        fp <- shortenPath fp
+                        mod <- parseHsSource fp lbs
+                        return (h,mod)
+                (cho',newHo) <- func cho (snds modules)
+                let hoh = HoHeader {
+                                     hohDepends    = [ (hsModuleName mod,h) | (h,mod) <- modules],
+                                     hohModDepends = hdep,
+                                     hohHash       = hh,
+                                     hohMetaInfo   = []
+                                   }
+                    idep = HoIDeps $ Map.fromList [ (h,(hsModuleName mod,hsModuleRequires mod)) | (h,mod) <- modules]
+                recordHoFile newHo idep (map sourceHoName sc) hoh
+                writeIORef ref (CompCollected cho' cn)
+                return cho'
+
+
+    cho <- f rnode
+    return (cho,undefined,undefined)
+
+{-
+
hunk ./Ho/Build.hs 436
-                SourceRaw { sourceHash = h,sourceLBS = lbs, sourceFP = fp } -> parseHsSource fp lbs >>= return . (,) h
+                SourceRaw { sourceHash = h,sourceLBS = lbs, sourceFP = fp } -> do
+                    fp <- shortenPath fp
+                    mod <- parseHsSource fp lbs
+                    return (h,mod)
hunk ./Ho/Build.hs 453
-    let readHo = mconcat [ ho | [(_,(_,CompHo _ ho))] <- sccm ]
+    let readHo = mconcat [ ho | [(_,(_,CompHo _ _ ho))] <- sccm ]
hunk ./Ho/Build.hs 457
+-}
hunk ./Ho/Build.hs 618
+vindent xs = vcat (map ("    " ++) xs)
+
hunk ./Ho/Build.hs 627
-    when (not $ Map.null (hoIDeps idep)) $ putStrLn $ "IDeps:\n" <>  vcat (map pprint . Map.toList $ hoIDeps idep)
-    when (not $ Prelude.null (hohDepends hoh)) $ putStrLn $ "Dependencies:\n" <>  vcat (map pprint . sortUnder fst $ hohDepends hoh)
-    when (not $ Prelude.null (hohModDepends hoh)) $ putStrLn $ "ModDependencies:\n" <>  vcat (map pprint $ hohModDepends hoh)
hunk ./Ho/Build.hs 628
-    putStrLn $ "MetaInfo:\n" <> vcat (sort [text (' ':' ':fromAtom k) <> char ':' <+> show v | (k,v) <- hohMetaInfo hoh])
+    when (not $ Map.null (hoIDeps idep)) $ putStrLn $ "IDeps:\n" <>  vindent (map pprint . Map.toList $ hoIDeps idep)
+    when (not $ Prelude.null (hohDepends hoh)) $ putStrLn $ "Dependencies:\n" <>  vindent (map pprint . sortUnder fst $ hohDepends hoh)
+    when (not $ Prelude.null (hohModDepends hoh)) $ putStrLn $ "ModDependencies:\n" <>  vindent (map pprint $ hohModDepends hoh)
+    when (not $ Prelude.null (hohMetaInfo hoh)) $ putStrLn $ "MetaInfo:\n" <> vindent (sort [text (' ':' ':fromAtom k) <> char ':' <+> show v | (k,v) <- hohMetaInfo hoh])
hunk ./Ho/Type.hs 7
-import DataConstructors(DataTable)
+import DataConstructors(DataTable,dataTablePrims)
hunk ./Ho/Type.hs 47
-collectedHo = CollectedHo { choFiles = mempty, choExternalNames = mempty, choHo = mempty, choVarMap = mempty }
+collectedHo = CollectedHo {
+    choFiles = mempty,
+    choExternalNames = mempty,
+    choHo = mempty { hoBuild = mempty { hoDataTable = dataTablePrims } },
+    choVarMap = mempty
+    }