[pypy-svn] r29812 - in pypy/dist/pypy/interpreter/astcompiler: . test

mwh at codespeak.net mwh at codespeak.net
Sat Jul 8 13:59:45 CEST 2006


Author: mwh
Date: Sat Jul  8 13:59:37 2006
New Revision: 29812

Modified:
   pypy/dist/pypy/interpreter/astcompiler/ast.py
   pypy/dist/pypy/interpreter/astcompiler/ast.txt
   pypy/dist/pypy/interpreter/astcompiler/astgen.py
   pypy/dist/pypy/interpreter/astcompiler/test/test_ast.py
Log:
(misto, mwh)
Fixed a bug with mutating "could be None" node attributes.  Added special cases
for mutating the handful of non-regular node types (and added tests for running
a null mutator over such nodes).  A very simple constant folder now at least
doesn't choke on pystone and whatever that imports, so the mutation support is
(fingers crossed) probably complete enough now.


Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/ast.py	Sat Jul  8 13:59:37 2006
@@ -802,7 +802,7 @@
     space.setattr(w_self, space.wrap("test"), w_new_test)
 
     w_fail = space.getattr(w_self, space.wrap("fail"))
-    if space.is_w(w_fail, space.w_None):
+    if not space.is_w(w_fail, space.w_None):
         w_mutate_fail = space.getattr(w_fail, space.wrap("mutate"))
         w_mutate_fail_args = Arguments(space, [ w_visitor ])
         w_new_fail = space.call_args(w_mutate_fail, w_mutate_fail_args)
@@ -1465,14 +1465,14 @@
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_star_args = space.getattr(w_self, space.wrap("star_args"))
-    if space.is_w(w_star_args, space.w_None):
+    if not space.is_w(w_star_args, space.w_None):
         w_mutate_star_args = space.getattr(w_star_args, space.wrap("mutate"))
         w_mutate_star_args_args = Arguments(space, [ w_visitor ])
         w_new_star_args = space.call_args(w_mutate_star_args, w_mutate_star_args_args)
         space.setattr(w_self, space.wrap("star_args"), w_new_star_args)
 
     w_dstar_args = space.getattr(w_self, space.wrap("dstar_args"))
-    if space.is_w(w_dstar_args, space.w_None):
+    if not space.is_w(w_dstar_args, space.w_None):
         w_mutate_dstar_args = space.getattr(w_dstar_args, space.wrap("mutate"))
         w_mutate_dstar_args_args = Arguments(space, [ w_visitor ])
         w_new_dstar_args = space.call_args(w_mutate_dstar_args, w_mutate_dstar_args_args)
@@ -1642,7 +1642,8 @@
 
     def mutate(self, visitor):
         self.expr = self.expr.mutate(visitor)
-        self.ops[:] = [n.mutate(visitor) for n in self.ops]
+        self.ops[:] = [(op_name, node.mutate(visitor)) for (op_name, node) in self.ops]
+
         return visitor.visitCompare(self)
 
     def fget_expr( space, self):
@@ -1663,7 +1664,7 @@
     self.ops = ops
     self.lineno = lineno
     return space.wrap(self)
-    
+
 
 
 def descr_Compare_accept( space, w_self, w_visitor):
@@ -1671,7 +1672,7 @@
     args = Arguments(space, [ w_self ])
     return space.call_args(w_callable, args)
 
-def descr_Compare_mutate(space, w_self, w_visitor): 
+def descr_Compare_mutate(space, w_self, w_visitor):
     w_expr = space.getattr(w_self, space.wrap("expr"))
     w_mutate_expr = space.getattr(w_expr, space.wrap("mutate"))
     w_mutate_expr_args = Arguments(space, [ w_visitor ])
@@ -1682,16 +1683,22 @@
     list_w = space.unpackiterable(w_list)
     newlist_w = []
     for w_item in list_w:
-        w_item_mutate = space.getattr(w_item, space.wrap("mutate"))
-        w_item_mutate_args = Arguments(space, [ w_visitor ])
-        w_newitem = space.call_args(w_item_mutate, w_item_mutate_args)
-        newlist_w.append(w_newitem)
+        w_opname, w_node = space.unpackiterable(w_item, 2)
+        
+        w_node_mutate = space.getattr(w_node, space.wrap("mutate"))
+        w_node_mutate_args = Arguments(space, [ w_visitor ])
+        w_newnode = space.call_args(w_node_mutate, w_node_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_opname, w_newnode]))
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_visitCompare = space.getattr(w_visitor, space.wrap("visitCompare"))
     w_visitCompare_args = Arguments(space, [ w_self ])
     return space.call_args(w_visitCompare, w_visitCompare_args)
 
