-
Notifications
You must be signed in to change notification settings - Fork 1
/
dot-generator.dylan
58 lines (54 loc) · 1.97 KB
/
dot-generator.dylan
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
module: graphviz-renderer
author: Andreas Bogk and Hannes Mehnert
copyright: 2005-2011 Andreas Bogk and Hannes Mehnert. All rights reserved.
license: see license.txt in this directory
define function generate-dot
(graph :: <graph>, output :: <stream>, #key top-node) => ()
write(output, "digraph G {\n");
if (graph.attributes.size > 0)
for (value keyed-by name in graph.attributes)
write(output, concatenate(" ", name, " = \"", value ,"\";\n"));
end for;
end if;
for (node in graph.nodes)
process-node(node, output);
end;
write(output, "}\n");
end;
define function process-nodes
(top-node :: <node>, output :: <stream>) => ()
let nodes-queue = make(<deque>);
push(nodes-queue, top-node);
do(curry(push-last, nodes-queue), predecessors(top-node));
let visited = make(<stretchy-vector>);
while (nodes-queue.size > 0)
let node = nodes-queue.pop;
process-node(node, output);
add!(visited, node);
do(curry(push-last, nodes-queue),
choose(method(x) ~ member?(x, nodes-queue) & ~ member?(x, visited) end,
successors(node)))
end;
end;
define function process-node (node :: <node>, output :: <stream>) => ()
local method print-edge (edge :: <edge>)
write(output, concatenate(" \"", node.label, "\" -> \"",
edge.target.label, "\""));
print-attributes(output, edge.attributes);
write(output, ";\n");
end;
write(output, concatenate(" \"", node.label, "\""));
print-attributes(output, node.attributes);
write(output, ";\n");
do(print-edge, node.outgoing-edges);
end;
define function print-attributes (stream :: <stream>, attributes :: <string-table>)
if (attributes.size > 0)
let attrs = make(<stretchy-vector>);
for (ele in key-sequence(attributes))
add!(attrs, concatenate(ele, " = \"", attributes[ele], "\""));
end;
attrs := reduce1(method(x, y) concatenate(x, ",", y) end, attrs);
write(stream, concatenate(" [", attrs, "]"))
end;
end;