예제 #1
0
 public void Halt(HaltReason reason = HaltReason.HaltCalledDirectly)
 {
     if (!_halted)
     {
         _halted            = true;
         _reasonForLastHalt = reason;
         OnHalt?.Invoke(null, reason);
     }
 }
예제 #2
0
        private void Run()
        {
            while (true)
            {
                switch (GetValue(Pointer) % 100)
                {
                case 1: // Addition
                    SetResult(3, GetParam(1) + GetParam(2));
                    break;

                case 2: // Multiplication
                    SetResult(3, GetParam(1) * GetParam(2));
                    break;

                case 3: // Input
                    if (WantsInput != null)
                    {
                        Inputs.Enqueue(WantsInput.Invoke());
                    }
                    if (!Inputs.Any())
                    {
                        OnYield?.Invoke();
                        return;
                    }
                    SetResult(1, Inputs.Dequeue());
                    break;

                case 4: // Output
                    Output   = GetParam(1);
                    Pointer += 2;
                    OnOutput?.Invoke(Output);
                    break;

                case 5: // Jump-If-True
                    Pointer = GetParam(1) == 0 ? Pointer + 3 : (int)GetParam(2);
                    break;

                case 6: // Jump-If-False
                    Pointer = GetParam(1) != 0 ? Pointer + 3 : (int)GetParam(2);
                    break;

                case 7: // Less-Than
                    SetResult(3, GetParam(1) < GetParam(2) ? 1 : 0);
                    break;

                case 8: // Equals
                    SetResult(3, GetParam(1) == GetParam(2) ? 1 : 0);
                    break;

                case 9: // Adjust-Relative-Base
                    RelativeBase += (int)GetParam(1);
                    Pointer      += 2;
                    break;

                case 99:
                    OnHalt?.Invoke();
                    return;

                default:
                    throw new InvalidOperationException(
                              $"Invalid instruction: {Program[Pointer]}");
                }
            }
        }