+
+
+
 Compare.typedef = TypeDef('Compare', Node.typedef, 
                      __new__ = interp2app(descr_Compare_new, unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root, int]),
                      accept=interp2app(descr_Compare_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
@@ -1986,7 +1993,8 @@
         return visitor.visitDict(self)
 
     def mutate(self, visitor):
-        self.items[:] = [n.mutate(visitor) for n in self.items]
+        self.items[:] = [(n.mutate(visitor), o.mutate(visitor)) for (n, o) in self.items]
+
         return visitor.visitDict(self)
 
 
@@ -2002,7 +2010,6 @@
     self.items = items
     self.lineno = lineno
     return space.wrap(self)
-    
 
 
 
@@ -2011,21 +2018,30 @@
     args = Arguments(space, [ w_self ])
     return space.call_args(w_callable, args)
 
-def descr_Dict_mutate(space, w_self, w_visitor): 
+def descr_Dict_mutate(space, w_self, w_visitor):
     w_list = space.getattr(w_self, space.wrap("items"))
     list_w = space.unpackiterable(w_list)
     newlist_w = []
     for w_item in list_w:
-        w_item_mutate = space.getattr(w_item, space.wrap("mutate"))
-        w_item_mutate_args = Arguments(space, [ w_visitor ])
-        w_newitem = space.call_args(w_item_mutate, w_item_mutate_args)
-        newlist_w.append(w_newitem)
+        w_key, w_value = space.unpackiterable(w_item, 2)
+        
+        w_key_mutate = space.getattr(w_key, space.wrap("mutate"))
+        w_key_mutate_args = Arguments(space, [ w_visitor ])
+        w_newkey = space.call_args(w_key_mutate, w_key_mutate_args)
+
+        w_value_mutate = space.getattr(w_value, space.wrap("mutate"))
+        w_value_mutate_args = Arguments(space, [ w_visitor ])
+        w_newvalue = space.call_args(w_value_mutate, w_value_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_newkey, w_newvalue]))
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_visitDict = space.getattr(w_visitor, space.wrap("visitDict"))
     w_visitDict_args = Arguments(space, [ w_self ])
     return space.call_args(w_visitDict, w_visitDict_args)
 
