{-# LANGUAGE OverloadedStrings #-} -- This module was inspired by CBN.Trace.Graph and has a lot of code repetition. module CBN.Trace.HeapGraph (toGraphFiles) where import Control.Monad import Data.Graph (Graph) import Data.Monoid ((<>)) import qualified Data.Graph as Graph import qualified Data.Text as T import CBN.Closure import CBN.Pretty import CBN.Trace import CBN.Util.Doc.Style import qualified CBN.Util.Doc as Doc import qualified CBN.Util.Doc.Rendered as Rendered toGraphFiles :: Trace -> FilePath -> IO () toGraphFiles trace pathAndPrefix = forM_ (renderMemoryTrace trace) $ \(k,v) -> writeFile (pathAndPrefix ++ show k ++ ".dot") v renderMemoryTrace :: Trace -> [(Int,String)] renderMemoryTrace = go 0 where go n (Trace (hp, t) cont) = (n,x):xs where x = renderMemoryGraph $ toClosureGraph (hp, t) xs = case cont of TraceStep _ tr' -> go (n + 1) tr' TraceGC _ tr' -> go (n + 1) tr' _ -> [] renderMemoryGraph :: (Graph, Graph.Vertex -> (Closure, Id, [Id]), Id -> Graph.Vertex) -> String renderMemoryGraph (graph, f, g) = "digraph G {\n" ++ "node [ fontname=monospace, shape=plaintext ];\n" ++ concatMap mkFrame (Graph.vertices graph) ++ "}" where mkFrame :: Graph.Vertex -> String mkFrame vertex = let (closure, _, ids) = f vertex rows :: T.Text rows = mkRow (pretty closure) in T.unpack $ setLabel vertex ("<