yield statement and expression support (dummy)
authorStefan Behnel <scoder@users.berlios.de>
Tue, 17 Nov 2009 08:13:18 +0000 (09:13 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Tue, 17 Nov 2009 08:13:18 +0000 (09:13 +0100)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Parsing.py

index d20e0419e2e1967d6f8218963a284093bb2230ca..a3e7b9fec3306c6f8dc363a00703ec6f4845db94 100644 (file)
@@ -4030,6 +4030,32 @@ class LambdaNode(InnerFunctionNode):
         self.pymethdef_cname = self.def_node.entry.pymethdef_cname
         env.add_lambda_def(self.def_node)
 
+class YieldExprNode(ExprNode):
+    # Yield expression node
+    #
+    # arg         ExprNode   the value to return from the generator
+    # label_name  string     name of the C label used for this yield
+
+    subexprs = []
+    type = py_object_type
+
+    def analyse_types(self, env):
+        self.is_temp = 1
+        if self.arg is not None:
+            self.arg.analyse_types(env)
+            if not self.arg.type.is_pyobject:
+                self.arg = self.arg.coerce_to_pyobject(env)
+
+    def generate_result_code(self, code):
+        self.label_name = code.new_label('resume_from_yield')
+        code.use_label(self.label_name)
+        code.putln("/* FIXME: save temporary variables */")
+        code.putln("/* FIXME: return from function, yielding value */")
+        code.put_label(self.label_name)
+        code.putln("/* FIXME: restore temporary variables and  */")
+        code.putln("/* FIXME: extract sent value from closure */")
+
+
 #-------------------------------------------------------------------
 #
 #  Unary operator nodes
index 962186184df338fe293ac709af14bebaca145ca3..ddad09ae3677fbce2093e35b8350e9234aa1303f 100644 (file)
@@ -329,10 +329,16 @@ def p_yield_expression(s):
     # s.sy == "yield"
     pos = s.position()
     s.next()
-    if s.sy not in ('EOF', 'NEWLINE', ')'):
-        expr = p_expr(s)
-    s.error("generators ('yield') are not currently supported")
-    return Nodes.PassStatNode(pos)
+    if s.sy != ')' and s.sy not in statement_terminators:
+        arg = p_expr(s)
+    else:
+        arg = None
+    return ExprNodes.YieldExprNode(pos, arg=arg)
+
+def p_yield_statement(s):
+    # s.sy == "yield"
+    yield_expr = p_yield_expression(s)
+    return Nodes.ExprStatNode(yield_expr.pos, expr=yield_expr)
 
 #power: atom trailer* ('**' factor)*
 
@@ -1533,7 +1539,7 @@ def p_simple_statement(s, first_statement = 0):
     elif s.sy == 'from':
         node = p_from_import_statement(s, first_statement = first_statement)
     elif s.sy == 'yield':
-        node = p_yield_expression(s)
+        node = p_yield_statement(s)
     elif s.sy == 'assert':
         node = p_assert_statement(s)
     elif s.sy == 'pass':