예제 #1
0
파일: Parser.cs 프로젝트: omnimark/PTVS
        private Expression ParseLambdaHelperEnd(FunctionDefinition func, Expression expr, string whitespace, string colonWhiteSpace, List<string> commaWhiteSpace, bool ateTerminator) {
            // 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(expr.IndexSpan);
                body = new ExpressionStatement(y);
            } else {
                body = new ReturnStatement(expr);
            }
            body.SetLoc(expr.StartIndex, expr.EndIndex);

            FunctionDefinition func2 = PopFunction();
            System.Diagnostics.Debug.Assert(func == func2);

            func.SetBody(body);
            func.EndIndex = GetEnd();

            LambdaExpression ret = new LambdaExpression(func);
            func.SetLoc(func.IndexSpan);
            ret.SetLoc(func.IndexSpan);
            if (_verbatim) {
                AddPreceedingWhiteSpace(ret, whitespace);
                AddSecondPreceedingWhiteSpace(ret, colonWhiteSpace);
                AddListWhiteSpace(ret, commaWhiteSpace.ToArray());
                if (!ateTerminator) {
                    AddErrorIsIncompleteNode(ret);
                }
            }
            return ret;
        }
예제 #2
0
파일: Parser.cs 프로젝트: omnimark/PTVS
        // funcdef: [decorators] 'def' NAME parameters ':' suite
        // parameters: '(' [varargslist] ')'
        // this gets called with "def" as the look-ahead
        private FunctionDefinition ParseFuncDef(bool isCoroutine) {
            string preWhitespace = null, afterAsyncWhitespace = null;

            var start = isCoroutine ? GetStart() : 0;
            if (isCoroutine) {
                preWhitespace = _tokenWhiteSpace;
            }
            Eat(TokenKind.KeywordDef);
            
            if (isCoroutine) {
                afterAsyncWhitespace = _tokenWhiteSpace;
            } else {
                preWhitespace = _tokenWhiteSpace;
                start = GetStart();
            }

            var name = ReadName();
            var nameExpr = MakeName(name);
            nameExpr.SetLoc(GetStart(), GetEnd());
            string nameWhiteSpace = _tokenWhiteSpace;

            bool ateLeftParen = name.HasName && Eat(TokenKind.LeftParenthesis);
            string parenWhiteSpace = _tokenWhiteSpace;

            var lStart = GetStart();
            var lEnd = GetEnd();
            int grouping = _tokenizer.GroupingLevel;

            List<string> commaWhiteSpace = null;
            bool ateTerminator = false;
            Parameter[] parameters = ateLeftParen ? ParseVarArgsList(TokenKind.RightParenthesis, out commaWhiteSpace, out ateTerminator, true) : null;
            string closeParenWhiteSpace = _tokenWhiteSpace;
            FunctionDefinition ret;
            if (parameters == null) {
                // error in parameters
                ret = new FunctionDefinition(nameExpr, new Parameter[0]);
                ret.IsCoroutine = isCoroutine;
                if (_verbatim) {
                    AddVerbatimName(name, ret);
                    AddPreceedingWhiteSpace(ret, preWhitespace);
                    if (afterAsyncWhitespace != null) {
                        GetNodeAttributes(ret)[FunctionDefinition.WhitespaceAfterAsync] = afterAsyncWhitespace;
                    }
                    AddSecondPreceedingWhiteSpace(ret, nameWhiteSpace);
                    AddThirdPreceedingWhiteSpace(ret, parenWhiteSpace);
                    AddFourthPreceedingWhiteSpace(ret, closeParenWhiteSpace);
                    if (!ateTerminator) {
                        AddErrorMissingCloseGrouping(ret);
                    }
                    if (!ateLeftParen) {
                        AddErrorIsIncompleteNode(ret);
                    }
                }
                ret.SetLoc(start, lEnd);
                return ret;
            }

            string arrowWhiteSpace = null;
            Expression returnAnnotation = null;
            if (MaybeEat(TokenKind.Arrow)) {
                arrowWhiteSpace = _tokenWhiteSpace;
                returnAnnotation = ParseExpression();
            }

            var rStart = GetStart();
            var rEnd = GetEnd();

            ret = new FunctionDefinition(nameExpr, parameters);
            AddVerbatimName(name, ret);

            PushFunction(ret);

            // set IsCoroutine before parsing the body to enable use of 'await'
            ret.IsCoroutine = isCoroutine;

            Statement body = ParseClassOrFuncBody();
            FunctionDefinition ret2 = PopFunction();
            System.Diagnostics.Debug.Assert(ret == ret2);

            ret.SetBody(body);
            ret.ReturnAnnotation = returnAnnotation;
            ret.HeaderIndex = rEnd;
            if (_verbatim) {
                AddPreceedingWhiteSpace(ret, preWhitespace);
                if (afterAsyncWhitespace != null) {
                    GetNodeAttributes(ret)[FunctionDefinition.WhitespaceAfterAsync] = afterAsyncWhitespace;
                }
                AddSecondPreceedingWhiteSpace(ret, nameWhiteSpace);
                AddThirdPreceedingWhiteSpace(ret, parenWhiteSpace);
                AddFourthPreceedingWhiteSpace(ret, closeParenWhiteSpace);
                AddListWhiteSpace(ret, commaWhiteSpace.ToArray());
                if (arrowWhiteSpace != null) {
                    AddFifthPreceedingWhiteSpace(ret, arrowWhiteSpace);
                }
                if (!ateTerminator) {
                    AddErrorMissingCloseGrouping(ret);
                }
            }
            ret.SetLoc(start, body.EndIndex);

            return ret;
        }