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
# 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)*
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':