+
+
 Dict.typedef = TypeDef('Dict', Node.typedef, 
                      __new__ = interp2app(descr_Dict_new, unwrap_spec=[ObjSpace, W_Root, W_Root, int]),
                      accept=interp2app(descr_Dict_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
@@ -2285,14 +2301,14 @@
     space.setattr(w_self, space.wrap("expr"), w_new_expr)
 
     w_locals = space.getattr(w_self, space.wrap("locals"))
-    if space.is_w(w_locals, space.w_None):
+    if not space.is_w(w_locals, space.w_None):
         w_mutate_locals = space.getattr(w_locals, space.wrap("mutate"))
         w_mutate_locals_args = Arguments(space, [ w_visitor ])
         w_new_locals = space.call_args(w_mutate_locals, w_mutate_locals_args)
         space.setattr(w_self, space.wrap("locals"), w_new_locals)
 
     w_globals = space.getattr(w_self, space.wrap("globals"))
-    if space.is_w(w_globals, space.w_None):
+    if not space.is_w(w_globals, space.w_None):
         w_mutate_globals = space.getattr(w_globals, space.wrap("mutate"))
         w_mutate_globals_args = Arguments(space, [ w_visitor ])
         w_new_globals = space.call_args(w_mutate_globals, w_mutate_globals_args)
@@ -2481,7 +2497,7 @@
     space.setattr(w_self, space.wrap("body"), w_new_body)
 
     w_else_ = space.getattr(w_self, space.wrap("else_"))
-    if space.is_w(w_else_, space.w_None):
+    if not space.is_w(w_else_, space.w_None):
         w_mutate_else_ = space.getattr(w_else_, space.wrap("mutate"))
         w_mutate_else__args = Arguments(space, [ w_visitor ])
         w_new_else_ = space.call_args(w_mutate_else_, w_mutate_else__args)
@@ -2522,7 +2538,7 @@
     def fset_names( space, self, w_arg ):
         del self.names[:]
         for w_tup in space.unpackiterable( w_arg ):
-            w_name = space.getitem( w_tup, space.wrap(0) ) 
+            w_name = space.getitem( w_tup, space.wrap(0) )
             w_as_name = space.getitem( w_tup, space.wrap(1) )
             name = space.str_w( w_name )
             as_name = None
@@ -2698,7 +2714,7 @@
 
 def descr_Function_mutate(space, w_self, w_visitor): 
     w_decorators = space.getattr(w_self, space.wrap("decorators"))
-    if space.is_w(w_decorators, space.w_None):
+    if not space.is_w(w_decorators, space.w_None):
         w_mutate_decorators = space.getattr(w_decorators, space.wrap("mutate"))
         w_mutate_decorators_args = Arguments(space, [ w_visitor ])
         w_new_decorators = space.call_args(w_mutate_decorators, w_mutate_decorators_args)
@@ -3218,7 +3234,8 @@
         return visitor.visitIf(self)
 
     def mutate(self, visitor):
-        self.tests[:] = [n.mutate(visitor) for n in self.tests]
+        self.tests[:] = [(n.mutate(visitor), o.mutate(visitor)) for (n, o) in self.tests]
+
         if self.else_ is not None:
             self.else_ = self.else_.mutate(visitor)
         return visitor.visitIf(self)
@@ -3244,7 +3261,6 @@
     self.else_ = space.interp_w(Node, w_else_, can_be_None=True)
     self.lineno = lineno
     return space.wrap(self)
-    
 
 
 
@@ -3253,27 +3269,33 @@
     args = Arguments(space, [ w_self ])
     return space.call_args(w_callable, args)
 
-def descr_If_mutate(space, w_self, w_visitor): 
+def descr_If_mutate(space, w_self, w_visitor):
     w_list = space.getattr(w_self, space.wrap("tests"))
     list_w = space.unpackiterable(w_list)
     newlist_w = []
     for w_item in list_w:
-        w_item_mutate = space.getattr(w_item, space.wrap("mutate"))
-        w_item_mutate_args = Arguments(space, [ w_visitor ])
-        w_newitem = space.call_args(w_item_mutate, w_item_mutate_args)
-        newlist_w.append(w_newitem)
+        w_test, w_suite = space.unpackiterable(w_item, 2)
+
+        w_test_mutate = space.getattr(w_test, space.wrap("mutate"))
+        w_test_mutate_args = Arguments(space, [ w_visitor ])
+        w_newtest = space.call_args(w_test_mutate, w_test_mutate_args)
+
+        w_suite_mutate = space.getattr(w_suite, space.wrap("mutate"))
+        w_suite_mutate_args = Arguments(space, [ w_visitor ])
+        w_newsuite = space.call_args(w_suite_mutate, w_suite_mutate_args)
+        newlist_w.append(space.newtuple([w_newtest, w_newsuite]))
+    
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_else_ = space.getattr(w_self, space.wrap("else_"))
-    if space.is_w(w_else_, space.w_None):
+    if not space.is_w(w_else_, space.w_None):
         w_mutate_else_ = space.getattr(w_else_, space.wrap("mutate"))
         w_mutate_else__args = Arguments(space, [ w_visitor ])
         w_new_else_ = space.call_args(w_mutate_else_, w_mutate_else__args)
         space.setattr(w_self, space.wrap("else_"), w_new_else_)
 
-    w_visitIf = space.getattr(w_visitor, space.wrap("visitIf"))
-    w_visitIf_args = Arguments(space, [ w_self ])
-    return space.call_args(w_visitIf, w_visitIf_args)
+
+
 
 If.typedef = TypeDef('If', Node.typedef, 
                      __new__ = interp2app(descr_If_new, unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root, int]),
@@ -3303,7 +3325,7 @@
     def fset_names( space, self, w_arg ):
         del self.names[:]
         for w_tup in space.unpackiterable( w_arg ):
-            w_name = space.getitem( w_tup, space.wrap(0) ) 
+            w_name = space.getitem( w_tup, space.wrap(0) )
             w_as_name = space.getitem( w_tup, space.wrap(1) )
             name = space.str_w( w_name )
             as_name = None
@@ -3336,7 +3358,7 @@
     self.names = names
     self.lineno = lineno
     return space.wrap(self)
-    
+
 
 
 def descr_Import_accept( space, w_self, w_visitor):
@@ -4590,7 +4612,7 @@
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_dest = space.getattr(w_self, space.wrap("dest"))
-    if space.is_w(w_dest, space.w_None):
+    if not space.is_w(w_dest, space.w_None):
         w_mutate_dest = space.getattr(w_dest, space.wrap("mutate"))
         w_mutate_dest_args = Arguments(space, [ w_visitor ])
         w_new_dest = space.call_args(w_mutate_dest, w_mutate_dest_args)
@@ -4680,7 +4702,7 @@
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_dest = space.getattr(w_self, space.wrap("dest"))
-    if space.is_w(w_dest, space.w_None):
+    if not space.is_w(w_dest, space.w_None):
         w_mutate_dest = space.getattr(w_dest, space.wrap("mutate"))
         w_mutate_dest_args = Arguments(space, [ w_visitor ])
         w_new_dest = space.call_args(w_mutate_dest, w_mutate_dest_args)
@@ -4778,21 +4800,21 @@
 
 def descr_Raise_mutate(space, w_self, w_visitor): 
     w_expr1 = space.getattr(w_self, space.wrap("expr1"))
-    if space.is_w(w_expr1, space.w_None):
+    if not space.is_w(w_expr1, space.w_None):
         w_mutate_expr1 = space.getattr(w_expr1, space.wrap("mutate"))
         w_mutate_expr1_args = Arguments(space, [ w_visitor ])
         w_new_expr1 = space.call_args(w_mutate_expr1, w_mutate_expr1_args)
         space.setattr(w_self, space.wrap("expr1"), w_new_expr1)
 
     w_expr2 = space.getattr(w_self, space.wrap("expr2"))
-    if space.is_w(w_expr2, space.w_None):
+    if not space.is_w(w_expr2, space.w_None):
         w_mutate_expr2 = space.getattr(w_expr2, space.wrap("mutate"))
         w_mutate_expr2_args = Arguments(space, [ w_visitor ])
         w_new_expr2 = space.call_args(w_mutate_expr2, w_mutate_expr2_args)
         space.setattr(w_self, space.wrap("expr2"), w_new_expr2)
 
     w_expr3 = space.getattr(w_self, space.wrap("expr3"))
-    if space.is_w(w_expr3, space.w_None):
+    if not space.is_w(w_expr3, space.w_None):
         w_mutate_expr3 = space.getattr(w_expr3, space.wrap("mutate"))
         w_mutate_expr3_args = Arguments(space, [ w_visitor ])
         w_new_expr3 = space.call_args(w_mutate_expr3, w_mutate_expr3_args)
@@ -4859,7 +4881,7 @@
 
 def descr_Return_mutate(space, w_self, w_visitor): 
     w_value = space.getattr(w_self, space.wrap("value"))
-    if space.is_w(w_value, space.w_None):
+    if not space.is_w(w_value, space.w_None):
         w_mutate_value = space.getattr(w_value, space.wrap("mutate"))
         w_mutate_value_args = Arguments(space, [ w_visitor ])
         w_new_value = space.call_args(w_mutate_value, w_mutate_value_args)
@@ -5037,14 +5059,14 @@
     space.setattr(w_self, space.wrap("expr"), w_new_expr)
 
     w_lower = space.getattr(w_self, space.wrap("lower"))
-    if space.is_w(w_lower, space.w_None):
+    if not space.is_w(w_lower, space.w_None):
         w_mutate_lower = space.getattr(w_lower, space.wrap("mutate"))
         w_mutate_lower_args = Arguments(space, [ w_visitor ])
         w_new_lower = space.call_args(w_mutate_lower, w_mutate_lower_args)
         space.setattr(w_self, space.wrap("lower"), w_new_lower)
 
     w_upper = space.getattr(w_self, space.wrap("upper"))
-    if space.is_w(w_upper, space.w_None):
+    if not space.is_w(w_upper, space.w_None):
         w_mutate_upper = space.getattr(w_upper, space.wrap("mutate"))
         w_mutate_upper_args = Arguments(space, [ w_visitor ])
         w_new_upper = space.call_args(w_mutate_upper, w_mutate_upper_args)
@@ -5404,7 +5426,24 @@
 
     def mutate(self, visitor):
         self.body = self.body.mutate(visitor)
-        self.handlers[:] = [n.mutate(visitor) for n in self.handlers]
+        newhandlers = []
+
+        for expr1, expr2, body in self.handlers:
+
+            if expr1 is not None:
+
+                newhandlers.append(expr1.mutate(visitor))
+
+            if expr2 is not None:
+
+                newhandlers.append(expr2.mutate(visitor))
+
+            if body is not None:
+
+                newhandlers.append(body.mutate(visitor))
+
+        self.handlers[:] = newhandlers
+
         if self.else_ is not None:
             self.else_ = self.else_.mutate(visitor)
         return visitor.visitTryExcept(self)
@@ -5437,7 +5476,7 @@
     self.else_ = space.interp_w(Node, w_else_, can_be_None=True)
     self.lineno = lineno
     return space.wrap(self)
-    
+
 
 
 def descr_TryExcept_accept( space, w_self, w_visitor):
@@ -5445,7 +5484,7 @@
     args = Arguments(space, [ w_self ])
     return space.call_args(w_callable, args)
 
-def descr_TryExcept_mutate(space, w_self, w_visitor): 
+def descr_TryExcept_mutate(space, w_self, w_visitor):
     w_body = space.getattr(w_self, space.wrap("body"))
     w_mutate_body = space.getattr(w_body, space.wrap("mutate"))
     w_mutate_body_args = Arguments(space, [ w_visitor ])
@@ -5456,14 +5495,34 @@
     list_w = space.unpackiterable(w_list)
     newlist_w = []
     for w_item in list_w:
-        w_item_mutate = space.getattr(w_item, space.wrap("mutate"))
-        w_item_mutate_args = Arguments(space, [ w_visitor ])
-        w_newitem = space.call_args(w_item_mutate, w_item_mutate_args)
-        newlist_w.append(w_newitem)
+        w_expr1, w_expr2, w_body = space.unpackiterable(w_item, 3)
+
+        if space.is_w(w_expr1, space.w_None):
+            w_newexpr1 = w_expr1
+        else:
+            w_expr1_mutate = space.getattr(w_expr1, space.wrap("mutate"))
+            w_expr1_mutate_args = Arguments(space, [ w_visitor ])
+            w_newexpr1 = space.call_args(w_expr1_mutate, w_expr1_mutate_args)
+        
+        if space.is_w(w_expr2, space.w_None):
+            w_newexpr2 = w_expr2
+        else:
+            w_expr2_mutate = space.getattr(w_expr2, space.wrap("mutate"))
+            w_expr2_mutate_args = Arguments(space, [ w_visitor ])
+            w_newexpr2 = space.call_args(w_expr2_mutate, w_expr2_mutate_args)
+
+        if space.is_w(w_body, space.w_None):
+            w_newbody = w_body
+        else:
+            w_body_mutate = space.getattr(w_body, space.wrap("mutate"))
+            w_body_mutate_args = Arguments(space, [ w_visitor ])
+            w_newbody = space.call_args(w_body_mutate, w_body_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_newexpr1, w_newexpr2, w_newbody]))
     w_newlist = space.newlist(newlist_w)
     space.setslice(w_list, space.w_None, space.w_None, w_newlist)
     w_else_ = space.getattr(w_self, space.wrap("else_"))
