public bool Repeat(DILOperationSet operations, int offset)
        {
            int delta = Scalar, totalOperationsCovered = 1;

            for (int j = offset + 1; j < operations.Count; j++) // - i ?
            {
                var instruction = operations[j] as AdditionMemoryOp;
                if (instruction == null)
                {
                    break;
                }

                if (instruction.Offset != Offset)
                {
                    break;
                }

                totalOperationsCovered++;
                delta += instruction.Scalar;
            }

            if (totalOperationsCovered > 1)
            {
                operations.RemoveRange(offset, totalOperationsCovered);
                operations.Insert(offset, new AdditionMemoryOp(Offset, delta));

                return true;

            }

            return false;
        }
Esempio n. 2
0
        public bool Repeat(DILOperationSet operations, int offset)
        {
            int ptrDelta = Delta, totalPtrsCovered = 1;

            for (int j = offset + 1; j < operations.Count; j++)
            {
                var instruction = operations[j] as PtrOp;
                if (instruction == null)
                {
                    break;
                }

                ptrDelta += instruction.Delta;
                totalPtrsCovered++;
            }

            if (totalPtrsCovered > 1)
            {
                operations.RemoveRange(offset, totalPtrsCovered);
                operations.Insert(offset, new PtrOp(ptrDelta));
                return true;
            }

            return false;
        }
Esempio n. 3
0
 public void Run(DILOperationSet operations)
 {
     int ptr = Ptr; // since you can't pass a Property by reference...
     foreach (var instruction in operations)
     {
         var interpretableInstruction = instruction as IInterpretable;
         if (interpretableInstruction != null)
         {
             interpretableInstruction.Interpret(Domain, ref ptr);
             Ptr = ptr;
         } else
         {
             throw new Exception("Why isn't this instruction interpretable?");
         }
     }
 }
Esempio n. 4
0
        /// <summary>
        /// TODO: https://github.com/dreasgrech/yabfcompiler/issues/11
        ///       Do not emit the array and the pointer variables if they're not needed.
        /// </summary>
        private string CompileToExecutable(DILOperationSet operations, string filename)
        {
            var assembly = CreateAssemblyAndEntryPoint(filename);
            ILGenerator ilg = assembly.MainMethod.GetILGenerator();

            LocalBuilder array = ilg.CreateArray<byte>(DomainSize);
            LocalBuilder ptr = null;

            // Do not emit the pointer variable if it's not needed.
            if (operations.ContainsPointerOperations())
            {
                ptr = ilg.DeclareIntegerVariable();
            }

            foreach (var dilInstruction in operations)
            {
                dilInstruction.Emit(ilg, array, ptr);
            }

            ilg.Emit(OpCodes.Ret);

            Type t = assembly.MainClass.CreateType();
            assembly.DynamicAssembly.SetEntryPoint(assembly.MainMethod, PEFileKinds.ConsoleApplication);

            var compiledAssemblyFile = String.Format("{0}.exe", Path.GetFileNameWithoutExtension(filename));
            assembly.DynamicAssembly.Save(compiledAssemblyFile);

            return compiledAssemblyFile;
        }
Esempio n. 5
0
        /// <summary>
        /// Returns the location of the compiled assembly
        /// </summary>
        /// <returns></returns>
        public string Compile(string filename)
        {
            var instructions = Parser.GenerateDIL(File.ReadAllText(filename)).ToArray();

            LanguageInstruction? areLoopOperationsBalanced;
            if ((areLoopOperationsBalanced = AreLoopOperationsBalanced(instructions)) != null)
            {
                throw new InstructionNotFoundException(String.Format("Expected to find an {0} instruction but didn't.", (~areLoopOperationsBalanced.Value).ToString()));
            }

            var dilInstructions = new DILOperationSet(instructions);

            // If we're not in debug mode, optimize the shit out of it!
            if (!OptionEnabled(CompilationOptions.DebugMode))
            {
                while (dilInstructions.Optimize(ref dilInstructions))
                {
                }
            }

            //var interpreter = new Interpreter(30000);
            //interpreter.Run(dilInstructions);

            return CompileToExecutable(dilInstructions, filename);
        }
Esempio n. 6
0
 /// <summary>
 /// A simple loop is a loop which, when ignoring nested loops, the pointer returns to the initial position of the loop after execution
 /// 
 /// A nested loop also doesn't contain any IO.
 /// 
 /// This method needs to be changed to an instance method
 /// </summary>
 /// <param name="operations"></param>
 /// <returns></returns>
 public static bool IsSimple(DILOperationSet operations)
 {
     return
         new CodeWalker().Walk(operations).EndPtrPosition == 0
         && !ContainsIO(operations);
 }
