changeset 65:8cd61403ce80

Added to_dot method to flow. The method generates a dot graph representation of the flow graph.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Wed, 27 May 2009 11:58:57 +0200
parents c7d03c2e6e29
children 8b75ba4a3745
files pysmcl/flow.py pysmcl/test/unit/test_flow.py
diffstat 2 files changed, 88 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/pysmcl/flow.py	Wed May 27 11:58:09 2009 +0200
+++ b/pysmcl/flow.py	Wed May 27 11:58:57 2009 +0200
@@ -1,10 +1,12 @@
 import inspect
 import ast
+import StringIO
 
 # Import PySMCL packages.
-import pysmcl.pretty_print
+from pysmcl.pretty_print import PrettyPrinter
 import pysmcl.secret_ifs
 
+from pysmcl.graph import Node
 
 def analyze(function, join, combine, key, bottom):
     """
@@ -94,3 +96,37 @@
         return current
 
 
+    def to_dot(self, entry):
+        """Returns a pysmcl.graph.Node which is the dot node corresponding to entry.
+
+        entry (ast.Expr)
+        """
+        def pretty(ast_node):
+            output = StringIO.StringIO()
+            printer = PrettyPrinter(output)
+            printer.visit(ast_node)
+            s = output.getvalue()
+            return s.replace('\n', '')
+        pending_list = {}
+        worklist = [entry]
+        processed = {}
+        while len(worklist) > 0:
+            current = worklist.pop()
+            children = []
+            for n in current.children:
+                if n in processed.keys():
+                    children.append(processed[n])
+                else:
+                    pending_list[n] = Node([], pretty(n))
+                    children.append(pending_list[n])
+                    worklist.append(n)
+
+            if current in pending_list.keys():
+                node = pending_list[current]
+                node.out = children
+                del pending_list[current]
+            else:
+                node = Node(children, pretty(current))
+            processed[current] = node
+        return processed[entry]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pysmcl/test/unit/test_flow.py	Wed May 27 11:58:57 2009 +0200
@@ -0,0 +1,51 @@
+
+
+import unittest
+import StringIO
+
+from ast import *
+from pysmcl.ideal_functionality import init_statements
+from pysmcl.range_analysis import RangeAnalysis, Bottom
+
+from pysmcl.graph import Graph
+from pysmcl.flow import Flow
+
+class FlowToDotTest(unittest.TestCase):
+
+    def test_if(self):
+        p = 7
+        prog = parse(
+"""
+def f(x):
+    a=3
+    if x:
+         a=a+1
+    z=a+2-a
+""")
+        init_statements(prog)
+        flow = Flow()
+        flow.flow(prog.body[0])
+        entry = flow.to_dot(prog.body[0])
+        output = StringIO.StringIO()        
+        Graph(entry).to_dot(output)
+        expected_result = \
+"""digraph G {
+  in -> 2
+  in [shape = plaintext, label=""]
+    2 [label="def f(x):    a = 3    if(x):        a = a + 1    z = (a + 2) - a"]
+    2->1;
+    1 [label="a = 3"]
+    1->3;
+    3 [label="if(x):    a = a + 1"]
+    3->4;
+    3->5;
+    5 [label="z = (a + 2) - a"]
+    4 [label="a = a + 1"]
+    4->5;
+}
+"""
+        self.assertEquals(output.getvalue(), expected_result)
+
+
+if __name__ == '__main__':
+    unittest.main()