public TuringMachine Advanced()
    {
        if (IsHalted)
        {
            return(this);
        }
        if (IsStuckInALoop)
        {
            return(this);
        }

        var curState    = new InstructionSelector(State, Tape.Contains(Position));
        var instruction = Instructions[curState];
        var newState    = instruction.NewMachineState;

        if (newState < 0)
        {
            return(new TuringMachine(Instructions, Position, Tape, newState, ElapsedSteps + 1, PreviousState));
        }

        var newTape          = instruction.NewTapeValue ? Tape.Add(Position) : Tape.Remove(Position);
        var newPosition      = Position + (instruction.ThenMoveRightward ? 1 : -1);
        var newPreviousState = ElapsedSteps.IsPowerOfTwo ? Tuple.Create(State, Tape) : PreviousState;

        return(new TuringMachine(Instructions, newPosition, newTape, newState, ElapsedSteps + 1, newPreviousState));
    }
        public void SimpleTest()
        {
            var template  = new RegisterReadTemplate();
            var templates = new List <InstructionTemplate> {
                template
            };
            var root     = new RegisterRead(new VirtualRegister());
            var tree     = new Tree(root, new Ret());
            var selector = new InstructionSelector(templates);
            var ins      = selector.GetInstructions(tree);

            Assert.AreEqual(2, ins.Count());
        }
        public void AddTest()
        {
            var templates = new List <InstructionTemplate> {
                new AddTemplate(), new RegisterReadTemplate()
            };
            var v1       = new RegisterRead(new VirtualRegister());
            var v2       = new RegisterRead(new VirtualRegister());
            var v3       = new RegisterRead(new VirtualRegister());
            var node     = new ArithmeticBinaryOperation(ArithmeticOperationType.Addition, v1, v2);
            var root     = new ArithmeticBinaryOperation(ArithmeticOperationType.Addition, v3, node);
            var tree     = new Tree(root, new Ret());
            var selector = new InstructionSelector(templates);
            var ins      = selector.GetInstructions(tree);

            Assert.AreEqual(6, ins.Count());
        }
        public void NullTest()
        {
            InstructionTemplate nullTemplate = new NullTemplate();
            var template  = new RegisterReadTemplate();
            var templates = new List <InstructionTemplate> {
                template, nullTemplate
            };
            var root       = new RegisterRead(new VirtualRegister());
            var trueTarget =
                this.labelFactory.GetLabel(new Tree(new UnitImmediateValue(), new UnconditionalJump(null)));
            var controlFlow = new ConditionalJump(trueTarget, null);
            var tree        = new Tree(root, controlFlow);
            var selector    = new InstructionSelector(templates);
            var ins         = selector.GetInstructions(tree);

            Assert.AreEqual(2, ins.Count());
        }
        public void StackMemoryTest()
        {
            var template  = new ReserveStackMemoryTemplate();
            var templates = new List <InstructionTemplate> {
                template
            };
            var functionInfo = new Function(null, "abc", new List <VariableDeclaration>(), false, false);

            functionInfo.ReserveStackFrameLocation(IntType.Instance);
            functionInfo.ReserveStackFrameLocation(IntType.Instance);
            var root     = new ReserveStackMemory(functionInfo);
            var tree     = new Tree(root, new Ret());
            var selector = new InstructionSelector(templates);
            var ins      = selector.GetInstructions(tree);

            Assert.AreEqual(2, ins.Count());
            Assert.AreEqual("sub RSP, 32", ins.First().ToASM(null).First()); // 32 because of link + 2 local variables
        }