-    if space.is_w(w_else_, space.w_None):
+    if not space.is_w(w_else_, space.w_None):
         w_mutate_else_ = space.getattr(w_else_, space.wrap("mutate"))
         w_mutate_else__args = Arguments(space, [ w_visitor ])
         w_new_else_ = space.call_args(w_mutate_else_, w_mutate_else__args)
@@ -5473,6 +5532,7 @@
     w_visitTryExcept_args = Arguments(space, [ w_self ])
     return space.call_args(w_visitTryExcept, w_visitTryExcept_args)
 
+
 TryExcept.typedef = TypeDef('TryExcept', Node.typedef, 
                      __new__ = interp2app(descr_TryExcept_new, unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root, W_Root, int]),
                      accept=interp2app(descr_TryExcept_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] ),
@@ -5815,7 +5875,7 @@
     space.setattr(w_self, space.wrap("body"), w_new_body)
 
     w_else_ = space.getattr(w_self, space.wrap("else_"))
-    if space.is_w(w_else_, space.w_None):
+    if not space.is_w(w_else_, space.w_None):
         w_mutate_else_ = space.getattr(w_else_, space.wrap("mutate"))
         w_mutate_else__args = Arguments(space, [ w_visitor ])
         w_new_else_ = space.call_args(w_mutate_else_, w_mutate_else__args)
@@ -5916,7 +5976,7 @@
     space.setattr(w_self, space.wrap("body"), w_new_body)
 
     w_var = space.getattr(w_self, space.wrap("var"))