Esempio n. 7
0
 /// <summary>
 /// This method needs to be changed to an instance method
 /// </summary>
 /// <param name="operations"></param>
 /// <returns></returns>
 public static bool ContainsIO(DILOperationSet operations)
 {
     return operations.Any(o => o is WriteOp || o is ReadOp);
 }
Esempio n. 8
0
 public LoopOp(DILOperationSet instructions)
 {
     Instructions = instructions;
     NestedLoops = Instructions.OfType<LoopOp>().ToList();
 }
Esempio n. 9
0
        public LoopUnrollingResults Unroll()
        {
            var unrolled = new DILOperationSet();
            //if (IsClearanceLoop())
            //{
            //    unrolled.Add(new AssignOp(0, 0));
            //    return new LoopUnrollingResults(unrolled, true);
            //}

            var withUnrolledNestLoops = new DILOperationSet();
            foreach (var instruction in Instructions)
            {
                if (instruction is LoopOp)
                {
                    var nestedLoop = instruction as LoopOp;
                    var ur = nestedLoop.Unroll();
                    if (ur.WasLoopUnrolled)
                    {
                        withUnrolledNestLoops.AddRange(ur.UnrolledInstructions);
                    } else
                    {
                        withUnrolledNestLoops.Add(new LoopOp(ur.UnrolledInstructions));
                    }
                }
                else
                {
                    withUnrolledNestLoops.Add(instruction);
                }
            }

            if (IsSimple(withUnrolledNestLoops))
            {
                var walk = new CodeWalker().Walk(withUnrolledNestLoops);
                if (walk.Domain.ContainsKey(0) && walk.Domain[0] == -1)
                {
                    foreach (var cell in walk.Domain)
                    {
                        if (cell.Key == 0)
                        {
                            continue;
                        }

                        //// If the scalar value of the multiplication operation is 0,
                        //// then simply assign 0 to the cell because n * 0 = 0.
                        //if (cell.Value == 0)
                        //{
                        //    unrolled.Add(new AssignOp(cell.Key, 0));
                        //}
                        //else
                        //{
                            unrolled.Add(new MultiplicationMemoryOp(cell.Key, cell.Value));
                        //}
                    }

                    // If it's a simple loop, then the cell position of the loop should always be assigned a 0 since that's when the loop stops.
                    if (walk.Domain.ContainsKey(0))
                    {
                        unrolled.Add(new AssignOp(0, 0));
                    }

                    return new LoopUnrollingResults(unrolled, true);
                } else
                {
                    return new LoopUnrollingResults(withUnrolledNestLoops, false);

                }
            }

            return new LoopUnrollingResults(withUnrolledNestLoops, false);
        }
Esempio n. 10
0
        public bool Repeat(DILOperationSet operations, int offset)
        {
            int repeated = Repeated, totalOperationsCovered = 1;
            for (int i = offset + 1; i < operations.Count; i++)
            {
                var instruction = operations[i] as WriteOp;
                if (instruction == null)
                {
                    break;
                }

                if (instruction.Offset != Offset)
                {
                    break;
                }

                repeated += instruction.Repeated;
                totalOperationsCovered++;
            }

            if (totalOperationsCovered > 1)
            {
                operations.RemoveRange(offset, totalOperationsCovered);
                operations.Insert(offset, new WriteOp(Offset, repeated));
                return true;
            }

            return false;
        }
 public LoopUnrollingResults(DILOperationSet operations, bool wasLoopUnrolled)
 {
     UnrolledInstructions = operations;
     WasLoopUnrolled = wasLoopUnrolled;
 }
Esempio n. 12
0
        public bool Repeat(DILOperationSet operations, int offset)
        {
            var totalOperationsCovered = 1;
            for (int j = offset + 1; j < operations.Count; j++)
            {
                var instruction = operations[j] as AssignOp;
                if (instruction == null)
                {
                    break;
                }

                if (instruction.Offset != Offset)
                {
                    break;
                }

                if (instruction.Value != Value)
                {
                    break;
                }

                totalOperationsCovered++;
            }

            if (totalOperationsCovered > 1)
            {
                operations.RemoveRange(offset, totalOperationsCovered);
                operations.Insert(offset, new AssignOp(Offset, Value));

                return true;

            }

            return false;
        }