Esempio n. 1
0
        /// <summary>
        /// Applies the transformation
        /// </summary>
        /// <returns>The transformed item.</returns>
        /// <param name="item">The item to visit.</param>
        public ASTItem Transform(ASTItem item)
        {
            var stm = item as AST.ForStatement;

            if (stm == null)
            {
                return(item);
            }

            if (m_processed.Contains(stm))
            {
                return(item);
            }
            m_processed.Add(stm);

            Tuple <int, int, int> loopedges = null;

            try
            {
                loopedges = stm.GetStaticForLoopValues();
            }
            catch
            {
                return(item);
            }

            var incr = loopedges.Item3;

            if (incr == 1)
            {
                return(item);
            }

            var tmp = State.RegisterTemporaryVariable(Method, stm.LoopIndex.CecilType);

            State.TypeLookup[tmp] = VHDLTypes.INTEGER;

            // Find the first expression, so we can inject the assignment before it
            var firstexp = stm.LoopBody.All().OfType <Expression>().First();

            // Replace all the references
            foreach (var x in stm.All().OfType <Expression>())
            {
                var target = x.GetTarget();
                if (target == stm.LoopIndex)
                {
                    x.SetTarget(tmp);
                }
            }

            var exp = firstexp.SourceExpression;

            // Inject the assignment
            var nstm = new ExpressionStatement()
            {
                Expression = new AssignmentExpression()
                {
                    Left = new IdentifierExpression()
                    {
                        Name             = tmp.Name,
                        Target           = tmp,
                        SourceExpression = exp,
                        SourceResultType = tmp.CecilType
                    },
                    Operator = ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign,
                    Right    = new BinaryOperatorExpression()
                    {
                        Left = new IdentifierExpression()
                        {
                            Name             = stm.LoopIndex.Name,
                            Target           = stm.LoopIndex,
                            SourceExpression = exp,
                            SourceResultType = stm.LoopIndex.CecilType
                        },
                        Operator = ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.Multiply,
                        Right    = new PrimitiveExpression()
                        {
                            Value            = incr,
                            SourceResultType = tmp.CecilType,
                            SourceExpression = exp,
                        },
                        SourceExpression = exp,
                        SourceResultType = tmp.CecilType
                    },
                    SourceExpression = exp,
                    SourceResultType = tmp.CecilType
                }
            };

            nstm.UpdateParents();
            foreach (var x in nstm.All().OfType <Expression>())
            {
                State.TypeLookup[x] = VHDLTypes.INTEGER;
            }

            stm.LoopBody.PrependStatement(nstm);

            //Do not fix again
            stm.Increment = new AssignmentExpression(
                new IdentifierExpression(stm.LoopIndex),
                new BinaryOperatorExpression(
                    new IdentifierExpression(stm.LoopIndex),
                    ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.Add,
                    new PrimitiveExpression(1, tmp.CecilType)
                    )
            {
                SourceResultType = tmp.CecilType
            }
                )
            {
                Parent = stm, SourceResultType = tmp.CecilType
            };

            stm.Condition = new BinaryOperatorExpression(
                new IdentifierExpression(stm.LoopIndex),
                ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.LessThan,
                new PrimitiveExpression(loopedges.Item2 / loopedges.Item3, tmp.CecilType.Module.ImportReference(typeof(int)))
                )
            {
                Parent           = stm,
                SourceResultType = tmp.CecilType.Module.ImportReference(typeof(bool))
            };

            return(nstm);
        }