-    if space.is_w(w_var, space.w_None):
+    if not space.is_w(w_var, space.w_None):
         w_mutate_var = space.getattr(w_var, space.wrap("mutate"))
         w_mutate_var_args = Arguments(space, [ w_visitor ])
         w_new_var = space.call_args(w_mutate_var, w_mutate_var_args)

Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/ast.txt	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/ast.txt	Sat Jul  8 13:59:37 2006
@@ -1,5 +1,5 @@
 # This file describes the nodes of the AST in ast.py.  The module is
-# generated by astgen.py.  
+# generated by astgen.py.
 # The descriptions use the following special notation to describe
 # properties of the children:
 
@@ -23,9 +23,9 @@
 Function(AbstractFunction): decorators&, name*str, argnames!, defaults!, flags*int, w_doc%, code
 Lambda(AbstractFunction): argnames!, defaults!, flags*int, code
 Class: name*str, bases!, w_doc%, code
-Pass: 
-Break: 
-Continue: 
+Pass:
+Break:
+Continue:
 For: assign, list, body, else_&
 With: expr, body, var&
 While: test, body, else_&
@@ -55,7 +55,7 @@
 ListComp: expr, quals!
 ListCompFor: assign, list, ifs!
 ListCompIf: test
-GenExpr(AbstractFunction): code 
+GenExpr(AbstractFunction): code
 GenExprInner: expr, quals!
 GenExprFor: assign, iter, ifs!
 GenExprIf: test
@@ -71,7 +71,7 @@
 CallFunc: node, args!, star_args& = None, dstar_args& = None
 Keyword: name*str, expr
 Subscript: expr, flags*int, sub
-Ellipsis: 
+Ellipsis:
 Sliceobj: nodes!
 Slice: expr, flags*int, lower&, upper&
 Assert: test, fail&
@@ -126,6 +126,9 @@
     for op_name, node in self.ops:
         nodelist.append(node)
 
+mutate(Compare.ops):
+    self.ops[:] = [(op_name, node.mutate(visitor)) for (op_name, node) in self.ops]
+
 flatten_nodes(TryExcept.handlers):
     # handlers is a list of triplets (expr1, expr2, body)
     for expr1, expr2, body in self.handlers:
@@ -136,18 +139,35 @@
         if body is not None:
             nodelist.append(body)
 
+mutate(TryExcept.handlers):
+    newhandlers = []
+    for expr1, expr2, body in self.handlers:
+        if expr1 is not None:
+            newhandlers.append(expr1.mutate(visitor))
+        if expr2 is not None:
+            newhandlers.append(expr2.mutate(visitor))
+        if body is not None:
+            newhandlers.append(body.mutate(visitor))
+    self.handlers[:] = newhandlers
+
 flatten_nodes(Dict.items):
     # items is a list of couples (node (key), node (value))
     for key, value in self.items:
         nodelist.append(key)
         nodelist.append(value)
 
+mutate(Dict.items):
+    self.items[:] = [(n.mutate(visitor), o.mutate(visitor)) for (n, o) in self.items]
+
 flatten_nodes(If.tests):
     # tests is a list of couples (node (test), node (suite))
     for test, suite in self.tests:
         nodelist.append(test)
         nodelist.append(suite)
 
+mutate(If.tests):
+    self.tests[:] = [(n.mutate(visitor), o.mutate(visitor)) for (n, o) in self.tests]
+
 AssTuple.getArgNames(self):
     argnames = []
     for node in self.nodes:
@@ -229,7 +249,7 @@
 Import.fset_names( space, self, w_arg ):
     del self.names[:]
     for w_tup in space.unpackiterable( w_arg ):
-        w_name = space.getitem( w_tup, space.wrap(0) ) 
+        w_name = space.getitem( w_tup, space.wrap(0) )
         w_as_name = space.getitem( w_tup, space.wrap(1) )
         name = space.str_w( w_name )
         as_name = None
@@ -244,7 +264,7 @@
 From.fset_names( space, self, w_arg ):
     del self.names[:]
     for w_tup in space.unpackiterable( w_arg ):
-        w_name = space.getitem( w_tup, space.wrap(0) ) 
+        w_name = space.getitem( w_tup, space.wrap(0) )
         w_as_name = space.getitem( w_tup, space.wrap(1) )
         name = space.str_w( w_name )
         as_name = None
@@ -283,7 +303,7 @@
     self.names = names
     self.lineno = lineno
     return space.wrap(self)
-    
+
 def descr_Compare_new(space, w_subtype, w_expr, w_ops, lineno=-1):
     self = space.allocate_instance(Compare, w_subtype)
     self.expr = space.interp_w(Node, w_expr)
@@ -297,7 +317,32 @@
     self.ops = ops
     self.lineno = lineno
     return space.wrap(self)
-    
+
+def descr_Compare_mutate(space, w_self, w_visitor): 
+    w_expr = space.getattr(w_self, space.wrap("expr"))
+    w_mutate_expr = space.getattr(w_expr, space.wrap("mutate"))
+    w_mutate_expr_args = Arguments(space, [ w_visitor ])
+    w_new_expr = space.call_args(w_mutate_expr, w_mutate_expr_args)
+    space.setattr(w_self, space.wrap("expr"), w_new_expr)
+
+    w_list = space.getattr(w_self, space.wrap("ops"))
+    list_w = space.unpackiterable(w_list)
+    newlist_w = []
+    for w_item in list_w:
+        w_opname, w_node = space.unpackiterable(w_item, 2)
+        
+        w_node_mutate = space.getattr(w_node, space.wrap("mutate"))
+        w_node_mutate_args = Arguments(space, [ w_visitor ])
+        w_newnode = space.call_args(w_node_mutate, w_node_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_opname, w_newnode]))
+    w_newlist = space.newlist(newlist_w)
+    space.setslice(w_list, space.w_None, space.w_None, w_newlist)
+    w_visitCompare = space.getattr(w_visitor, space.wrap("visitCompare"))
+    w_visitCompare_args = Arguments(space, [ w_self ])
+    return space.call_args(w_visitCompare, w_visitCompare_args)
+
+
 def descr_Dict_new(space, w_subtype, w_items, lineno=-1):
     self = space.allocate_instance(Dict, w_subtype)
     items = []
