"""CPU functionality."""

import sys


class CPU:
    """Main CPU class."""

    def __init__(self):
        """Construct a new CPU."""
        self.ram = [0] * 256
        self.reg = [0] * 8
        self.pc = 0

    def ram_read(self, MAR):
        return self.ram[MAR]

    def ram_write(self, MAR, MDR):
        self.ram[MAR] = MDR

    def load(self, file):
        """Load a program into memory."""
        with open(file) as f:
            for x in f:
                #print(int(x[0:8], 2))
                self.ram[self.pc] = int(x[0:8], 2)
                self.pc += 1

    def alu(self, op, reg_a, reg_b):
        """ALU operations."""

        if op == "ADD":
            self.reg[reg_a] += self.reg[reg_b]
        elif op == "MUL":
            self.reg[reg_a] *= self.reg[reg_b]
        else:
            raise Exception("Unsupported ALU operation")

    def trace(self):
        """
        Handy function to print out the CPU state. You might want to call this
        from run() if you need help debugging.
        """

        print(f"TRACE: %02X | %02X %02X %02X |" % (
            self.pc,
            # self.fl,
            # self.ie,
            self.ram_read(self.pc),
            self.ram_read(self.pc + 1),
            self.ram_read(self.pc + 2)
        ), end='')

        for i in range(8):
            print(" %02X" % self.reg[i], end='')

        print()

    def run(self):
        """Run the CPU."""
        self.pc = 0
        self.reg[7] = 0xf4
        IR = self.ram[self.pc]
        HLT = 0b00000001
        LDI = 0b10000010
        PRN = 0b01000111
        MUL = 0b10100010
        PUSH = 0b01000101
        POP = 0b01000110

        while True:
            if IR == HLT:
                break
            elif IR == LDI:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.reg[operand_a] = operand_b
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PRN:
                operand_a = self.ram[self.pc + 1]
                print(self.reg[operand_a])
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == MUL:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.alu('MUL', operand_a, operand_b)
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PUSH:
                operand_a = self.reg[self.ram[self.pc + 1]]
                self.reg[7] -= 1
                self.ram[self.reg[7]] = operand_a
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == POP:
                self.reg[self.ram[self.pc + 1]] = self.ram[self.reg[7]]
                self.reg[7] += 1
                self.pc += 2
                IR = self.ram[self.pc]
            else:
                print("Unknown instruction")
                sys.exit(1)

c7afe3a3a95b09bda98b4cb8514c10d00ab75cbd
<mask token>


class CPU:
    <mask token>

    def __init__(self):
        """Construct a new CPU."""
        self.ram = [0] * 256
        self.reg = [0] * 8
        self.pc = 0

    def ram_read(self, MAR):
        return self.ram[MAR]
    <mask token>

    def load(self, file):
        """Load a program into memory."""
        with open(file) as f:
            for x in f:
                self.ram[self.pc] = int(x[0:8], 2)
                self.pc += 1
    <mask token>

    def trace(self):
        """
        Handy function to print out the CPU state. You might want to call this
        from run() if you need help debugging.
        """
        print(f'TRACE: %02X | %02X %02X %02X |' % (self.pc, self.ram_read(
            self.pc), self.ram_read(self.pc + 1), self.ram_read(self.pc + 2
            )), end='')
        for i in range(8):
            print(' %02X' % self.reg[i], end='')
        print()

    def run(self):
        """Run the CPU."""
        self.pc = 0
        self.reg[7] = 244
        IR = self.ram[self.pc]
        HLT = 1
        LDI = 130
        PRN = 71
        MUL = 162
        PUSH = 69
        POP = 70
        while True:
            if IR == HLT:
                break
            elif IR == LDI:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.reg[operand_a] = operand_b
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PRN:
                operand_a = self.ram[self.pc + 1]
                print(self.reg[operand_a])
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == MUL:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.alu('MUL', operand_a, operand_b)
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PUSH:
                operand_a = self.reg[self.ram[self.pc + 1]]
                self.reg[7] -= 1
                self.ram[self.reg[7]] = operand_a
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == POP:
                self.reg[self.ram[self.pc + 1]] = self.ram[self.reg[7]]
                self.reg[7] += 1
                self.pc += 2
                IR = self.ram[self.pc]
            else:
                print('Unknown instruction')
                sys.exit(1)

<mask token>


