Beispiel #1
0
        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;
        }
Beispiel #2
0
        //  genexpr_for  ::= "for" target_list "in" or_test [genexpr_iter]
        //  genexpr_iter ::= (genexpr_for | genexpr_if) *
        //
        //  "for" has NOT been eaten before entering this method
        private Expression ParseGeneratorExpression(Expression expr) {
            ForStatement root = ParseGenExprFor();
            Statement current = root;

            for (; ; ) {
                if (PeekToken(Tokens.KeywordForToken)) {
                    current = NestGenExpr(current, ParseGenExprFor());
                } else if (PeekToken(Tokens.KeywordIfToken)) {
                    current = NestGenExpr(current, ParseGenExprIf());
                } else {
                    // Generator Expressions have an implicit function definition and yield around their expression.
                    //  (x for i in R)
                    // becomes:
                    //   def f(): 
                    //     for i in R: yield (x)
                    ExpressionStatement ys = new ExpressionStatement(new YieldExpression(expr));
                    ys.Expression.SetLoc(_globalParent, expr.IndexSpan);
                    ys.SetLoc(_globalParent, expr.IndexSpan);
                    NestGenExpr(current, ys);
                    break;
                }
            }

            // We pass the outermost iterable in as a parameter because Python semantics
            // say that this one piece is computed at definition time rather than iteration time
            const string fname = "<genexpr>";
            Parameter parameter = new Parameter("__gen_$_parm__", 0);
            FunctionDefinition func = new FunctionDefinition(fname, new Parameter[] { parameter }, root);
            func.IsGenerator = true;
            func.SetLoc(_globalParent, root.StartIndex, GetEnd());
            func.HeaderIndex = root.EndIndex;

            //  Transform the root "for" statement
            Expression outermost = root.List;
            NameExpression ne = new NameExpression("__gen_$_parm__");
            ne.SetLoc(_globalParent, outermost.IndexSpan);
            root.List = ne;

            GeneratorExpression ret = new GeneratorExpression(func, outermost);
            ret.SetLoc(_globalParent, expr.StartIndex, GetEnd());
            return ret;
        }
Beispiel #3
0
        // funcdef: [decorators] 'def' NAME parameters ':' suite
        // parameters: '(' [varargslist] ')'
        // this gets called with "def" as the look-ahead
        private FunctionDefinition ParseFuncDef() {
            Eat(TokenKind.KeywordDef);
            var start = GetStart();
            string name = ReadName();

            Eat(TokenKind.LeftParenthesis);

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

            Parameter[] parameters = ParseVarArgsList(TokenKind.RightParenthesis);
            FunctionDefinition ret;
            if (parameters == null) {
                // error in parameters
                ret = new FunctionDefinition(name, new Parameter[0]);
                ret.SetLoc(_globalParent, start, lEnd);
                return ret;
            }

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

            ret = new FunctionDefinition(name, parameters);
            PushFunction(ret);


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

            ret.Body = body;
            ret.HeaderIndex = rEnd;

            if (_sink != null) {
                _sink.MatchPair(
                    new SourceSpan(_tokenizer.IndexToLocation(lStart), _tokenizer.IndexToLocation(lEnd)), 
                    new SourceSpan(_tokenizer.IndexToLocation(rStart), _tokenizer.IndexToLocation(rEnd)), 
                    grouping
                );
            }

            ret.SetLoc(_globalParent, start, body.EndIndex);

            return ret;
        }
Beispiel #4
0
        // funcdef: [decorators] 'def' NAME parameters ':' suite
        // parameters: '(' [varargslist] ')'
        // this gets called with "def" as the look-ahead
        private FunctionDefinition ParseFuncDef() {
            Eat(TokenKind.KeywordDef);
            SourceLocation start = GetStart();
            string name = ReadName();

            Eat(TokenKind.LeftParenthesis);

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

            Parameter[] parameters = ParseVarArgsList(TokenKind.RightParenthesis);
            if (parameters == null) {
                // error in parameters
                return new FunctionDefinition(name, new Parameter[0], _sourceUnit);
            }

            SourceLocation rStart = GetStart(), rEnd = GetEnd();

            FunctionDefinition ret = new FunctionDefinition(name, parameters, _sourceUnit);
            PushFunction(ret);


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

            ret.Body = body;
            ret.Header = rEnd;

            _sink.MatchPair(new SourceSpan(lStart, lEnd), new SourceSpan(rStart, rEnd), grouping);

            ret.SetLoc(start, body.End);

            return ret;
        }