@@ -310,7 +355,28 @@
     self.items = items
     self.lineno = lineno
     return space.wrap(self)
-    
+
+def descr_Dict_mutate(space, w_self, w_visitor): 
+    w_list = space.getattr(w_self, space.wrap("items"))
+    list_w = space.unpackiterable(w_list)
+    newlist_w = []
+    for w_item in list_w:
+        w_key, w_value = space.unpackiterable(w_item, 2)
+        
+        w_key_mutate = space.getattr(w_key, space.wrap("mutate"))
+        w_key_mutate_args = Arguments(space, [ w_visitor ])
+        w_newkey = space.call_args(w_key_mutate, w_key_mutate_args)
+
+        w_value_mutate = space.getattr(w_value, space.wrap("mutate"))
+        w_value_mutate_args = Arguments(space, [ w_visitor ])
+        w_newvalue = space.call_args(w_value_mutate, w_value_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_newkey, w_newvalue]))
+    w_newlist = space.newlist(newlist_w)
+    space.setslice(w_list, space.w_None, space.w_None, w_newlist)
+    w_visitDict = space.getattr(w_visitor, space.wrap("visitDict"))
+    w_visitDict_args = Arguments(space, [ w_self ])
+    return space.call_args(w_visitDict, w_visitDict_args)
 
 def descr_If_new(space, w_subtype, w_tests, w_else_, lineno=-1):
     self = space.allocate_instance(If, w_subtype)
@@ -325,7 +391,32 @@
     self.else_ = space.interp_w(Node, w_else_, can_be_None=True)
     self.lineno = lineno
     return space.wrap(self)
+
+def descr_If_mutate(space, w_self, w_visitor):
+    w_list = space.getattr(w_self, space.wrap("tests"))
+    list_w = space.unpackiterable(w_list)
+    newlist_w = []
+    for w_item in list_w:
+        w_test, w_suite = space.unpackiterable(w_item, 2)
+
+        w_test_mutate = space.getattr(w_test, space.wrap("mutate"))
+        w_test_mutate_args = Arguments(space, [ w_visitor ])
+        w_newtest = space.call_args(w_test_mutate, w_test_mutate_args)
+
+        w_suite_mutate = space.getattr(w_suite, space.wrap("mutate"))
+        w_suite_mutate_args = Arguments(space, [ w_visitor ])
+        w_newsuite = space.call_args(w_suite_mutate, w_suite_mutate_args)
+        newlist_w.append(space.newtuple([w_newtest, w_newsuite]))
     
+    w_newlist = space.newlist(newlist_w)
+    space.setslice(w_list, space.w_None, space.w_None, w_newlist)
+    w_else_ = space.getattr(w_self, space.wrap("else_"))
+    if not space.is_w(w_else_, space.w_None):
+        w_mutate_else_ = space.getattr(w_else_, space.wrap("mutate"))
+        w_mutate_else__args = Arguments(space, [ w_visitor ])
+        w_new_else_ = space.call_args(w_mutate_else_, w_mutate_else__args)
+        space.setattr(w_self, space.wrap("else_"), w_new_else_)
+
 
 def descr_TryExcept_new(space, w_subtype, w_body, w_handlers, w_else_, lineno=-1):
     self = space.allocate_instance(TryExcept, w_subtype)
@@ -343,4 +434,51 @@
     self.else_ = space.interp_w(Node, w_else_, can_be_None=True)
     self.lineno = lineno
     return space.wrap(self)
