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 Encode_DoesIgnoresOperandForNonOperandInstructions(InstructionType op, Int32 operand, UInt64 expected) { // Arrange var encoder = new Encoder(); var instruction = new Instruction { Type = op, Operand = operand }; // Act var encodedInstruction = encoder.Encode(instruction); // Assert encodedInstruction.Should().Be(expected); }
public void Encode_EncodesInstructionsCorrectly(InstructionType op, Int32? operand, UInt64 expected) { // Arrange var encoder = new Encoder(); var instruction = new Instruction { Type = op, Operand = operand.HasValue ? operand.Value : 0 }; // Act var encodedInstruction = encoder.Encode(instruction); // Assert encodedInstruction.Should().Be(expected); }
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); }
/// <summary> /// Encode an instruction. /// </summary> /// <param name="instruction">Instruction to encode.</param> /// <returns></returns> public UInt64 Encode(Instruction instruction) { if (instruction == null) { throw new ArgumentNullException("instruction"); } UInt32 encodeOperand = (UInt32)instruction.Operand; switch (instruction.Type) { // No encoded operands case InstructionType.Mult: // Fallthrough intentional case InstructionType.Ret: case InstructionType.Stop: case InstructionType.Print: encodeOperand = 0; break; } return (((UInt64)instruction.Type) << 32) + encodeOperand; }
private static void InvalidInstruction(ExecutionContext context, Instruction instruction) { throw new InvalidOperationException(instruction.ToString()); }