Beispiel #5
0
        private Expression FinishOldLambdef()
        {
            Location start = GetStart();
            Expression[] parameters, defaults;
            FunctionAttributes flags;
            ParseVarArgsList(out parameters, out defaults, out flags, TokenKind.Colon);
            Location mid = GetEnd();

            Expression expr = ParseOldTest();
            Statement body = new ReturnStatement(expr);
            body.SetLoc(GetExternal(), expr.Start, expr.End);
            FunctionDefinition func = new FunctionDefinition(SymbolTable.StringToId("<lambda$" + (oldLambdaCount++) + ">"), parameters, defaults, flags, body, context.SourceFile);
            func.SetLoc(GetExternal(), start, GetEnd());
            func.Header = mid;
            LambdaExpression ret = new LambdaExpression(func);
            ret.SetLoc(GetExternal(), start, GetEnd());
            return ret;
        }
Beispiel #6
0
        private Expression ParseGeneratorExpression(Expression test)
        {
            ForStatement root = ParseGenExprFor();
            Statement current = root;

            for (; ; ) {
                if (PeekToken(Tokens.KeywordForToken)) {
                    current = NestGenExpr(current, ParseGenExprFor());
                } else if (PeekToken(Tokens.KeywordIfToken)) {
                    current = NestGenExpr(current, ParseGenExprIf());
                } else {
                    YieldStatement ys = new YieldStatement(test, 0);
                    ys.SetLoc(GetExternal(), test.Start, test.End);
                    NestGenExpr(current, ys);
                    break;
                }
            }

            SymbolId fname = SymbolTable.StringToId("__gen_" + System.Threading.Interlocked.Increment(ref genexp_counter));
            NameExpression pname = new NameExpression(SymbolTable.GeneratorParmName);
            FunctionDefinition func = new FunctionDefinition(fname, new Expression[] { pname }, new Expression[] { }, FunctionAttributes.None, root, context.SourceFile);
            func.YieldCount = 1;
            func.SetLoc(GetExternal(), root.Start, GetEnd());
            func.Header = root.End;

            //  Transform the root "for" statement
            Expression outermost = root.List;
            root.List = pname;

            CallExpression gexp = FinishCallExpr(new NameExpression(fname), new Arg(outermost));
            CallExpression iter = FinishCallExpr(new NameExpression(SymbolTable.Iter), new Arg(gexp));

            GeneratorExpression ret = new GeneratorExpression(func, iter);
            ret.SetLoc(GetExternal(), root.Start, GetEnd());
            return ret;
        }
Beispiel #7
0
        // funcdef: [decorators] 'def' NAME parameters ':' suite
        // parameters: '(' [varargslist] ')'
        // this gets called with "def" as the look-ahead
        private FunctionDefinition ParseFuncDef()
        {
            Eat(TokenKind.KeywordDef);
            Location start = GetStart();
            SymbolId name = ReadName();

            Eat(TokenKind.LeftParenthesis);

            Location lStart = GetStart(), lEnd = GetEnd();
            int grouping = tokenizer.GroupingLevel;

            Expression[] parameters, defaults;
            FunctionAttributes flags;
            ParseVarArgsList(out parameters, out defaults, out flags, TokenKind.RightParenthesis);

            Location rStart = GetStart(), rEnd = GetEnd();

            FunctionDefinition ret = new FunctionDefinition(name, parameters, defaults, flags, context.SourceFile);
            PushFunction(ret);

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

            ret.Body = body;
            ret.Header = rEnd;

            context.Sink.MatchPair(new CodeSpan(lStart, lEnd), new CodeSpan(rStart, rEnd), grouping);

            ret.SetLoc(GetExternal(), start, GetEnd());

            return ret;
        }