Beispiel #1
0
        protected override SyntaxNode VisitForSyntax(ForSyntax pNode)
        {
            //Rewrite for statements with iterator arrays to normal for statements
            if (pNode.Iterator != null)
            {
                var i = SyntaxFactory.Identifier("!i");
                i.SetType(SmallTypeCache.Int);

                var postOp = pNode.Reverse ? UnaryExpressionOperator.PostDecrement : UnaryExpressionOperator.PostIncrement;
                UnaryExpressionSyntax finalizer = SyntaxFactory.UnaryExpression(i, postOp);

                SyntaxNode        end  = null;
                DeclarationSyntax decl = null;

                //Save itvar in case we are looping in a case body
                var rw = _rewrite;
                var it = _itVar;

                //Declare our iterator outside the for loop
                //This will help if our iterator is complex like a function call
                var iterVar = SyntaxFactory.Identifier("!iter");
                iterVar.SetType(pNode.Iterator.Type);
                var iterDecl = SyntaxFactory.SingleDeclaration(iterVar, pNode.Iterator);

                if (pNode.Iterator.Type.IsArray)
                {
                    //We are iterating over an array
                    //Reverse loops will start at Array.Length and decrement to 0
                    //Normal loops will start at 0 and increment to Array.Length
                    if (pNode.Reverse)
                    {
                        var length = SyntaxFactory.UnaryExpression(iterVar, UnaryExpressionOperator.Length);
                        length.SetType(SmallTypeCache.Int);
                        decl = SyntaxFactory.SingleDeclaration(i, SyntaxFactory.BinaryExpression(length, BinaryExpressionOperator.Subtraction, SyntaxFactory.NumericLiteral(1)));
                        end  = SyntaxFactory.NumericLiteral(0);
                    }
                    else
                    {
                        decl = SyntaxFactory.SingleDeclaration(i, SyntaxFactory.NumericLiteral(0));
                        end  = SyntaxFactory.UnaryExpression(iterVar, UnaryExpressionOperator.Length);
                        ((UnaryExpressionSyntax)end).SetType(SmallTypeCache.Int);
                    }

                    _itVar = SyntaxFactory.ArrayAccess(iterVar, i);
                    ((ArrayAccessSyntax)_itVar).SetType(iterVar.Type);
                }
                else if (pNode.Iterator.Type.IsAssignableFrom(_enumerable))
                {
                    //We are iterating over an enumerable
                    //Reverse loops will start at Count and decrement to 0
                    //Normal loops will start at 0 and increment to Count
                    if (pNode.Reverse)
                    {
                        var count = SyntaxFactory.MemberAccess(iterVar, SyntaxFactory.Identifier("Count"));
                        decl = SyntaxFactory.SingleDeclaration(i, SyntaxFactory.BinaryExpression(count, BinaryExpressionOperator.Subtraction, SyntaxFactory.NumericLiteral(1)));
                        end  = SyntaxFactory.NumericLiteral(0);
                    }
                    else
                    {
                        decl = SyntaxFactory.SingleDeclaration(i, SyntaxFactory.NumericLiteral(0));
                        end  = SyntaxFactory.MemberAccess(iterVar, SyntaxFactory.Identifier("Count"));
                    }

                    _itVar = SyntaxFactory.MemberAccess(iterVar, SyntaxFactory.MethodCall("ItemAt", new List <SyntaxNode>()
                    {
                        SyntaxFactory.Identifier("!i")
                    }));
                }
                else
                {
                    //Some bad type. We can't rewrite if it isn't array or enumerable
                    return(base.VisitForSyntax(pNode));
                }

                var op        = pNode.Reverse ? BinaryExpressionOperator.GreaterThanOrEqual : BinaryExpressionOperator.LessThan;
                var condition = SyntaxFactory.BinaryExpression(i, op, end);
                condition.SetType(SmallTypeCache.Boolean);

                var body         = (BlockSyntax)Visit(pNode.Body);
                var forStatement = SyntaxFactory.For(new List <DeclarationSyntax>()
                {
                    decl
                }, condition, new List <SyntaxNode>()
                {
                    finalizer
                }, body);

                //Restore our it for any other nested loops
                _itVar   = it;
                _rewrite = rw;

                //Return our iterator declaration and for rewrite
                return(SyntaxFactory.Block(new List <SyntaxNode>()
                {
                    iterDecl, forStatement
                }));
            }

            return(base.VisitForSyntax(pNode));
        }
Beispiel #2
0
 protected virtual SyntaxNode VisitArrayAccessSyntax(ArrayAccessSyntax pNode)
 {
     return(SyntaxFactory.ArrayAccess(pNode.Identifier, Visit(pNode.Index)));
 }