-    
+
+def descr_TryExcept_mutate(space, w_self, w_visitor): 
+    w_body = space.getattr(w_self, space.wrap("body"))
+    w_mutate_body = space.getattr(w_body, space.wrap("mutate"))
+    w_mutate_body_args = Arguments(space, [ w_visitor ])
+    w_new_body = space.call_args(w_mutate_body, w_mutate_body_args)
+    space.setattr(w_self, space.wrap("body"), w_new_body)
+
+    w_list = space.getattr(w_self, space.wrap("handlers"))
+    list_w = space.unpackiterable(w_list)
+    newlist_w = []
+    for w_item in list_w:
+        w_expr1, w_expr2, w_body = space.unpackiterable(w_item, 3)
+
+        if space.is_w(w_expr1, space.w_None):
+            w_newexpr1 = w_expr1
+        else:
+            w_expr1_mutate = space.getattr(w_expr1, space.wrap("mutate"))
+            w_expr1_mutate_args = Arguments(space, [ w_visitor ])
+            w_newexpr1 = space.call_args(w_expr1_mutate, w_expr1_mutate_args)
+        
+        if space.is_w(w_expr2, space.w_None):
+            w_newexpr2 = w_expr2
+        else:
+            w_expr2_mutate = space.getattr(w_expr2, space.wrap("mutate"))
+            w_expr2_mutate_args = Arguments(space, [ w_visitor ])
+            w_newexpr2 = space.call_args(w_expr2_mutate, w_expr2_mutate_args)
+
+        if space.is_w(w_body, space.w_None):
+            w_newbody = w_body
+        else:
+            w_body_mutate = space.getattr(w_body, space.wrap("mutate"))
+            w_body_mutate_args = Arguments(space, [ w_visitor ])
+            w_newbody = space.call_args(w_body_mutate, w_body_mutate_args)
+        
+        newlist_w.append(space.newtuple([w_newexpr1, w_newexpr2, w_newbody]))
+    w_newlist = space.newlist(newlist_w)
+    space.setslice(w_list, space.w_None, space.w_None, w_newlist)
+    w_else_ = space.getattr(w_self, space.wrap("else_"))
+    if not space.is_w(w_else_, space.w_None):
+        w_mutate_else_ = space.getattr(w_else_, space.wrap("mutate"))
+        w_mutate_else__args = Arguments(space, [ w_visitor ])
+        w_new_else_ = space.call_args(w_mutate_else_, w_mutate_else__args)
+        space.setattr(w_self, space.wrap("else_"), w_new_else_)
+
+    w_visitTryExcept = space.getattr(w_visitor, space.wrap("visitTryExcept"))
+    w_visitTryExcept_args = Arguments(space, [ w_self ])
+    return space.call_args(w_visitTryExcept, w_visitTryExcept_args)

Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/astgen.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/astgen.py	Sat Jul  8 13:59:37 2006
@@ -46,7 +46,9 @@
         self.nargs = len(self.argnames)
         self.init = []
         self.applevel_new = []
+        self.applevel_mutate = []
         self.flatten_nodes = {}
+        self.mutate_nodes = {}
         self.additional_methods = {}
         self.parent = parent
 
@@ -299,7 +301,11 @@
         print >> buf, "    def mutate(self, visitor):"
         if len(self.argnames) != 0:
             for argname in self.argnames:
-                if self.argprops[argname] == P_NODE:
+                if argname in self.mutate_nodes:
+                    for line in self.mutate_nodes[argname]:
+                        if line.strip():
+                            print >> buf, '    ' + line
+                elif self.argprops[argname] == P_NODE:
                     print >> buf, "        self.%s = self.%s.mutate(visitor)" % (argname,argname)
                 elif self.argprops[argname] == P_NONE:
                     print >> buf, "        if self.%s is not None:" % (argname,)
@@ -360,28 +366,17 @@
             if "fset_%s" % attr not in self.additional_methods:
                 self._gen_fset_func( buf, attr, prop )
 
-    def _gen_typedef(self, buf):
-        initargs = [strip_default(arg.strip())
-                    for arg in self.get_initargs().split(',') if arg]
-        if initargs:
-            new_unwrap_spec = ['ObjSpace', 'W_Root'] + ['W_Root'] * len(initargs) + ['int']
-        else:
-            new_unwrap_spec = ['ObjSpace', 'W_Root', 'int']
-        parent_type = "%s.typedef" % self.parent.name
-        print >> buf, "def descr_%s_accept( space, w_self, w_visitor):" %self.name
-        print >> buf, "    w_callable = space.getattr(w_visitor, space.wrap('visit%s'))" % self.name
-        print >> buf, "    args = Arguments(space, [ w_self ])"
-        print >> buf, "    return space.call_args(w_callable, args)"
-
-        print >> buf, ""
-        # mutate stuff
+    def _gen_descr_mutate(self, buf):
+        if self.applevel_mutate:
+            print >> buf, ''.join(self.applevel_mutate)
+            return
         print >> buf, "def descr_%s_mutate(space, w_self, w_visitor): " % self.name
         for argname in self.argnames:
             if self.argprops[argname] in [P_NODE, P_NONE]:
                 print >> buf, '    w_%s = space.getattr(w_self, space.wrap("%s"))' % (argname,argname)
                 if self.argprops[argname] == P_NONE:
                     indent = '    '
