コード例 #1
0
        public IList <long> Run()
        {
            if (_memory == null)
            {
                throw new Exception($"You must load a program first using {nameof(Computer)}.{nameof(Load)}");
            }

            Running = true;

            while (Running && _instructionPointer < _memory.Count)
            {
                var instruction     = new Instruction(_memory[(int)_instructionPointer]);
                var parameterValues = GetParameterValues(instruction);

                long index;
                var  jmp = false;
                switch (instruction.Op)
                {
                case OpCode.Add:
                    index = GetIndex(parameterValues[2]);
                    ExtendMemoryIfRequired(index);
                    _memory[(int)index] = GetValue(parameterValues[0]) + GetValue(parameterValues[1]);
                    break;

                case OpCode.Multiply:
                    index = GetIndex(parameterValues[2]);
                    ExtendMemoryIfRequired(index);
                    _memory[(int)index] = GetValue(parameterValues[0]) * GetValue(parameterValues[1]);
                    break;

                case OpCode.Save:
                    index = GetIndex(parameterValues[0]);
                    ExtendMemoryIfRequired(index);
                    var input = InputModule.InputCallback();
                    _memory[(int)index] = input;
                    break;

                case OpCode.Output:
                    var outputValue = GetValue(parameterValues[0]);
                    OutputModule.OutputCallback(outputValue);
                    break;

                case OpCode.JmpT:
                    jmp = GetValue(parameterValues[0]) > 0;
                    if (jmp)
                    {
                        _instructionPointer = GetValue(parameterValues[1]);
                    }
                    break;

                case OpCode.JmpF:
                    jmp = GetValue(parameterValues[0]) == 0;
                    if (jmp)
                    {
                        _instructionPointer = GetValue(parameterValues[1]);
                    }
                    break;

                case OpCode.LessThan:
                    var lt = GetValue(parameterValues[0]) < GetValue(parameterValues[1]);
                    index = GetIndex(parameterValues[2]);
                    ExtendMemoryIfRequired(index);
                    _memory[(int)index] = lt ? 1 : 0;;
                    break;

                case OpCode.Eql:
                    var eql = GetValue(parameterValues[0]) == GetValue(parameterValues[1]);
                    index = GetIndex(parameterValues[2]);
                    ExtendMemoryIfRequired(index);
                    var toStore = eql ? 1 : 0;
                    _memory[(int)index] = toStore;
                    break;

                case OpCode.Halt:
                    Halted = true;
                    return(_memory);

                case OpCode.SetRbo:
                    _rbo += GetValue(parameterValues[0]);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (!jmp)
                {
                    _instructionPointer += instruction.ParameterModes.Count + 1;
                }
            }

            return(_memory);
        }