Esempio n. 1
0
        public void Print_DecodesOperand()
        {
            // Arrange
            var printer = new Print();
            var stack = new Mock<IStack>();
            stack.Setup(s => s.Pop())
                .Returns(1234);

            var decoder = new Mock<IDecoder>();
            decoder.Setup(d => d.Decode(It.IsAny<UInt64>()))
                .Returns(new Instruction
                {
                    Operand = 12345
                });

            var context = new ExecutionContext
            {
                Stack = stack.Object,
                Decoder = decoder.Object
            };

            // Act
            printer.Execute(context, null);

            // Verify
            decoder.Verify(d => d.Decode(1234), Times.Once);
        }
Esempio n. 2
0
        public void Call_SetsProgramCounterToOperandValue()
        {
            // Arrange
            var caller = new Call();
            var context = new ExecutionContext();
            var instruction = new Instruction { Operand = 54321 };

            // Act
            caller.Execute(context, instruction);

            // Assert
            context.ProgramCounter.Should().Be(54321);
        }
Esempio n. 3
0
        public void Push_PushesValueOntoStack()
        {
            // Arrange
            var encoder = new Mock<IEncoder>();
            var stack = new Mock<IStack>();
            var context = new ExecutionContext
            {
                Encoder = encoder.Object,
                Stack = stack.Object
            };
            var instruction = new Instruction { Operand = 12345 };
            var pusher = new Push();

            // Act
            pusher.Execute(context, instruction);

            // Assert
            stack.Verify(s => s.Push(It.IsAny<UInt64>()), Times.Once);
        }
Esempio n. 4
0
        public void Push_EncodesADataInstructionWithGivenOperand()
        {
            // Arrange
            var encoder = new Mock<IEncoder>();
            var stack = new Mock<IStack>();
            var context = new ExecutionContext
            {
                Encoder = encoder.Object,
                Stack = stack.Object
            };
            var instruction = new Instruction { Operand = 12345 };
            var pusher = new Push();

            // Act
            pusher.Execute(context, instruction);

            // Assert
            encoder.Verify(e => e.Encode(It.Is<Instruction>(i => i.Operand == instruction.Operand && i.Type == InstructionType.Data)));
        }
Esempio n. 5
0
        public void Multiply_PopsTwoOperandsMultiplyEncodeAndPushBackToStack()
        {
            // Arrange
            var instruction = new Instruction { Type = InstructionType.Mult };

            var stack = new Mock<IStack>();
            stack.Setup(s => s.Pop())
                .Returns(Operand);

            var encoder = new Mock<IEncoder>();
            encoder.Setup(e => e.Encode(It.Is<Instruction>(i => i.Operand == Result && i.Type == InstructionType.Data)))
                .Returns(EncodedValue);

            var decoder = new Mock<IDecoder>();
            decoder.Setup(d => d.Decode(Operand))
                .Returns(new Instruction { Operand = Operand });

            var alu = new Mock<IArithmeticLogicUnit>();
            alu.Setup(a => a.Multiply(Operand, Operand))
                .Returns(Result);

            var context = new ExecutionContext
            {
                Stack = stack.Object,
                Encoder = encoder.Object,
                Decoder = decoder.Object,
                Alu = alu.Object
            };

            var multiplier = new Multiply();

            // Act
            multiplier.Execute(context, instruction);

            // Assert
            stack.Verify(s => s.Pop(), Times.Exactly(2));
            decoder.Verify(d => d.Decode(Operand), Times.Exactly(2));
            alu.Verify(a => a.Multiply(Operand, Operand), Times.Once);
            encoder.Verify(e => e.Encode(It.Is<Instruction>(i => i.Operand == Result && i.Type == InstructionType.Data)));
            stack.Verify(s => s.Push(EncodedValue), Times.Once);
        }
Esempio n. 6
0
        public void Return_SetsProgramCounterToDecodedAddress()
        {
            // Arrange
            var returner = new Return();
            var stack = new Mock<IStack>();
            var decoder = new Mock<IDecoder>();
            decoder.Setup(d => d.Decode(It.IsAny<UInt64>()))
                .Returns(new Instruction { Operand = 999999999 });

            var context = new ExecutionContext
            {
                Stack = stack.Object,
                Decoder = decoder.Object
            };

            // Act
            returner.Execute(context, null);

            // Asserty
            context.ProgramCounter.Should().Be(999999999);
        }
Esempio n. 7
0
        public void Return_CallsDecodeToGetAddress()
        {
            // Arrange
            var returner = new Return();
            var stack = new Mock<IStack>();
            var decoder = new Mock<IDecoder>();
            decoder.Setup(d => d.Decode(It.IsAny<UInt64>()))
                .Returns(new Instruction { Operand = 999999999 });

            var context = new ExecutionContext
            {
                Stack = stack.Object,
                Decoder = decoder.Object
            };

            // Act
            returner.Execute(context, null);

            // Asserty
            decoder.Verify(d => d.Decode(It.IsAny<UInt64>()), Times.Once);
        }
Esempio n. 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Computer"/> class.
        /// </summary>
        /// <param name="stack">The stack.</param>
        /// <param name="encoder">The instruction encoder.</param>
        /// <param name="decoder">The instruction decoder.</param>
        public ExecutionUnit(IStack stack, IEncoder encoder, IDecoder decoder, IArithmeticLogicUnit alu)
        {
            _context = new ExecutionContext
            {
                Stack = stack,
                Encoder = encoder,
                Decoder = decoder,
                Alu = alu,
                Executing = true
            };

            _dispatcher = new Dictionary<InstructionType, Action<ExecutionContext, Instruction>>
            {
                { InstructionType.Mult, Multiply.GetAction() },
                { InstructionType.Call, Call.GetAction() },
                { InstructionType.Ret, Return.GetAction() },
                { InstructionType.Stop, Stop.GetAction() },
                { InstructionType.Print, Print.GetAction() },
                { InstructionType.Push, Push.GetAction() }
            };
        }
Esempio n. 9
0
 private static void InvalidInstruction(ExecutionContext context, Instruction instruction)
 {
     throw new InvalidOperationException(instruction.ToString());
 }