-- This file is included by Transform.ag -- Generates code for a dependency graph SEM Program | Program loc.ppGraph = "digraph Deps {" >-< indent 2 ( vlist [ ppgNode (Map.findWithDefault noPos d @blocks.gathStmtPosMap) d @loc.distRanks | d <- @loc.unqItems ]) >-< indent 2 ( vlist [ label' from >#< "->" >#< ppgDeps (map label' [to]) >#< pp_block "[" "]" "," ( ppgColor (isOnCycle from @loc.distRanks && isOnCycle to @loc.distRanks) : maybe [] (\d -> [ppgProp "label" d]) (ppgReason reason)) >|< ";" | (from, (reason, tos)) <- Map.assocs @loc.unqDeps , length tos >= 1 , let label' = \item -> ppgKey (Map.findWithDefault noPos item @blocks.gathStmtPosMap) item , to <- tos ] ) >-< "}" { isOnCycle :: DepItem -> Map DepItem (Bool,Int) -> Bool isOnCycle d mp = case Map.lookup d mp of Nothing -> False Just (b,_) -> b ppgProp :: PP a => String -> a -> PP_Doc ppgProp s d = s >|< "=" >|< pp_doubleQuotes (pp d) ppgNms :: QIdent -> PP_Doc ppgNms = hlist . map show ppgDeps :: PP a => [a] -> PP_Doc ppgDeps [x] = pp x ppgDeps xs = pp_block "{" "}" ";" (map pp xs) ppgNode :: Pos -> DepItem -> Map DepItem (Bool,Int) -> PP_Doc ppgNode pos item rankMap = case item of DepMatch n -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "label" l, c] >|< ";" DepAssert n -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "label" l, c] >|< ";" DepDefault n -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "label" l, c] >|< ";" DepAttach n -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "shape" "box",ppgProp "label" l, c] >|< ";" DepInvoke nms -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "shape" "box",ppgProp "skew" ".3",ppgProp "label" l,c] >|< ";" DepVisStart nms -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "shape" "box",ppgProp "skew" ".3",ppgProp "label" l,c] >|< ";" DepVisEnd nms -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "shape" "box",ppgProp "skew" ".3",ppgProp "label" l,c] >|< ";" DepClause nms -> ppgKey pos item >#< pp_block "[" "]" "," [ppgProp "shape" "box",ppgProp "skew" ".3",ppgProp "label" l,c] >|< ";" where mbInfo = Map.lookup item rankMap l = ppgLabel pos item (maybe Nothing (Just . snd) mbInfo) c = ppgColor (maybe False fst mbInfo) ppgColor :: Bool -> PP_Doc ppgColor True = ppgProp "color" "red4" ppgColor False = ppgProp "color" "black" ppgLabel :: Pos -> DepItem -> Maybe Int -> PP_Doc ppgLabel pos item mbRank = case item of DepMatch m -> r >#< show m >|< "?@" >|< show (line pos) DepAssert n -> r >#< show n >|< "@" >|< show (line pos) DepDefault o -> r >#< "d" >|< show o DepAttach n -> r >#< "@" >|< show (line pos) DepInvoke (visit:name:_) -> r >#< name >|< "." >|< visit >|< "@" >|< show (line $ identPos name) DepInvoke _ -> r >#< text "i???" DepVisStart (visit:_) -> r >#< ">" >|< show visit >|< "@" >|< show (line $ identPos visit) DepVisStart _ -> r >#< text ">v???" DepVisEnd (visit:_) -> r >#< show visit >|< "@" >|< show (line $ identPos visit) >|< "<" DepVisEnd _ -> r >#< text " r >#< "|" >|< show clause >|< "@" >|< show (line $ identPos clause) DepClause _ -> r >#< text "|???" where r = case mbRank of Nothing -> empty Just k -> show k >|< ":" ppgKey :: Pos -> DepItem -> PP_Doc ppgKey pos item = case item of DepMatch n -> "s" >|< show n DepAssert n -> "s" >|< show n DepDefault n -> "d" >|< show n DepAttach n -> "a" >|< show n DepInvoke nms -> "iv" >|< ppgNms nms DepVisStart nms -> "vb" >|< ppgNms nms DepVisEnd nms -> "ve" >|< ppgNms nms DepClause nms -> "cl" >|< ppgNms nms ppgReason :: Reason -> Maybe PP_Doc ppgReason reason = case reason of ReasonScopeVisit i -> Nothing -- Just ("sc-vis-pre" >#< show i) ReasonScopeClause i -> Nothing -- Just ("sc-cl" >#< show i) ReasonScopeEnd i -> Nothing -- Just ("sc-vis-end" >#< show i) ReasonAttrReq chld attr -> Just (show chld >|< "." >|< show attr) ReasonInvokeReq i -> Just ("inv" >#< show i) ReasonChildReq i -> Nothing -- Just ("chld" >#< show i) ReasonAttach i v -> Just ("att" >#< show i >|< "." >|< show v) ReasonDefault attr -> Nothing -- Just ("def." >|< show attr) ReasonDetach _ _ -> Nothing -- Just $ text "detach" ReasonError -> Just $ text "error" }