private Expression ParseLambdaHelperEnd(FunctionDefinition func, Expression expr) { // Pep 342 in Python 2.5 allows Yield Expressions, which can occur inside a Lambda body. // In this case, the lambda is a generator and will yield it's final result instead of just return it. Statement body; if (func.IsGenerator) { YieldExpression y = new YieldExpression(expr); y.SetLoc(_globalParent, expr.IndexSpan); body = new ExpressionStatement(y); } else { body = new ReturnStatement(expr); } body.SetLoc(_globalParent, expr.StartIndex, expr.EndIndex); FunctionDefinition func2 = PopFunction(); System.Diagnostics.Debug.Assert(func == func2); func.Body = body; func.EndIndex = GetEnd(); LambdaExpression ret = new LambdaExpression(func); func.SetLoc(_globalParent, func.IndexSpan); ret.SetLoc(_globalParent, func.IndexSpan); return ret; }
/// <summary> /// Peek if the next token is a 'yield' and parse a yield expression. Else return null. /// /// Called w/ yield already eaten. /// </summary> /// <returns>A yield expression if present, else null. </returns> // yield_expression: "yield" [expression_list] private Expression ParseYieldExpression() { // Mark that this function is actually a generator. // If we're in a generator expression, then we don't have a function yet. // g=((yield i) for i in range(5)) // In that acse, the genexp will mark IsGenerator. FunctionDefinition current = CurrentFunction; if (current != null) { current.IsGenerator = true; } var start = GetStart(); // Parse expression list after yield. This can be: // 1) empty, in which case it becomes 'yield None' // 2) a single expression // 3) multiple expression, in which case it's wrapped in a tuple. Expression yieldResult; bool trailingComma; List<Expression> l = ParseExpressionList(out trailingComma); if (l.Count == 0) { // Check empty expression and convert to 'none' yieldResult = new ConstantExpression(null); } else if (l.Count != 1) { // make a tuple yieldResult = MakeTupleOrExpr(l, trailingComma); } else { // just take the single expression yieldResult = l[0]; } Expression yieldExpression = new YieldExpression(yieldResult); yieldExpression.SetLoc(_globalParent, start, GetEnd()); return yieldExpression; }
/// <summary> /// Peek if the next token is a 'yield' and parse a yield expression. Else return null. /// /// Called w/ yield already eaten. /// </summary> /// <returns>A yield expression if present, else null. </returns> // yield_expression: "yield" [expression_list] private Expression ParseYieldExpression() { // Mark that this function is actually a generator. // If we're in a generator expression, then we don't have a function yet. // g=((yield i) for i in range(5)) // In that acse, the genexp will mark IsGenerator. FunctionDefinition current = CurrentFunction; if (current != null) { current.IsGenerator = true; } SourceLocation start = GetStart(); // Parse expression list after yield. This can be: // 1) empty, in which case it becomes 'yield None' // 2) a single expression // 3) multiple expression, in which case it's wrapped in a tuple. const bool allowEmptyExpr = true; Expression yieldResult = ParseTestListAsExpr(allowEmptyExpr); // Check empty expression and convert to 'none' TupleExpression t = yieldResult as TupleExpression; if (t != null) { if (t.Items.Length == 0) { yieldResult = new ConstantExpression(null); } } Expression yieldExpression = new YieldExpression(yieldResult); yieldExpression.SetLoc(start, GetEnd()); return yieldExpression; }