class CPU:
    <mask token>

    def __init__(self):
        """Construct a new CPU."""
        self.ram = [0] * 256
        self.reg = [0] * 8
        self.pc = 0

    def ram_read(self, MAR):
        return self.ram[MAR]

    def ram_write(self, MAR, MDR):
        self.ram[MAR] = MDR

    def load(self, file):
        """Load a program into memory."""
        with open(file) as f:
            for x in f:
                self.ram[self.pc] = int(x[0:8], 2)
                self.pc += 1

    def alu(self, op, reg_a, reg_b):
        """ALU operations."""
        if op == 'ADD':
            self.reg[reg_a] += self.reg[reg_b]
        elif op == 'MUL':
            self.reg[reg_a] *= self.reg[reg_b]
        else:
            raise Exception('Unsupported ALU operation')

    def trace(self):
        """
        Handy function to print out the CPU state. You might want to call this
        from run() if you need help debugging.
        """
        print(f'TRACE: %02X | %02X %02X %02X |' % (self.pc, self.ram_read(
            self.pc), self.ram_read(self.pc + 1), self.ram_read(self.pc + 2
            )), end='')
        for i in range(8):
            print(' %02X' % self.reg[i], end='')
        print()

    def run(self):
        """Run the CPU."""
        self.pc = 0
        self.reg[7] = 244
        IR = self.ram[self.pc]
        HLT = 1
        LDI = 130
        PRN = 71
        MUL = 162
        PUSH = 69
        POP = 70
        while True:
            if IR == HLT:
                break
            elif IR == LDI:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.reg[operand_a] = operand_b
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PRN:
                operand_a = self.ram[self.pc + 1]
                print(self.reg[operand_a])
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == MUL:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.alu('MUL', operand_a, operand_b)
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PUSH:
                operand_a = self.reg[self.ram[self.pc + 1]]
                self.reg[7] -= 1
                self.ram[self.reg[7]] = operand_a
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == POP:
                self.reg[self.ram[self.pc + 1]] = self.ram[self.reg[7]]
                self.reg[7] += 1
                self.pc += 2
                IR = self.ram[self.pc]
            else:
                print('Unknown instruction')
                sys.exit(1)

<mask token>


class CPU:
    """Main CPU class."""

    def __init__(self):
        """Construct a new CPU."""
        self.ram = [0] * 256
        self.reg = [0] * 8
        self.pc = 0

    def ram_read(self, MAR):
        return self.ram[MAR]

    def ram_write(self, MAR, MDR):
        self.ram[MAR] = MDR

    def load(self, file):
        """Load a program into memory."""
        with open(file) as f:
            for x in f:
                self.ram[self.pc] = int(x[0:8], 2)
                self.pc += 1

    def alu(self, op, reg_a, reg_b):
        """ALU operations."""
        if op == 'ADD':
            self.reg[reg_a] += self.reg[reg_b]
        elif op == 'MUL':
            self.reg[reg_a] *= self.reg[reg_b]
        else:
            raise Exception('Unsupported ALU operation')

    def trace(self):
        """
        Handy function to print out the CPU state. You might want to call this
        from run() if you need help debugging.
        """
        print(f'TRACE: %02X | %02X %02X %02X |' % (self.pc, self.ram_read(
            self.pc), self.ram_read(self.pc + 1), self.ram_read(self.pc + 2
            )), end='')
        for i in range(8):
            print(' %02X' % self.reg[i], end='')
        print()

    def run(self):
        """Run the CPU."""
        self.pc = 0
        self.reg[7] = 244
        IR = self.ram[self.pc]
        HLT = 1
        LDI = 130
        PRN = 71
        MUL = 162
        PUSH = 69
        POP = 70
        while True:
            if IR == HLT:
                break
            elif IR == LDI:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.reg[operand_a] = operand_b
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PRN:
                operand_a = self.ram[self.pc + 1]
                print(self.reg[operand_a])
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == MUL:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.alu('MUL', operand_a, operand_b)
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PUSH:
                operand_a = self.reg[self.ram[self.pc + 1]]
                self.reg[7] -= 1
                self.ram[self.reg[7]] = operand_a
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == POP:
                self.reg[self.ram[self.pc + 1]] = self.ram[self.reg[7]]
                self.reg[7] += 1
                self.pc += 2
                IR = self.ram[self.pc]
            else:
                print('Unknown instruction')
                sys.exit(1)

<mask token>
import sys


