Пример #1
0
        public ExecuteAction Step()
        {
            Instruction nextInstruction = NextInstruction;

            Trace?.TraceInformation("[{0}] {1}", ProgramCounter, nextInstruction);

            var args = new InstructionEventArgs()
            {
                Instruction = nextInstruction
            };

            Executing?.Invoke(this, args);

            if (args.Action == ExecuteAction.Break)
            {
                return(args.Action);
            }

            this.Operations[nextInstruction.Opcode](nextInstruction.Operand);

            Executed?.Invoke(this, args);

            if (!IsHalted)
            {
                if (nextInstruction.Opcode != OpCode.JMP &&
                    nextInstruction.Opcode != OpCode.TAC)
                {
                    ProgramCounter++;
                }
            }
            else
            {
                Halted?.Invoke(this, EventArgs.Empty);
            }

            return(args.Action);
        }
Пример #2
0
        public void Run()
        {
            BigInteger iptr = 0;

            while (true)
            {
                var opCode = Memory[(int)iptr].ToString("D2");

                var parameterModes = opCode.Length > 2 ? opCode.Substring(0, opCode.Length - 2) : "";

                if (opCode.EndsWith(OpCodeAdd))
                {
                    var modes = ParseParameterModes(parameterModes, 3);
                    var a     = GetValueFromMemory(iptr + 1, modes[0]);
                    var b     = GetValueFromMemory(iptr + 2, modes[1]);
                    checked
                    {
                        SetValueInMemory(a + b, iptr + 3, modes[2]);
                    }
                    iptr += 4;
                }
                else if (opCode.EndsWith(OpCodeMultiply))
                {
                    var modes = ParseParameterModes(parameterModes, 3);
                    var a     = GetValueFromMemory(iptr + 1, modes[0]);
                    var b     = GetValueFromMemory(iptr + 2, modes[1]);
                    checked
                    {
                        SetValueInMemory(a * b, iptr + 3, modes[2]);
                    }
                    iptr += 4;
                }
                else if (opCode.EndsWith(OpCodeInput))
                {
                    while (StdIn.Count == 0)
                    {
                        Thread.Sleep(1);
                    }

                    StdIn.TryDequeue(out var input);

                    var modes = ParseParameterModes(parameterModes, 1);
                    SetValueInMemory(input, iptr + 1, modes[0]);
                    iptr += 2;
                }
                else if (opCode.EndsWith(OpCodeOutput))
                {
                    var modes  = ParseParameterModes(parameterModes, 1);
                    var output = GetValueFromMemory(iptr + 1, modes[0]);
                    StdOut.Enqueue(output);
                    iptr += 2;
                }
                else if (opCode.EndsWith(OpCodeJumpIfNotZero))
                {
                    var modes = ParseParameterModes(parameterModes, 2);
                    var value = GetValueFromMemory(iptr + 1, modes[0]);
                    if (value != 0)
                    {
                        var jumpAddress = GetValueFromMemory(iptr + 2, modes[1]);
                        iptr = jumpAddress;
                    }
                    else
                    {
                        iptr += 3;
                    }
                }
                else if (opCode.EndsWith(OpCodeJumpIfZero))
                {
                    var modes = ParseParameterModes(parameterModes, 2);
                    var value = GetValueFromMemory(iptr + 1, modes[0]);
                    if (value == 0)
                    {
                        var jumpAddress = GetValueFromMemory(iptr + 2, modes[1]);
                        iptr = jumpAddress;
                    }
                    else
                    {
                        iptr += 3;
                    }
                }
                else if (opCode.EndsWith(OpCodeLessThan))
                {
                    var modes = ParseParameterModes(parameterModes, 3);
                    var a     = GetValueFromMemory(iptr + 1, modes[0]);
                    var b     = GetValueFromMemory(iptr + 2, modes[1]);
                    if (a < b)
                    {
                        SetValueInMemory(1, iptr + 3, modes[2]);
                    }
                    else
                    {
                        SetValueInMemory(0, iptr + 3, modes[2]);
                    }
                    iptr += 4;
                }
                else if (opCode.EndsWith(OpCodeEquals))
                {
                    var modes = ParseParameterModes(parameterModes, 3);
                    var a     = GetValueFromMemory(iptr + 1, modes[0]);
                    var b     = GetValueFromMemory(iptr + 2, modes[1]);
                    if (a == b)
                    {
                        SetValueInMemory(1, iptr + 3, modes[2]);
                    }
                    else
                    {
                        SetValueInMemory(0, iptr + 3, modes[2]);
                    }
                    iptr += 4;
                }
                else if (opCode.EndsWith(OpCodeRelativeBaseOffset))
                {
                    var modes  = ParseParameterModes(parameterModes, 1);
                    var offset = GetValueFromMemory(iptr + 1, modes[0]);
                    RelativeBaseAddress += offset;
                    iptr += 2;
                }
                else if (opCode.EndsWith(OpCodeBreak))
                {
                    Halted?.Invoke();
                    break;
                }
                else
                {
                    throw new System.Exception();
                }
            }
        }