Пример #1
0
        protected virtual void Visit(ForEachStatement forEachStatement)
        {
            WriteLinkLine(forEachStatement);

            if (forEachStatement.Variable == null)
            {
                localVariableCount++;

                Identifier parameterType;
                Identifier parameterMember;
                if (!TryParameters(forEachStatement.Collection, out parameterType, out parameterMember))
                {
                    Write(@"#error ""Unexpected parameter for 'foreach params' [");
                    VisitDynamic(forEachStatement.Collection);
                    WriteLine(@"]. Expecting single property access""");
                    return;
                }

                string variable = "____" + localVariableCount;
                Write("foreach(").Write("var ").Write(variable).Write(" in ");
                VisitDynamic(forEachStatement.Collection);
                WriteLine(")");

                var statement = forEachStatement.Body as BlockStatement;
                if (statement == null)
                {
                    statement = new BlockStatement {Span = forEachStatement.Body.Span};
                    statement.Statements.Add(forEachStatement.Body);
                }
                AddPushPopParameters(statement, parameterType, parameterMember, new VariableReferenceExpression(variable), forEachStatement.Span);

                VisitDynamic(statement);

                localVariableCount--;
            }
            else
            {
                Write("foreach(");
                IsVisitingVariableInlines = true;
                VisitDynamic(forEachStatement.Variable);
                IsVisitingVariableInlines = false;
                Write(" in ");
                VisitDynamic(forEachStatement.Collection);
                Write(")");
                WriteLine();
                VisitDynamic(forEachStatement.Body);
            }
        }
Пример #2
0
        /// <summary>
        /// Creates a ForStatement with the same behavior
        /// </summary>
        /// <param name="forEachStatement">the ForEachStatement</param>
        /// <returns>the ForStatement</returns>
        private static ForStatement ExpandForEachStatement(ForEachStatement forEachStatement)
        {
            if (forEachStatement != null)
            {
                var collec = forEachStatement.Collection.TypeInference.Declaration as Variable;
                LiteralExpression dimLit = null;
                if (collec.Type is ArrayType)
                {
                    if ((collec.Type as ArrayType).Dimensions.Count == 1)
                    {
                        dimLit = (collec.Type as ArrayType).Dimensions[0] as LiteralExpression;
                    }
                }

                if (dimLit != null)
                {
                    var initializer = new Variable(ScalarType.Int, forEachStatement.Variable.Name.Text + "Iter", new LiteralExpression(0));
                    var vre = new VariableReferenceExpression(initializer.Name);
                    var condition = new BinaryExpression(BinaryOperator.Less, vre, dimLit);
                    var next = new UnaryExpression(UnaryOperator.PreIncrement, vre);
                    ForStatement forStatement = new ForStatement(new DeclarationStatement(initializer), condition, next);
                    var body = new BlockStatement();

                    var variable = forEachStatement.Variable;
                    variable.InitialValue = new IndexerExpression(forEachStatement.Collection, new VariableReferenceExpression(initializer));
                    body.Statements.Add(new DeclarationStatement(variable));

                    if (forEachStatement.Body is BlockStatement)
                        body.Statements.AddRange((forEachStatement.Body as BlockStatement).Statements);
                    else
                        body.Statements.Add(forEachStatement.Body);

                    forStatement.Body = body;

                    return forStatement;
                }

                // TODO: multidimension-array?
                // TODO: unroll?
                // TODO: multiple foreach?
            }
            return null;
        }
Пример #3
0
        private Node Visit(ForEachStatement forEachStatement)
        {
            if (expandForEachStatements)
            {
                // run analysis on collection
                Visit(forEachStatement.Collection);

                var inference = forEachStatement.Collection.TypeInference.Declaration as Variable;
                if (!(inference != null && inference.Type is ArrayType))
                    return forEachStatement;

                if ((inference.Type as ArrayType).Dimensions.Count > 1)
                {
                    Error(XenkoMessageCode.ErrorMultiDimArray, forEachStatement.Span, inference, forEachStatement, analyzedModuleMixin.MixinName);
                    return forEachStatement;
                }

                var dim = (int)((inference.Type as ArrayType).Dimensions.FirstOrDefault() as LiteralExpression).Value;

                var result = new StatementList();
                for (int i = 0; i < dim; ++i)
                {
                    var cloned = forEachStatement.DeepClone();
                    var replace = new XenkoReplaceExtern(cloned.Variable, new IndexerExpression(cloned.Collection, new LiteralExpression(i)));
                    replace.Run(cloned.Body);
                    result.Add(cloned.Body);
                }

                Visit((Node)result);
                return result;
            }
            else
            {
                Visit((Node)forEachStatement);
                parsingInfo.ForEachStatements.Add(new StatementNodeCouple(forEachStatement, ParentNode));
                return forEachStatement;
            }
        }