class CPU:
    """Main CPU class."""

    def __init__(self):
        """Construct a new CPU."""
        self.ram = [0] * 256
        self.reg = [0] * 8
        self.pc = 0

    def ram_read(self, MAR):
        return self.ram[MAR]

    def ram_write(self, MAR, MDR):
        self.ram[MAR] = MDR

    def load(self, file):
        """Load a program into memory."""
        with open(file) as f:
            for x in f:
                self.ram[self.pc] = int(x[0:8], 2)
                self.pc += 1

    def alu(self, op, reg_a, reg_b):
        """ALU operations."""
        if op == 'ADD':
            self.reg[reg_a] += self.reg[reg_b]
        elif op == 'MUL':
            self.reg[reg_a] *= self.reg[reg_b]
        else:
            raise Exception('Unsupported ALU operation')

    def trace(self):
        """
        Handy function to print out the CPU state. You might want to call this
        from run() if you need help debugging.
        """
        print(f'TRACE: %02X | %02X %02X %02X |' % (self.pc, self.ram_read(
            self.pc), self.ram_read(self.pc + 1), self.ram_read(self.pc + 2
            )), end='')
        for i in range(8):
            print(' %02X' % self.reg[i], end='')
        print()

    def run(self):
        """Run the CPU."""
        self.pc = 0
        self.reg[7] = 244
        IR = self.ram[self.pc]
        HLT = 1
        LDI = 130
        PRN = 71
        MUL = 162
        PUSH = 69
        POP = 70
        while True:
            if IR == HLT:
                break
            elif IR == LDI:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.reg[operand_a] = operand_b
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PRN:
                operand_a = self.ram[self.pc + 1]
                print(self.reg[operand_a])
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == MUL:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.alu('MUL', operand_a, operand_b)
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PUSH:
                operand_a = self.reg[self.ram[self.pc + 1]]
                self.reg[7] -= 1
                self.ram[self.reg[7]] = operand_a
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == POP:
                self.reg[self.ram[self.pc + 1]] = self.ram[self.reg[7]]
                self.reg[7] += 1
                self.pc += 2
                IR = self.ram[self.pc]
            else:
                print('Unknown instruction')
                sys.exit(1)

"""CPU functionality."""

import sys


class CPU:
    """Main CPU class."""

    def __init__(self):
        """Construct a new CPU."""
        self.ram = [0] * 256
        self.reg = [0] * 8
        self.pc = 0

    def ram_read(self, MAR):
        return self.ram[MAR]

    def ram_write(self, MAR, MDR):
        self.ram[MAR] = MDR

    def load(self, file):
        """Load a program into memory."""
        with open(file) as f:
            for x in f:
                #print(int(x[0:8], 2))
                self.ram[self.pc] = int(x[0:8], 2)
                self.pc += 1

    def alu(self, op, reg_a, reg_b):
        """ALU operations."""

        if op == "ADD":
            self.reg[reg_a] += self.reg[reg_b]
        elif op == "MUL":
            self.reg[reg_a] *= self.reg[reg_b]
        else:
            raise Exception("Unsupported ALU operation")

    def trace(self):
        """
        Handy function to print out the CPU state. You might want to call this
        from run() if you need help debugging.
        """

        print(f"TRACE: %02X | %02X %02X %02X |" % (
            self.pc,
            # self.fl,
            # self.ie,
            self.ram_read(self.pc),
            self.ram_read(self.pc + 1),
            self.ram_read(self.pc + 2)
        ), end='')

        for i in range(8):
            print(" %02X" % self.reg[i], end='')

        print()

    def run(self):
        """Run the CPU."""
        self.pc = 0
        self.reg[7] = 0xf4
        IR = self.ram[self.pc]
        HLT = 0b00000001
        LDI = 0b10000010
        PRN = 0b01000111
        MUL = 0b10100010
        PUSH = 0b01000101
        POP = 0b01000110

        while True:
            if IR == HLT:
                break
            elif IR == LDI:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.reg[operand_a] = operand_b
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PRN:
                operand_a = self.ram[self.pc + 1]
                print(self.reg[operand_a])
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == MUL:
                operand_a = self.ram[self.pc + 1]
                operand_b = self.ram[self.pc + 2]
                self.alu('MUL', operand_a, operand_b)
                self.pc += 3
                IR = self.ram[self.pc]
            elif IR == PUSH:
                operand_a = self.reg[self.ram[self.pc + 1]]
                self.reg[7] -= 1
                self.ram[self.reg[7]] = operand_a
                self.pc += 2
                IR = self.ram[self.pc]
            elif IR == POP:
                self.reg[self.ram[self.pc + 1]] = self.ram[self.reg[7]]
                self.reg[7] += 1
                self.pc += 2
                IR = self.ram[self.pc]
            else:
                print("Unknown instruction")
                sys.exit(1)
