예제 #1
0
        private ExecutionState <GroupState> Run(string code, InstructionExecutor <GroupState> executor = null)
        {
            (Synfron.Staxe.Matcher.Data.IMatchData matchData, bool success, int _, int?_, string _) = LanguageMatchEngine.Match(code);

            Assert.True(success);

            InstructionGenerator generator = new InstructionGenerator();
            IList <Instruction <GroupState> > instructions = generator.Generate(matchData);

            InstructionOptimizer <GroupState> optimizer = new InstructionOptimizer <GroupState>();

            instructions = optimizer.Optimize(instructions).ToArray();

            GroupState groupState = new GroupState();

            groupState.Group.Instructions = instructions.ToArray();
            ExecutionState <GroupState> executionState = new ExecutionState <GroupState>(groupState);

            executor = executor ?? new InstructionExecutor <GroupState>()
            {
                ExternalDynamicPointers = NativeLocator.GetNativePointer,
                ValueProvider           = new ValueProvider()
            };
            PrintDiagnostics.EnableDiagnostics(code, executor, executionState, true);

            executor.Execute(executionState);

            return(executionState);
        }
예제 #2
0
        public void InstructionExecutor_Execute_AllExecutable()
        {
            InstructionExecutionBody <G> executionBody = Mock.Of <InstructionExecutionBody <G> >();
            Instruction <G> instruction = TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody);

            Group <G> group = new Group <G>
            {
                Instructions = new[]
                {
                    instruction,
                    instruction,
                    instruction,
                    instruction,
                    instruction,
                    instruction,
                    instruction
                }
            };
            G groupState     = Mock.Of <G>(m => m.Group == group);
            E executionState = new ExecutionState <G>(groupState);


            InstructionExecutor <G> sut = new InstructionExecutor <G>();

            sut.Execute(executionState);

            Assert.Equal(7, executionState.InstructionIndex);
            Mock.Get(executionBody).Verify(m => m(sut, executionState, It.IsAny <object[]>(), It.IsAny <StackList <ValuePointer <G> > >(), It.IsAny <StackList <StackValuePointer <G> > >()), Times.Exactly(7));
        }
예제 #3
0
        public void InstructionExecutor_Execute_NotExecutable_StopProcessing()
        {
            InstructionExecutionBody <G> executionBody        = Mock.Of <InstructionExecutionBody <G> >();
            InstructionExecutionBody <G> specialExecutionBody = Mock.Of <InstructionExecutionBody <G> >();
            Instruction <G> specialInstruction = TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, specialExecutionBody);

            Group <G> group = new Group <G>
            {
                Instructions = new[]
                {
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    specialInstruction,
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                }
            };
            G groupState = Mock.Of <G>(m => m.Group == group);

            Mock.Get(specialExecutionBody).Setup(m => m(It.IsAny <IInstructionExecutor <G> >(), It.IsAny <E>(), It.IsAny <object[]>(), It.IsAny <StackList <ValuePointer <G> > >(), It.IsAny <StackList <StackValuePointer <G> > >())).Callback((IInstructionExecutor <G> ie, ExecutionState <G> e, object[] payload, StackList <ValuePointer <G> > stackRegister, StackList <StackValuePointer <G> > stackPointers) =>
            {
                e.Executable = false;
            });
            E executionState = new ExecutionState <G>(groupState);


            InstructionExecutor <G> sut = new InstructionExecutor <G>();

            sut.Execute(executionState);

            Assert.Equal(4, executionState.InstructionIndex);
        }
예제 #4
0
        private static void Day12()
        {
            var instructions        = LineByLine.GetLines("day12/day12_input.txt");
            var instructionExecutor = new InstructionExecutor(instructions.ToArray());
            var valueOfRegisterA    = instructionExecutor.Execute();

            Console.WriteLine("Value of register A: " + valueOfRegisterA);
        }
