[pypy-svn] r56355 - in pypy/branch/2.5-features/pypy/interpreter: . astcompiler pyparser test

bgola at codespeak.net bgola at codespeak.net
Mon Jul 7 16:56:46 CEST 2008


Author: bgola
Date: Mon Jul  7 16:56:45 2008
New Revision: 56355

Modified:
   pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py
   pypy/branch/2.5-features/pypy/interpreter/astcompiler/pycodegen.py
   pypy/branch/2.5-features/pypy/interpreter/generator.py
   pypy/branch/2.5-features/pypy/interpreter/pyparser/astbuilder.py
   pypy/branch/2.5-features/pypy/interpreter/test/test_generator.py
   pypy/branch/2.5-features/pypy/interpreter/typedef.py
Log:
Supporting part of pep-342, generator stuff (.send()). Things may be broken now because of the current default magic number (see execute_generator_frame() in pyframe.py).

Modified: pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py	(original)
+++ pypy/branch/2.5-features/pypy/interpreter/astcompiler/pyassem.py	Mon Jul  7 16:56:45 2008
@@ -519,7 +519,7 @@
         'PRINT_ITEM_TO': -2,
         'PRINT_NEWLINE': 0,
         'PRINT_NEWLINE_TO': -1,
-        'YIELD_VALUE': -1,
+        'YIELD_VALUE': 0,
         'EXEC_STMT': -3,
         'BUILD_CLASS': -2,
         'STORE_NAME': -1,

Modified: pypy/branch/2.5-features/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/branch/2.5-features/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/branch/2.5-features/pypy/interpreter/astcompiler/pycodegen.py	Mon Jul  7 16:56:45 2008
@@ -695,6 +695,7 @@
 
         node.expr.accept( self )
         self.emit('YIELD_VALUE')
+        self.emit('POP_TOP')
 
         for start, cont, anchor in stack:
             if cont:

Modified: pypy/branch/2.5-features/pypy/interpreter/generator.py
==============================================================================
--- pypy/branch/2.5-features/pypy/interpreter/generator.py	(original)
+++ pypy/branch/2.5-features/pypy/interpreter/generator.py	Mon Jul  7 16:56:45 2008
@@ -28,18 +28,26 @@
         """x.__iter__() <==> iter(x)"""
         return self.space.wrap(self)
 
-    def descr_next(self):
-        """x.next() -> the next value, or raise StopIteration"""
+    def descr_send(self, w_arg=None):
+        """send(arg) -> send 'arg' into generator,
+return next yielded value or raise StopIteration."""
         space = self.space
         if self.running:
             raise OperationError(space.w_ValueError,
                                  space.wrap('generator already executing'))
         if self.frame.frame_finished_execution:
-            raise OperationError(space.w_StopIteration, space.w_None) 
+            raise OperationError(space.w_StopIteration, space.w_None)
+        if self.frame.last_instr == -1:
+            if w_arg and not space.is_w(w_arg, space.w_None):
+                msg = "can't send non-None value to a just-started generator"
+                raise OperationError(space.w_TypeError, space.wrap(msg))
+        else:
+            if not w_arg:
+                w_arg = space.w_None
         self.running = True
         try:
             try:
-                w_result = self.frame.execute_generator_frame(space.w_None)
+                w_result = self.frame.execute_generator_frame(w_arg)
             except OperationError:
                 # errors finish a frame
                 self.frame.frame_finished_execution = True
@@ -52,3 +60,9 @@
         finally:
             self.frame.f_back = None
             self.running = False
+
+    def descr_next(self):
+        """x.next() -> the next value, or raise StopIteration"""
+        return self.descr_send()
+ 
+

Modified: pypy/branch/2.5-features/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/branch/2.5-features/pypy/interpreter/pyparser/astbuilder.py	(original)
+++ pypy/branch/2.5-features/pypy/interpreter/pyparser/astbuilder.py	Mon Jul  7 16:56:45 2008
@@ -880,6 +880,11 @@
 
 def build_yield_stmt(builder, nb):
     atoms = get_atoms(builder, nb)
+    lineno = atoms[0].lineno
+    builder.push(ast.Discard(ast.Yield(atoms[1], lineno), lineno))
+
+def build_yield_expr(builder, nb):
+    atoms = get_atoms(builder, nb)
     builder.push(ast.Yield(atoms[1], atoms[0].lineno))
 
 def build_continue_stmt(builder, nb):
@@ -1038,6 +1043,7 @@
     'import_name' : build_import_name,
     'import_from' : build_import_from,
     'yield_stmt' : build_yield_stmt,
+    'yield_expr' : build_yield_expr,
     'continue_stmt' : build_continue_stmt,
     'del_stmt' : build_del_stmt,
     'assert_stmt' : build_assert_stmt,

Modified: pypy/branch/2.5-features/pypy/interpreter/test/test_generator.py
==============================================================================
--- pypy/branch/2.5-features/pypy/interpreter/test/test_generator.py	(original)
+++ pypy/branch/2.5-features/pypy/interpreter/test/test_generator.py	Mon Jul  7 16:56:45 2008
@@ -26,6 +26,14 @@
         g = f()
         assert [x for x in g] == [1]
 
+    def test_generator5(self):
+        def f():
+            v = (yield )
+            yield v
+        g = f()
+        g.next()
+        assert g.send(42) == 42
+
     def test_generator_explicit_stopiteration(self):
         def f():
             yield 1

Modified: pypy/branch/2.5-features/pypy/interpreter/typedef.py
==============================================================================
--- pypy/branch/2.5-features/pypy/interpreter/typedef.py	(original)
+++ pypy/branch/2.5-features/pypy/interpreter/typedef.py	Mon Jul  7 16:56:45 2008
@@ -817,6 +817,8 @@
                               unwrap_spec=['self', ObjSpace]),
     next       = interp2app(GeneratorIterator.descr_next,
                             descrmismatch='next'),
+    send       = interp2app(GeneratorIterator.descr_send,
+                            descrmismatch='send'),
     __iter__   = interp2app(GeneratorIterator.descr__iter__,
                             descrmismatch='__iter__'),
     gi_running = interp_attrproperty('running', cls=GeneratorIterator),



More information about the Pypy-commit mailing list