-                    print >> buf, '    if space.is_w(w_%s, space.w_None):' % (argname,)
+                    print >> buf, '    if not space.is_w(w_%s, space.w_None):' % (argname,)
                 else:
                     indent = ''
                 print >> buf, indent+'    w_mutate_%s = space.getattr(w_%s, space.wrap("mutate"))' % ( argname,
@@ -411,8 +406,26 @@
         print >> buf, "    w_visit%s_args = Arguments(space, [ w_self ])" % self.name
         print >> buf, "    return space.call_args(w_visit%s, w_visit%s_args)" % (self.name,
                                                                              self.name )
+        
+
+    def _gen_typedef(self, buf):
+        initargs = [strip_default(arg.strip())
+                    for arg in self.get_initargs().split(',') if arg]
+        if initargs:
+            new_unwrap_spec = ['ObjSpace', 'W_Root'] + ['W_Root'] * len(initargs) + ['int']
+        else:
+            new_unwrap_spec = ['ObjSpace', 'W_Root', 'int']
+        parent_type = "%s.typedef" % self.parent.name
+        print >> buf, "def descr_%s_accept( space, w_self, w_visitor):" %self.name
+        print >> buf, "    w_callable = space.getattr(w_visitor, space.wrap('visit%s'))" % self.name
+        print >> buf, "    args = Arguments(space, [ w_self ])"
+        print >> buf, "    return space.call_args(w_callable, args)"
 
         print >> buf, ""
+        # mutate stuff
+        self._gen_descr_mutate(buf)
+        
+        print >> buf, ""
         print >> buf, "%s.typedef = TypeDef('%s', %s, " % (self.name, self.name, parent_type)
         print >> buf, "                     __new__ = interp2app(descr_%s_new, unwrap_spec=[%s])," % (self.name, ', '.join(new_unwrap_spec))
         print >> buf, "                     accept=interp2app(descr_%s_accept, unwrap_spec=[ObjSpace, W_Root, W_Root] )," % self.name
@@ -457,6 +470,8 @@
 rx_flatten_nodes = re.compile('flatten_nodes\((.*)\.(.*)\):')
 rx_additional_methods = re.compile('(\\w+)\.(\w+)\((.*?)\):')
 rx_descr_news_methods = re.compile('def\s+descr_(\\w+)_new\((.*?)\):')
+rx_descr_mutate_methods = re.compile('def\s+descr_(\\w+)_mutate\((.*?)\):')
+rx_mutate = re.compile('mutate\((.*)\.(.*)\):')
 def parse_spec(file):
     classes = {}
     cur = None
@@ -503,6 +518,17 @@
             flatten_expect_comment = True
             continue
 
+        mo = rx_mutate.match(line)
+        if mo:
+            kind = 'mutate'
+            # special case for getChildNodes flattening
+            name = mo.group(1)
+            attr = mo.group(2)
+            cur = classes[name]
+            _cur_ = attr
+            cur.mutate_nodes[attr] = []
+            continue
+
         mo = rx_additional_methods.match(line)
         if mo:
             kind = 'additional_method'
@@ -522,6 +548,14 @@
             cur.applevel_new = [mo.group(0) + '\n']
             continue
 
+        mo = rx_descr_mutate_methods.match(line)
+        if mo:
+            kind = 'applevel_mutate'
+            name = mo.group(1)
+            cur = classes[name]
+            cur.applevel_mutate = [mo.group(0) + '\n']
+            continue
+
         if kind == 'init':
             # some code for the __init__ method
             cur.init.append(line)
@@ -530,10 +564,14 @@
                 assert line.strip().startswith("#")
                 flatten_expect_comment=False
             cur.flatten_nodes[_cur_].append(line)
+        elif kind == 'mutate':
+            cur.mutate_nodes[_cur_].append(line)
         elif kind == 'additional_method':
             cur.additional_methods[_cur_].append(' '*4 + line)
         elif kind == 'applevel_new':
             cur.applevel_new.append(line)
+        elif kind == 'applevel_mutate':
+            cur.applevel_mutate.append(line)
             
     for node in classes.values():
         node.setup_parent(classes)

Modified: pypy/dist/pypy/interpreter/astcompiler/test/test_ast.py
==============================================================================
--- pypy/dist/pypy/interpreter/astcompiler/test/test_ast.py	(original)
+++ pypy/dist/pypy/interpreter/astcompiler/test/test_ast.py	Sat Jul  8 13:59:37 2006
@@ -1,4 +1,17 @@
 from pypy.interpreter.astcompiler import ast#_temp as ast
+from pypy.module.recparser.pyparser import source2ast
+from pypy.interpreter.pyparser.test.test_astbuilder import FakeSpace
+
+class BaseVisitor:
+    def __getattr__(self, attr):
+        if attr.startswith('visit'):
+            return self.default
+        else:
+            raise AttributeError(attr)
+    def default(self, node):
+        return node
+    def visitAdd(self, node):
+        return ast.Const(3)
 
 class TestMutate:
 
@@ -6,19 +19,35 @@
         c1 = ast.Const(1)
         c2 = ast.Const(2)
         add = ast.Add(c1, c2)
-        class Visitor:
-            def __getattr__(self, attr):
-                if attr.startswith('visit'):
-                    return self.default
-                else:
-                    raise AttributeError(attr)
-            def default(self, node):
-                return node
+        class Visitor(BaseVisitor):
             def visitAdd(self, node):
                 return ast.Const(3)
         c3 = add.mutate(Visitor())
         assert isinstance(c3, ast.Const)
 
+    def test_mutate_strange_cases(self):
+        src = '''
+if a:
+    b
+        '''
+        ast = source2ast(FakeSpace(), src)
+        ast.mutate(BaseVisitor())
+        src = '''
+try:
+    b
+except Exception:
+    pass
+        '''
+        ast = source2ast(FakeSpace(), src)
+        ast.mutate(BaseVisitor())
+        src = '{1:2}'
+        ast = source2ast(FakeSpace(), src)
+        ast.mutate(BaseVisitor())
+        src = '1 > 3'
+        ast = source2ast(FakeSpace(), src)
+        ast.mutate(BaseVisitor())
+         
+
 class AppTestMutate:
     def test_mutate_add(self):
         import parser
@@ -37,3 +66,34 @@
                 return parser.ASTConst(3)
         c3 = add.mutate(Visitor())
         assert isinstance(c3, parser.ASTConst)
+
+    def test_mutate_strange_cases(self):
+        import parser
+        class BaseVisitor:
+            def __getattr__(self, attr):
+                if attr.startswith('visit'):
+                    return self.default
+                else:
+                    raise AttributeError(attr)
+            def default(self, node):
+                return node
+        ast = parser.source2ast('if a: b')
+        ast.mutate(BaseVisitor())
+        
+        src = '''
+try:
+    b
+except Exception:
+    pass
+        '''
+        ast = parser.source2ast(src)
+        ast.mutate(BaseVisitor())
+
+        src = '{1:2}'
+        ast = parser.source2ast(src)
+        ast.mutate(BaseVisitor())
+
+        src = '1 > 3'
+        ast = parser.source2ast(src)
+        ast.mutate(BaseVisitor())
+        



More information about the Pypy-commit mailing list