diff python/ppci/c3/visitor.py @ 300:158068af716c

yafm
author Windel Bouwman
date Tue, 03 Dec 2013 18:00:22 +0100
parents python/c3/visitor.py@a747a45dcd78
children b145f8e6050b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/python/ppci/c3/visitor.py	Tue Dec 03 18:00:22 2013 +0100
@@ -0,0 +1,85 @@
+from .astnodes import *
+
+
+class Visitor:
+    """
+        Visitor that can visit all nodes in the AST
+        and run pre and post functions.
+    """
+    def visit(self, node, f_pre=None, f_post=None):
+        self.f_pre = f_pre
+        self.f_post = f_post
+        self.do(node)
+
+    def do(self, node):
+        # Run visitor:
+        if self.f_pre:
+            self.f_pre(node)
+
+        # Descent into subnodes:
+        if type(node) is Package:
+            for decl in node.declarations:
+                self.do(decl)
+        elif type(node) is Function:
+            for s in node.declarations:
+                self.do(s)
+            self.do(node.body)
+        elif type(node) is CompoundStatement:
+            for s in node.statements:
+                self.do(s)
+        elif type(node) is IfStatement:
+            self.do(node.condition)
+            self.do(node.truestatement)
+            if node.falsestatement:
+                self.do(node.falsestatement)
+        elif type(node) is FunctionCall:
+            for arg in node.args:
+                self.do(arg)
+        elif type(node) is Assignment:
+            self.do(node.lval)
+            self.do(node.rval)
+        elif type(node) is ReturnStatement:
+            self.do(node.expr)
+        elif type(node) is Binop:
+            self.do(node.a)
+            self.do(node.b)
+        elif type(node) is Unop:
+            self.do(node.a)
+        elif type(node) is ExpressionStatement:
+            self.do(node.ex)
+        elif type(node) is TypeCast:
+            self.do(node.a)
+        elif type(node) is FieldRef:
+            self.do(node.base)
+        elif type(node) is Deref:
+            self.do(node.ptr)
+        elif type(node) is Constant:
+            self.do(node.value)
+        elif type(node) in [VariableUse, Variable, Literal, FunctionType,
+                            DefinedType, FormalParameter, LocalVariable]:
+            # Those nodes do not have child nodes.
+            pass
+        elif type(node) is WhileStatement:
+            self.do(node.condition)
+            self.do(node.statement)
+        else:
+            raise Exception('Could not visit "{0}"'.format(node))
+
+        # run post function
+        if self.f_post:
+            self.f_post(node)
+
+
+class AstPrinter:
+    """ Prints an AST as text """
+    def printAst(self, pkg):
+        self.indent = 0
+        visitor = Visitor()
+        visitor.visit(pkg, self.print1, self.print2)
+
+    def print1(self, node):
+        print(' ' * self.indent + str(node))
+        self.indent += 2
+
+    def print2(self, node):
+        self.indent -= 2