implementation module pretty // $Id$ import StdEnv :: Layout = Line String // A single line | Indent String [Layout] // A sequence of lines, the first of which is indented by a string (and the rest by an equivalent number of spaces) class Pretty t where pretty :: t -> Layout instance Pretty {#Char} where pretty s = Line s instance <<< Layout where <<< f l = printlayout l cont True [] f where cont first prefixes f = f printlayout (Line s) cont first is f = cont False (if first (asspaces is) is) ((printindents is f) <<< s) printlayout (Indent i ls) cont first is f = foldr printlayout cont` ls True [i:is] f where cont` first` is` f` = cont first is f` asspaces is = [toString (spaces (sum (map size is)))] printindents is f = foldr printindent f is printindent i f = f<< %include "basic.lit" > %include "graph.lit" -extgraph > %include "rule.lit" > %include "clean.lit" -cleanrule -cleantyperule -coretyperule -symbolmodule -typesymbolmodule ------------------------------------------------------------------------ Get the Select nodes from a graph. > getselectnodes :: graph symbol ** -> ** -> [((**,num),(num,**))] > getselectnodes graph root > = foldr (withmeta (nodecontents graph) addselectnode) [] (nodelist graph [root]) > where addselectnode (True,(Select arity index,[tuplenode])) selectnode > = (((tuplenode,arity),(index,selectnode)):) > addselectnode contents node = id Distribute the Select nodes over their indexes. > splitselectnodes :: ((**,num),[(num,**)]) -> (**,[[**]]) > splitselectnodes ((tuplenode,arity),selects) > = (tuplenode,foldr dist (rep arity []) selects) > where dist (1,selectnode) (ns:nss) = (selectnode:ns):nss > dist (index,selectnode) (ns:nss) = ns:dist (index-1,selectnode) nss Make left hand sides. > makelhss :: [**] -> [[**]] -> ([**],[[**]]) > makelhss heap nss > = (heap,[]), if empty > = (heap'',ns':nss''), otherwise > where (heap'',nss'') = makelhss heap' nss' > (empty,ns',heap',nss') = heads heap nss > heads heap [] = (True,[],heap,[]) > heads (node:heap) ([]:nss) > = (empty,node:ns',heap',[]:nss') > where (empty,ns',heap',nss') = heads heap nss > heads heap ((n:ns):nss) > = (False,n:ns',heap',ns:nss') > where (empty,ns',heap',nss') = heads heap nss > makenodedefs :: [**] -> [(**,[[**]])] -> [(**,[**])] > makenodedefs heap [] > = [] > makenodedefs heap ((tuplenode,nss):rest) > = map (pair tuplenode) lhss++nodedefs > where (heap',lhss) = makelhss heap nss > nodedefs = makenodedefs heap' rest > pretty :: symbol -> rule symbol node -> [[char]] > pretty symbol rule > = (showsymbol symbol++' ':concat (map ((++" ").fst) argreprs)++"-> "++snd rootrepr): > map2 shownodedef nodedefs (map snd tuplereprs) > where args = lhs rule; root = rhs rule; graph = rulegraph rule > nodedefs = makenodedefs (heap--nodelist graph (root:args)) tupleselections > tupleselections > = ( map splitselectnodes. > partition fst snd > ) (getselectnodes graph root) > tuplenodes = map fst tupleselections > prunedgraph = foldr prunegraph graph tuplenodes > [argreprs,[rootrepr],tuplereprs] > = hof (foldgraph prettyref (issafe.shownode) prettydef prunedgraph) [args,[root],map fst nodedefs] > where prettyref node (saferef,unsaferef) = issafe (shownode node++':':saferef) > shownodedef (tuplenode,selectnodes) tuplerepr > = ", ("++join ',' (map shownode selectnodes)++"): "++tuplerepr >issafe::[char]->([char],[char]) >prettydef::symbol->[([char],[char])]->([char],[char]) ------------------------------------------------------------------------ Useful (higher order) functions. > withmeta :: (*->**) -> (**->*->***) -> * -> *** > withmeta meta f x = f (meta x) x > pair :: * -> ** -> (*,**) > pair x y = (x,y) > hof :: ([*]->[**]) -> [[*]] -> [[**]] > hof f xss > = claims xss (f (concat xss)) > claims :: [[*]] -> [**] -> [[**]] > claims [] ys = [] > claims (xs:xss) ys > = zs:claims xss ys' > where (zs,ys') = claim xs ys */