public static OpcodeInstruction FromLine(string line)
        {
            OpcodeInstruction op = new OpcodeInstruction();

            op.LineOrigin = line;

            string[] parts = line.Split(' ');
            op.Argument = Int32.Parse(parts[1]);
            switch (parts[0])
            {
            case "nop":
                op.Action     = op.NoOperation;
                op.FlipAction = op.Jump;
                op.Undo       = op.UndoNoOperation;
                op.UndoFlip   = op.UndoJump;
                break;

            case "acc":
                op.Action = op.Accumulate;
                op.Undo   = op.UndoAccumulate;
                break;

            case "jmp":
                op.Action     = op.Jump;
                op.FlipAction = op.NoOperation;
                op.Undo       = op.UndoJump;
                op.UndoFlip   = op.UndoNoOperation;
                break;
            }

            return(op);
        }
Beispiel #2
0
 private void ExecuteOrThrow(OpcodeInstruction opcode)
 {
     if (opcode.AlreadyExecuted)
     {
         throw new OpcodeAlreadyExecutedException(Accumulator, InstructionPointer, Opcodes[InstructionPointer]);
     }
     Execute(opcode);
 }
Beispiel #3
0
 private void ExecuteOrRewindAndBranch(OpcodeInstruction opcode)
 {
     if (opcode.AlreadyExecuted)
     {
         Console.WriteLine($"Blocked at IP {InstructionPointer}. Undoing...");
         OpcodeInstruction previousOpcode;
         do
         {
             previousOpcode = OpcodeHistory.Pop();
             previousOpcode.AlreadyExecuted = false;
             previousOpcode.Undo(this);
             Console.WriteLine("Undoing {" + InstructionPointer + "} " + previousOpcode);
         } while (!previousOpcode.IsJumpOrNop());
         while (true)
         {
             Console.WriteLine("Flipping {" + InstructionPointer + "} " + previousOpcode);
             previousOpcode.AlreadyExecuted = true;
             previousOpcode.FlipAction(this);
             OpcodeHistory.Push(previousOpcode);
             try
             {
                 RunUntilTheEnd();
                 Console.WriteLine("Run successful, accumulator is " + Accumulator);
                 return;
             }
             catch (Exception)
             {
                 OpcodeInstruction branchOpCode = OpcodeHistory.Pop();
                 while (branchOpCode != previousOpcode)
                 {
                     branchOpCode.AlreadyExecuted = false;
                     branchOpCode.Undo(this);
                     Console.WriteLine("Undoing {" + InstructionPointer + "} " + branchOpCode);
                     branchOpCode = OpcodeHistory.Pop();
                 }
                 branchOpCode.AlreadyExecuted = false;
                 Console.WriteLine("Undoing flip {" + InstructionPointer + "} " + branchOpCode);
                 branchOpCode.UndoFlip(this);
                 do
                 {
                     previousOpcode = OpcodeHistory.Pop();
                     previousOpcode.AlreadyExecuted = false;
                     previousOpcode.Undo(this);
                     Console.WriteLine("Undoing {" + InstructionPointer + "} " + previousOpcode);
                 } while (!previousOpcode.IsJumpOrNop());
             }
         }
     }
     else
     {
         Console.WriteLine("Doing {" + InstructionPointer + "} " + opcode);
         Execute(opcode);
     }
 }
Beispiel #4
0
 public OpcodeAlreadyExecutedException(int accumulator, int instructionPointer, OpcodeInstruction opcode)
 {
     Accumulator        = accumulator;
     InstructionPointer = instructionPointer;
     Opcode             = opcode;
 }
Beispiel #5
0
 private void Execute(OpcodeInstruction opcode)
 {
     OpcodeHistory.Push(opcode);
     opcode.AlreadyExecuted = true;
     opcode.Action(this);
 }