[pypy-svn] r34946 - pypy/dist/pypy/rlib/parsing

arigo at codespeak.net arigo at codespeak.net
Fri Nov 24 20:20:56 CET 2006


Author: arigo
Date: Fri Nov 24 20:20:54 2006
New Revision: 34946

Modified:
   pypy/dist/pypy/rlib/parsing/tree.py
Log:
Trying to get rid of the 'exec' here.  A closure works just as nicely.
This fixes a problem where multiple 'self.dispatch_table' get merged
between multiple subclasses of RPythonVisitor.



Modified: pypy/dist/pypy/rlib/parsing/tree.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/tree.py	(original)
+++ pypy/dist/pypy/rlib/parsing/tree.py	Fri Nov 24 20:20:54 2006
@@ -26,6 +26,7 @@
             id(self), self.symbol, addinfo)).replace("\\", "\\\\")
 
     def visit(self, visitor):
+        "NOT_RPYTHON"
         if isinstance(visitor, RPythonVisitor):
             visitor.dispatch(self)
         method = getattr(visitor, "visit_" + self.symbol, None)
@@ -52,6 +53,7 @@
                 yield line
 
     def visit(self, visitor):
+        "NOT_RPYTHON"
         if isinstance(visitor, RPythonVisitor):
             visitor.dispatch(self)
         general = getattr(visitor, "visit", None)
@@ -75,34 +77,32 @@
     def __str__(self):
         return "could not visit %s" % (self.node, )
 
-def make_dispatch_function(dispatch_table):
-    code = ["def dispatch(self, node):"]
-    code.append("    if isinstance(node, Nonterminal):")
-    code.append("        if node.symbol not in self.dispatch_table:")
-    if "__general_nonterminal_visit" in dispatch_table:
-        code.append(
-                "            return self.dispatch_table['__general_nonterminal_visit'](self, node)")
-    elif "__general_visit" in dispatch_table:
-        code.append(
-                "            return self.dispatch_table['__general_visit'](self, node)")
-    else:
-        code.append("            raise VisitError(node)")
-    code.append("        else:")
-    code.append("            return self.dispatch_table[node.symbol](self, node)")
-    code.append("    if isinstance(node, Symbol):")
-    code.append("        if node.symbol not in self.dispatch_table:")
-    if "__general_symbol_visit" in dispatch_table:
-        code.append(
-                "            return self.dispatch_table['__general_symbol_visit'](self, node)")
-    elif "__general_visit" in dispatch_table:
-        code.append(
-                "            return self.dispatch_table['__general_visit'](self, node)")
-    else:
-        code.append("              raise VisitError(node)")
-    code.append("        else:")
-    code.append("            return self.dispatch_table[node.symbol](self, node)")
-    code.append("    raise VisitError(node)")
-    exec py.code.Source("\n".join(code)).compile()
+def make_dispatch_function(__general_nonterminal_visit=None,
+                           __general_symbol_visit=None,
+                           __general_visit=None,
+                           **dispatch_table):
+    def dispatch(self, node):
+        if isinstance(node, Nonterminal):
+            if node.symbol not in dispatch_table:
+                if __general_nonterminal_visit:
+                    return __general_nonterminal_visit(self, node)
+                elif __general_visit:
+                    return __general_visit(self, node)
+                else:
+                    raise VisitError(node)
+            else:
+                return dispatch_table[node.symbol](self, node)
+        if isinstance(node, Symbol):
+            if node.symbol not in dispatch_table:
+                if __general_symbol_visit:
+                    return __general_symbol_visit(self, node)
+                elif __general_visit:
+                    return __general_visit(self, node)
+                else:
+                    raise VisitError(node)
+            else:
+                return dispatch_table[node.symbol](self, node)
+        raise VisitError(node)
     return dispatch
 
 class CreateDispatchDictionaryMetaclass(type):
@@ -116,26 +116,8 @@
                         "general_visit"]:
             if special in dct:
                 dispatch_table["__" + special] = dct[special]
-        dct["dispatch_table"] = dispatch_table
-        dct["dispatch"] = make_dispatch_function(dispatch_table)
+        dct["dispatch"] = make_dispatch_function(**dispatch_table)
         return type.__new__(cls, name_, bases, dct)
 
 class RPythonVisitor(object):
     __metaclass__ = CreateDispatchDictionaryMetaclass
-
-    def dispatch(self, node):
-        if isinstance(node, Nonterminal):
-            if node.symbol not in self.dispatch_table:
-                raise VisitError(node)
-            else:
-                return self.dispatch_table[node.symbol](self, node)
-        elif isinstance(node, Symbol):
-            if node.symbol not in self.dispatch_table:
-                if "__general_symbol" in self.dispatch_table:
-                    return self.dispatch_table["__general_symbol"](self, node)
-                raise VisitError(node)
-            else:
-                return self.dispatch_table[node.symbol](self, node)
-
-        else:
-            raise VisitError(node)



More information about the Pypy-commit mailing list