File: daVinci.sml

package info (click to toggle)
mlton 20210117%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 58,464 kB
  • sloc: ansic: 27,682; sh: 4,455; asm: 3,569; lisp: 2,879; makefile: 2,347; perl: 1,169; python: 191; pascal: 68; javascript: 7
file content (121 lines) | stat: -rw-r--r-- 4,173 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
(*
 * This backend communicates with the daVinci tool.
 *
 * -- Allen
 *)

structure daVinci : GRAPH_DISPLAY =
struct

   structure L = GraphLayout
   structure G = Graph

   fun suffix() = ".daVinci"
   fun program() = "daVinci"

   fun visualize out (G.GRAPH G) =
   let val l = ref 0
       fun newLabel() = (l := !l + 1; "L" ^ Int.toString(!l))
       val spaces = "                                           ";
       fun int n   = out (Int.toString n)
       fun nl()    = out "\n"
       fun tab t   = out(String.substring(spaces,0,t)) handle _ => out spaces
       fun nice l  =  String.toString (String.map (fn #"\t" => #" "
                                                       | c => c) l)
       fun quote s      = (out "\""; out s; out "\"")
       fun comma()      = out ", "   
       fun atom(a,b)    = (out "a("; quote a; comma(); quote b; out ")") 
       fun OBJECT l     = atom("OBJECT",nice l)
       fun FONTFAMILY f = atom("FONTFAMILY",f)
       fun FONTSTYLE s  = atom("FONTSTYLE",s)
       fun COLOR c      = atom("COLOR",c)
       fun EDGECOLOR c  = atom("EDGECOLOR",c)
       fun Dir ()       = atom("_DIR","none")
       fun label l      = (OBJECT l;             comma(); 
                           FONTFAMILY "courier"; comma();
                           FONTSTYLE "normal"
                          ) 

       exception FOUND of string

       fun nodeAttrib (L.LABEL l) = label l
         | nodeAttrib (L.COLOR c) = COLOR c
         | nodeAttrib (L.BORDERLESS) = atom("_GO","text")
         | nodeAttrib (L.BORDER_COLOR c) = COLOR c
         | nodeAttrib _ = ()

       and isNodeAttrib (L.LABEL l) = true
         | isNodeAttrib (L.COLOR c) = true
         | isNodeAttrib (L.BORDERLESS) = true
         | isNodeAttrib (L.BORDER_COLOR c) = true
         | isNodeAttrib _ = false

       and edgeAttrib (L.COLOR c)       = EDGECOLOR c
         | edgeAttrib (L.ARROW_COLOR c) = EDGECOLOR c
         | edgeAttrib (L.EDGEPATTERN p) = atom("EDGEPATTERN",p)
         | edgeAttrib L.DIR = Dir()
         | edgeAttrib _ = () 

       and isEdgeAttrib (L.COLOR c)       = true
         | isEdgeAttrib (L.ARROW_COLOR c) = true
         | isEdgeAttrib (L.EDGEPATTERN p) = true
         | isEdgeAttrib (L.DIR) = true
         | isEdgeAttrib _ = false 

       and findEdgeLabel ((L.LABEL "")::l) = findEdgeLabel l
         | findEdgeLabel ((L.LABEL l)::_) = raise FOUND l
         | findEdgeLabel (_::l) = findEdgeLabel l
         | findEdgeLabel []     = ()

       and listify comma f []      = ()
         | listify comma f [x]     = f x
         | listify comma f (x::xs) = (f x; comma(); listify comma f xs)

       and attribs t (p,gen) a =
          (tab t; out "[\n";
           tab (t+2); listify comma gen (List.filter p a); nl();
           tab t; out "]\n"
          )

       fun doNode t (n,a) =
           ( tab t; 
             out "l(\""; int n; out "\",n(\"\",\n";
             attribs (t+2) (isNodeAttrib,nodeAttrib) a;
             comma();
             tab (t+2); out "[\n";
             listify comma (doEdge (t+2)) (#out_edges G n);
             tab (t+2); out "]))\n"
           )

       and doEdge t (i,j,a) =
          ((findEdgeLabel a;
            tab t; out "l(\""; 
            int i; out "->"; int j; 
            (* dummy label; daVinci chokes on duplicated edge names *)
            out "-"; out(newLabel()); 
            out "\",e(\"\",\n";
            attribs (t+2) (isEdgeAttrib,edgeAttrib) a;
            tab t; out ",r(\""; int j; out "\")))")
            handle FOUND l =>
            let val x = newLabel()
            in
            (tab t; out "l(\""; int i; out("->"^x^"\",e(\"\",");
             attribs (t+2) (isEdgeAttrib,edgeAttrib) (L.DIR::a);
             out ",l(\""; out(newLabel());
             out "\",n(\"\",[a(\"OBJECT\",\"";
             out l; out "\"),a(\"_GO\",\"text\")],";
             out("[l(\""^x^"->"); int j; out "\",e(\"\",";
             attribs (t+2) (isEdgeAttrib,edgeAttrib) a;
             tab t; out ",r(\""; int j; out "\")))]))))"
            )
            end
          )

   in  out "[\n";
       listify comma (doNode 2) (#nodes G ());
       out "]\n" 
   end
   

end