functor FLOWGRAPH(structure C2B : CodeToBlockSig structure Basic : BasicSig ): sig include FlowSig val codeToFlow : C.Code -> G.Graph end = struct exception FlowError local open Basic C2B C2B.C in structure B = C2B.B structure C = C2B.C structure G = struct type Vertex = int datatype Graph = FG of( Vertex * ( Vertex list * (C2B.B.Block * C2B.C.Cond) ) ) list fun vertices (FG g) = map #1 g fun adj (FG g) v = #1(lookup g v) end fun data (G.FG g) v = #2(lookup g v) local val c2b = C2B.codeToBlock o C2B.C.Code val enq = enq (op < : int * int -> bool) fun headers n [] = [] | headers n (s :: code) = let val headersRest = headers (n+1) code in case s of GOTO( c , m) => enq (n+1) (enq m headersRest) | _ => headersRest end fun take 0 x y = (x, y) | take n x (h :: t) = take (n-1) (h :: x) t | take _ x [] = (x, []) fun getBlock n p code = let val (b, rest) = take (p-n) [] code val blockInfo = case b of (GOTO(c, q) :: ss) => (n, ([q, p], (c2b(rev ss), c))) | _ => (n, ([p], (c2b(rev b), TRUE))) in (blockInfo, rest) end in fun codeToFlow (Code code) = let val headerList = enq 0 (headers 0 code) fun blocks (n::p::hs) code = let val (b, rest) = getBlock n p code in b :: (blocks (p :: hs) rest) end | blocks [n] code = [(n,([], (c2b code, TRUE)))] | blocks [] [] = [(0,([], (c2b [] , TRUE)))] | blocks _ _ = raise FlowError in G.FG(blocks headerList code) end end end end;