예제 #5
0
        public void InstructionExecutor_Execute_WithInterrupts()
        {
            InstructionExecutionBody <G> interruptableExecutionBody   = Mock.Of <InstructionExecutionBody <G> >();
            InstructionExecutionBody <G> uninterruptableExecutionBody = Mock.Of <InstructionExecutionBody <G> >();
            Instruction <G> interruptableInstruction = TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, true, interruptableExecutionBody);

            Instruction <G> uninterruptableInstruction = TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, uninterruptableExecutionBody);

            Group <G> group = new Group <G>
            {
                Instructions = new[]
                {
                    uninterruptableInstruction,
                    uninterruptableInstruction,
                    uninterruptableInstruction,
                    interruptableInstruction,
                    uninterruptableInstruction,
                    uninterruptableInstruction,
                    uninterruptableInstruction
                }
            };
            G groupState     = Mock.Of <G>(m => m.Group == group);
            E executionState = new ExecutionState <G>(groupState);
            IInterrupt <G> inactiveInterrupt = Mock.Of <IInterrupt <G> >(m => m.Intersects(executionState) == false);

            IInterrupt <G>[] activeInterrupts = new IInterrupt <G>[]
            {
                Mock.Of <IInterrupt <G> >(m => m.Intersects(executionState) == true),
                Mock.Of <IInterrupt <G> >(m => m.Intersects(executionState) == true),
                Mock.Of <IInterrupt <G> >(m => m.Intersects(executionState) == true),
                Mock.Of <IInterrupt <G> >(m => m.Intersects(executionState) == true)
            };
            executionState.Interrupts.Add(inactiveInterrupt);
            executionState.Interrupts.Add(activeInterrupts[0]);
            executionState.Interrupts.Add(inactiveInterrupt);
            executionState.Interrupts.Add(activeInterrupts[1]);
            InterruptedHandler <G> interruptedHandler = Mock.Of <InterruptedHandler <G> >();

            InstructionExecutor <G> sut = new InstructionExecutor <G>();

            sut.Interrupts.Add(inactiveInterrupt);
            sut.Interrupts.Add(activeInterrupts[2]);
            sut.Interrupts.Add(inactiveInterrupt);
            sut.Interrupts.Add(activeInterrupts[3]);
            sut.Interrupted += interruptedHandler;
            Mock.Get(interruptedHandler).Setup(m => m(sut, It.IsAny <InterruptedEventArgs <G> >())).Callback((InstructionExecutor <G> sender, InterruptedEventArgs <G> args) =>
            {
                Assert.Equal(executionState, args.ExecutionState);
                Assert.Equal(activeInterrupts.OrderBy(i => i.GetHashCode()), args.Interrupts.OrderBy(i => i.GetHashCode()));
            });

            sut.Execute(executionState);

            Assert.Equal(7, executionState.InstructionIndex);
            Mock.Get(uninterruptableExecutionBody).Verify(m => m(sut, executionState, It.IsAny <object[]>(), It.IsAny <StackList <ValuePointer <G> > >(), It.IsAny <StackList <StackValuePointer <G> > >()), Times.Exactly(6));
            Mock.Get(interruptableExecutionBody).Verify(m => m(sut, executionState, It.IsAny <object[]>(), It.IsAny <StackList <ValuePointer <G> > >(), It.IsAny <StackList <StackValuePointer <G> > >()), Times.Once);
            Mock.Get(interruptedHandler).Verify(m => m(sut, It.IsAny <InterruptedEventArgs <G> >()), Times.Once);
        }
예제 #6
0
        private int ExecuteNextOpcode()
        {
            if (IsHalted)
            {
                executionContext.OpcodeBytes.Add(NOP_opcode);
                return(InstructionExecutor.Execute(NOP_opcode));
            }

            return(InstructionExecutor.Execute(FetchNextOpcode()));
        }
