public OpCode GetOpCode(byte opCode) { if (!OpCodeDictionary.ContainsKey(opCode)) { return(null); } return(OpCodeDictionary[opCode]); }
internal void Process() { while (!Ended) { long num1 = 0, num2 = 0, update_place = 0; int opcode = 0; long instruction_val = memory[instruction_pointer]; string instruct = instruction_val.ToString("0000"); int[] instruction = instruct.Select(c => Convert.ToInt32(c.ToString())).ToArray(); opcode = instruction[instruction.Length - 1] + instruction[instruction.Length - 2] * 10; int param_count = OpCodeDictionary.GetOpcodeInstructionCount(opcode) - 1; long addr(int i) { return(GetMode(instruction_pointer, i) switch { ParameterModes.Position => memory[instruction_pointer + i], ParameterModes.Immediate => instruction_pointer + i, ParameterModes.Relative => relativeBase + memory[instruction_pointer + i], _ => throw new ArgumentException() }); } long arg(int i) => memory[addr(i)]; if (opcode != OpCodes.End) { num1 = memory[instruction_pointer + 1]; num2 = memory[instruction_pointer + 2]; } bool pointer_modified = false; if (opcode == OpCodes.Add || opcode == OpCodes.Multiply || opcode == OpCodes.LessThan || opcode == OpCodes.Equal) { update_place = memory[instruction_pointer + 3]; //Parameters that an instruction writes to will never be in immediate mode. } switch (opcode) { case OpCodes.Add: memory[addr(3)] = arg(1) + arg(2); break; case OpCodes.Multiply: memory[addr(3)] = arg(1) * arg(2); break; case OpCodes.SaveInput: if (loadedProgram == AvailablePrograms.Amplification) { int input = 0; if (inputCount > 0) { input = inputParameters[1]; } else { input = inputParameters[inputCount]; } memory[addr(1)] = input; } else { Console.WriteLine("Please Enter Input:"); int input = Convert.ToInt32(Console.ReadLine()); memory[addr(1)] = input; } inputCount++; break; case OpCodes.ReturnOutput: Outputs.Add(arg(1)); break; case OpCodes.JumpIfTrue: instruction_pointer = arg(1) != 0 ? arg(2) : instruction_pointer + 3; pointer_modified = true; break; case OpCodes.JumpIfFalse: instruction_pointer = arg(1) == 0 ? arg(2) : instruction_pointer + 3; pointer_modified = true; break; case OpCodes.LessThan: memory[addr(3)] = arg(1) < arg(2) ? 1 : 0; break; case OpCodes.Equal: memory[addr(3)] = arg(1) == arg(2) ? 1 : 0; break; case OpCodes.AdjustRelativeBaseOffset: relativeBase += arg(1); break; case OpCodes.End: Ended = true; return; default: throw new ArgumentException("invalid opcode " + opcode); } if (!pointer_modified) { instruction_pointer = instruction_pointer + OpCodeDictionary.GetOpcodeInstructionCount(opcode); } }