Exemple #1
0
        /// <summary>
        /// Constructs a Loop given a set of instructions and 
        /// an offset of the position of where the loop starts
        /// </summary>
        /// <param name="instructions"></param>
        /// <param name="offset">The index of the StartLoop instruction</param>
        /// <returns></returns>
        public static Loop Construct(LanguageInstruction[] instructions, int offset)
        {
            var loopInstructions = GetLoopInstructions(instructions, offset);
            var nestedLoops = GetNestedLoops(loopInstructions);

            return new Loop(offset, loopInstructions, nestedLoops);
        }
Exemple #2
0
        /// <summary>
        /// Returns null if the number of StartLoop operations match the number of EndLoop operations
        /// 
        /// Otherwise, it returns the operation with the excess total.
        /// </summary>
        private LanguageInstruction? AreLoopOperationsBalanced(LanguageInstruction[] instructions)
        {
            int totalStartLoopOperations = instructions.Where(instruction => instruction == LanguageInstruction.StartLoop).Count(),
                totalEndLoopOperations = instructions.Where(instruction => instruction == LanguageInstruction.EndLoop).Count();

            if (totalStartLoopOperations == totalEndLoopOperations)
            {
                return null;
            }

            if (totalStartLoopOperations > totalEndLoopOperations)
            {
                return LanguageInstruction.StartLoop;
            }

            return LanguageInstruction.EndLoop;
        }
Exemple #3
0
        /// <summary>
        /// Given a set of instructions, this method returns a collection of 
        /// nested loops contained in the set.
        /// </summary>
        /// <returns></returns>
        private static List<Loop> GetNestedLoops(LanguageInstruction[] instructions)
        {
            var nestedLoops = new List<Loop>();
            var loopInstructions = instructions;
            var containsNestedLoops = loopInstructions.Any(li => li == LanguageInstruction.StartLoop);
            if (!containsNestedLoops)
            {
                return nestedLoops;
            }

            for (int i = 0; i < instructions.Length; i++)
            {
                var ins = instructions[i];
                if (!(ins == LanguageInstruction.StartLoop || ins == LanguageInstruction.EndLoop))
                {
                    continue;
                }

                if (ins == LanguageInstruction.StartLoop)
                {
                    var lInstructions = GetLoopInstructions(instructions, i);
                    var loop = new Loop(i, lInstructions, GetNestedLoops(lInstructions));
                    nestedLoops.Add(loop);

                    i = GetNextClosingLoopIndex(instructions, i).Value;
                }
            }

            return nestedLoops;
        }
Exemple #4
0
        private static int? GetNextClosingLoopIndex(LanguageInstruction[] instructions, int index)
        {
            int stack = 0;

            for (int i = index + 1; i < instructions.Length; i++)
            {
                if (instructions[i] == LanguageInstruction.StartLoop)
                {
                    stack += 1;
                }

                if (instructions[i] == LanguageInstruction.EndLoop)
                {
                    if (stack > 0)
                    {
                        stack--;
                        continue;
                    }

                    return i;
                }
            }

            return null;
        }
Exemple #5
0
 /// <summary>
 /// Given a set of instructions and an offset of where the loop starts,
 /// this method returns the operations that the loop contains
 /// </summary>
 /// <param name="instructions"></param>
 /// <param name="offset">The index of the StartLoop instruction</param>
 /// <returns></returns>
 private static LanguageInstruction[] GetLoopInstructions(LanguageInstruction[] instructions, int offset)
 {
     var closingEndLoopIndex = GetNextClosingLoopIndex(instructions, offset).Value;
     return instructions.Skip(offset + 1).Take(closingEndLoopIndex - offset - 1).ToArray();
 }