예제 #7
0
        private int AcceptPendingInterrupt()
        {
            if (executionContext.IsEiOrDiInstruction)
            {
                return(0);
            }

            if (NmiInterruptPending)
            {
                IsHalted       = false;
                Registers.IFF1 = 0;
                this.ExecuteCall(NmiServiceRoutine);
                return(11);
            }

            if (!InterruptsEnabled)
            {
                return(0);
            }

            var activeIntSource = InterruptSources.FirstOrDefault(s => s.IntLineIsActive);

            if (activeIntSource == null)
            {
                return(0);
            }

            Registers.IFF1 = 0;
            Registers.IFF2 = 0;
            IsHalted       = false;

            switch (InterruptMode)
            {
            case 0:
                var opcode = activeIntSource.ValueOnDataBus.GetValueOrDefault(0xFF);
                InstructionExecutor.Execute(opcode);
                return(13);

            case 1:
                InstructionExecutor.Execute(RST38h_opcode);
                return(13);

            case 2:
                var pointerAddress = NumberUtils.CreateShort(
                    lowByte: activeIntSource.ValueOnDataBus.GetValueOrDefault(0xFF),
                    highByte: Registers.I);
                var callAddress = NumberUtils.CreateShort(
                    lowByte: Memory[pointerAddress],
                    highByte: Memory[pointerAddress.Inc()]);
                this.ExecuteCall(callAddress.ToUShort());
                return(19);
            }

            return(0);
        }
예제 #8
0
        public void BooleanTests(string expression, bool expectedResult)
        {
            (Synfron.Staxe.Matcher.Data.IMatchData matchData, bool success, int _, int?_, string _) = LanguageMatchEngine.Match(expression);

            Assert.True(success);

            InstructionGenerator generator = new InstructionGenerator();
            IList <Instruction <GroupState> > instructions = generator.Generate(matchData);

            InstructionOptimizer <GroupState> optimizer = new InstructionOptimizer <GroupState>();

            instructions = optimizer.Optimize(instructions);
            GroupState groupState = new GroupState();

            groupState.Group.Instructions = instructions.ToArray();
            ExecutionState <GroupState>      executionState = new ExecutionState <GroupState>(groupState);
            InstructionExecutor <GroupState> executor       = new InstructionExecutor <GroupState>();

            executor.Execute(executionState);

            Assert.Equal(expectedResult, ((DefaultBooleanValue <GroupState>)executionState.ListRegister.Last().Value).Data);
        }
예제 #9
0
        public void InstructionExecutor_Execute_Exception_RethrownAsEngineRuntimeException()
        {
            InstructionExecutionBody <G> specialExecutionBody = Mock.Of <InstructionExecutionBody <G> >();
            InstructionExecutionBody <G> executionBody        = Mock.Of <InstructionExecutionBody <G> >();
            int             sourcePosition     = 20;
            Exception       thrownException    = new Exception("Engine exception");
            Instruction <G> specialInstruction = TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, sourcePosition, false, specialExecutionBody);

            Group <G> group = new Group <G>
            {
                Instructions = new[]
                {
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    specialInstruction,
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody),
                    TestInstructionProvider <G> .GetInstruction(InstructionCode.NON, null, null, false, executionBody)
                }
            };
            G groupState = Mock.Of <G>(m => m.Group == group);

            Mock.Get(specialExecutionBody).Setup(m => m(It.IsAny <IInstructionExecutor <G> >(), It.IsAny <E>(), It.IsAny <object[]>(), It.IsAny <StackList <ValuePointer <G> > >(), It.IsAny <StackList <StackValuePointer <G> > >())).Callback((IInstructionExecutor <G> ie, ExecutionState <G> e, object[] payload, StackList <ValuePointer <G> > stackRegister, StackList <StackValuePointer <G> > stackPointers) =>
            {
                throw thrownException;
            });
            E executionState = new ExecutionState <G>(groupState);


            InstructionExecutor <G> sut = new InstructionExecutor <G>();
            EngineRuntimeException  ex  = Assert.Throws <EngineRuntimeException>(() => sut.Execute(executionState));

            Assert.Equal("Runtime execution error", ex.Message);
            Assert.Equal(thrownException, ex.InnerException);
            Assert.Equal(sourcePosition, ex.Position);
        }