示例#1
0
        /// <summary>
        /// Renders a single ForStatement with the given indentation
        /// </summary>
        /// <returns>The VHDL lines in the statement.</returns>
        /// <param name="method">The method the statement belongs to.</param>
        /// <param name="s">The statement to render.</param>
        /// <param name="indentation">The indentation to use.</param>
        private IEnumerable <string> RenderStatement(AST.Method method, AST.ForStatement s, int indentation)
        {
            var edges = s.GetStaticForLoopValues();

            var endval = edges.Item2;

            endval--;

            var indent = new string(' ', indentation);

            yield return($"{indent}for {s.LoopIndex.Name} in {edges.Item1} to {endval} loop");

            var incr = edges.Item3;

            if (incr != 1)
            {
                throw new Exception($"Expected the for loop to have an increment of 1, it has {incr}");
            }

            foreach (var n in RenderStatement(method, s.LoopBody, indentation + 4))
            {
                yield return(n);
            }

            yield return($"{indent}end loop;");
        }
示例#2
0
        /// <summary>
        /// Renders a single ForStatement with the given indentation
        /// </summary>
        /// <returns>The VHDL lines in the statement.</returns>
        /// <param name="method">The method the statement belongs to.</param>
        /// <param name="s">The statement to render.</param>
        /// <param name="indentation">The indentation to use.</param>
        private IEnumerable <string> RenderStatement(AST.Method method, AST.ForStatement s, int indentation)
        {
            var edges  = s.GetStaticForLoopValues();
            var endval = edges.Item2;
            var incr   = edges.Item3;

            var indent = new string(' ', indentation);

            yield return($"{indent}for (size_t {s.LoopIndex.Name} = {edges.Item1}; {s.LoopIndex.Name} < {endval}; {s.LoopIndex.Name} += {incr}) {{");

            foreach (var n in RenderStatement(method, s.LoopBody, indentation + 4))
            {
                yield return(n);
            }

            yield return($"{indent}}}");
        }
示例#3
0
文件: ForLoop.cs 项目: kenkendk/SMEIL
 /// <summary>
 /// Creates a new variable instnace
 /// </summary>
 /// <param name="source">The source item</param>
 public ForLoop(AST.ForStatement source)
 {
     Source = source ?? throw new ArgumentNullException(nameof(source));
 }
示例#4
0
        /// <summary>
        /// Returns the start, end and increment integer values for a statically sized for loop
        /// </summary>
        /// <returns>The static for loop start, end and increment values.</returns>
        /// <param name="self">The statement to extract the values for.</param>
        public static Tuple <int, int, int> GetStaticForLoopValues(this AST.ForStatement self)
        {
            int start, end, incr;

            if (!(self.Initializer is AST.PrimitiveExpression))
            {
                throw new Exception($"Unable to statically expand loop initializer: {self.Initializer.SourceExpression}");
            }
            if (!(self.Condition is AST.BinaryOperatorExpression))
            {
                throw new Exception($"Unable to statically expand loop initializer: {self.Condition.SourceExpression}");
            }
            if (((BinaryOperatorExpression)self.Condition).Operator != ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.LessThan)
            {
                throw new Exception($"Can only statically expand loops with a less-than operator: {self.Condition.SourceExpression}");
            }

            start = ResolveIntegerValue(self.Initializer);

            var cond_left  = ((BinaryOperatorExpression)self.Condition).Left.GetUnwrapped();
            var cond_right = ((BinaryOperatorExpression)self.Condition).Right.GetUnwrapped();

            if (cond_left.GetTarget() != self.LoopIndex)
            {
                throw new Exception($"Can only statically expand loops where the left side of the condition is the loop variable");
            }

            if (cond_right is PrimitiveExpression || cond_right.GetTarget() != null)
            {
                end = ResolveIntegerValue(cond_right);
            }
            else if (cond_right is BinaryOperatorExpression)
            {
                var boe = cond_right as BinaryOperatorExpression;
                if (boe.Operator != ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.Add && boe.Operator != ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.Subtract)
                {
                    throw new Exception($"Can only statically expand loops if the condition is a simple add/subtract operation: {boe.SourceExpression}");
                }

                var lefttarget = boe.Left.GetTarget();
                if (lefttarget == null)
                {
                    throw new Exception($"Can only statically expand loops if the condition is a simple add/subtract operation: {boe.SourceExpression}");
                }

                var left_opr  = ResolveIntegerValue(boe.Left);
                var right_opr = ResolveIntegerValue(boe.Right);

                if (boe.Operator == ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.Add)
                {
                    end = left_opr + right_opr;
                }
                else
                {
                    end = left_opr - right_opr;
                }
            }
            else
            {
                throw new Exception($"Can only statically expand loops if the condition is a simple add/subtract operation: {self.Condition.SourceExpression}");
            }

            if (self.Increment is UnaryOperatorExpression)
            {
                var uoe = self.Increment as UnaryOperatorExpression;
                if (uoe.Operand.GetTarget() != self.LoopIndex)
                {
                    throw new Exception($"The item in the loop increment must be the loop variable: {self.Increment.SourceExpression}");
                }
                if (uoe.Operator != ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorType.PostIncrement)
                {
                    throw new Exception($"The item in the loop increment must be the loop variable with post increment: {self.Increment.SourceExpression}");
                }
                incr = 1;
            }
            else if (self.Increment is AssignmentExpression)
            {
                var boe = self.Increment as AssignmentExpression;
                if (boe.Left.GetTarget() != self.LoopIndex)
                {
                    throw new Exception($"The item in the loop increment must be the loop variable: {self.Increment.SourceExpression}");
                }
                if (boe.Operator == ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Assign && boe.Right.GetUnwrapped() is BinaryOperatorExpression)
                {
                    var boee = boe.Right.GetUnwrapped() as BinaryOperatorExpression;
                    if (boee.Operator != ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorType.Add)
                    {
                        throw new Exception($"The item in the loop increment must be a simple addition: {self.Increment.SourceExpression}");
                    }
                    if (boee.Left.GetTarget() != self.LoopIndex)
                    {
                        throw new Exception($"The item in the loop increment must be the loop variable: {self.Increment.SourceExpression}");
                    }

                    incr = ResolveIntegerValue(boee.Right);
                }
                else
                {
                    if (boe.Operator != ICSharpCode.Decompiler.CSharp.Syntax.AssignmentOperatorType.Add)
                    {
                        throw new Exception($"The item in the loop increment must be a simple addition: {self.Increment.SourceExpression}");
                    }
                    incr = ResolveIntegerValue(boe.Right);
                }
            }
            else
            {
                throw new Exception($"Can only statically expand loops if the increment is a simple constant: {self.Condition.SourceExpression}");
            }

            return(new Tuple <int, int, int>(start, end, incr));
        }