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); }
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); }
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); }
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))); }
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); }
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); }
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); }
/// <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() } }; }
private static void InvalidInstruction(ExecutionContext context, Instruction instruction) { throw new InvalidOperationException(instruction.ToString()); }