If Statement Continuously Running and Never Completing Content Within

  Kiến thức lập trình

I am creating a Virtual Machine (VM) with Python, I am currently working on adding to my Assembly Instructions but more specifically adding IF statements. Currently my CPU gets stuck in a loop and never fully computing the IF statements (infinitely repeating my debug statement of fetching {instruction}), I need help fixing this problem.

I tried adding a few debug print statements within the IF to figure out where it all went wrong but couldn’t deduce a place or how the problem happened. I checked a few sites like Stackoverflow to see if a similar question had popped up but I found nothing. I also asked ChatGPT to see if it was able to fix the issue, but nothing worked.

computer.py

import pygame
import os

class RAM:
    def __init__(self, size):
        self.memory = [0] * size
        self.variables = {}
        os.system('cls' if os.name == 'nt' else 'clear')
        print("Running [INSERT_NAME]...")

    def write(self, address_or_name, value):
        if isinstance(address_or_name, str):  # Handle variables
            self.variables[address_or_name] = value  # No conversion to int here
        else:  # Handle memory addresses
            if 0 <= address_or_name < len(self.memory):
                self.memory[address_or_name] = value

    def read(self, address_or_name):
        if isinstance(address_or_name, str):  # Handle variables
            value = self.variables.get(address_or_name, 0)
            return value
        else:  # Handle memory addresses
            if 0 <= address_or_name < len(self.memory):
                return self.memory[address_or_name]
            else:
                print(f"Error: Attempted to read from an invalid address {address_or_name}")
                return 0

    def load_program_from_file(self, filename):
        try:
            with open(filename, 'r') as f:
                lines = f.read().splitlines()
                address = 0
                for line in lines:
                    line = line.split(';')[0].strip()  # Remove comments and trim whitespace
                    if line:
                        self.memory[address] = line
                        address += 1
        except FileNotFoundError:
            print(f"Error: File {filename} not found")
        except Exception as e:
            print(f"Error: {e}")

class CPU:
    def __init__(self, ram, display_surface):
        self.ram = ram
        self.registers = {
            'A': 0, 
            'PC': 0,
        }
        self.running = True
        self.display_surface = display_surface
        self.in_if_block = False
        self.execute_if_block = False
        self.skip_until_end = False

    def fetch(self):
        pc = self.registers['PC']
        if 0 <= pc < len(self.ram.memory):
            instruction = self.ram.read(pc)
            print(f"Fetched instruction: {instruction}")  # For debugging
            return instruction
        else:
            print(f"Error: Program Counter {pc} is out of range")
            self.running = False
            return None

    def execute(self, instruction):
        instruction = str(instruction).strip()

        if self.in_if_block:
            if instruction == 'THEN':
                return  # Just skip 'THEN' line
            elif instruction == 'END':
                self.in_if_block = False
                self.skip_until_end = False
            elif self.execute_if_block:
                if instruction.startswith('DRAW'):
                    self.perform_draw()
            elif self.skip_until_end:
                return  # Just skip until END

        elif instruction.startswith('IF'):
            print("if block detected")  # For debugging
            self.in_if_block = True
            parts = instruction.split()

            if len(parts) >= 5:  # Adjust to make sure it has enough parts
                var_name = parts[2]
                operator = parts[3]
                value = int(parts[4])

                var_value = int(self.ram.read(var_name))
                print(f"Condition check: {var_value} {operator} {value}")  # Debugging

                condition_met = False
                if operator == '>':
                    condition_met = var_value > value
                elif operator == '<':
                    condition_met = var_value < value
                elif operator == '>=':
                    condition_met = var_value >= value
                elif operator == '<=':
                    condition_met = var_value <= value
                elif operator == '==':
                    condition_met = var_value == value
                elif operator == '!=':
                    condition_met = var_value != value

                self.execute_if_block = condition_met
                self.skip_until_end = not condition_met

        elif instruction.startswith('SET'):
            var_name = self.ram.read(self.registers['PC'] + 1)  # Get the variable name from the next memory address
            value = int(self.ram.read(self.registers['PC'] + 2))  # Get the value from the following memory address
            self.ram.write(var_name, value)  # Write the value to the variable in RAM
            self.registers['PC'] += 3  # Increment PC by 3 to move past the SET command and its parameters

        elif instruction.startswith('LOAD'):
            var_name = instruction.split()[1]
            self.registers['A'] = int(self.ram.read(var_name))

        elif instruction.startswith('DRAW'):
            self.perform_draw()

        elif instruction == 'HALT':
            print("Halting CPU...")
            self.running = False

        else:
            pass

    def perform_draw(self):
        x_value = self.ram.read(self.registers['PC'] + 1)
        y_value = self.ram.read(self.registers['PC'] + 2)
        color = self.ram.read(self.registers['PC'] + 3)

        try:
            x_value = int(self.ram.read(self.registers['PC'] + 1))
        except Exception:
            x_value = self.ram.read(self.registers['PC'] + 1)

        try:
            y_value = int(self.ram.read(self.registers['PC'] + 2))
        except Exception:
            y_value = self.ram.read(self.registers['PC'] + 2)

        if isinstance(x_value, str):
            x_value = int(self.ram.read(x_value))
        if isinstance(y_value, str):
            y_value = int(self.ram.read(y_value))

        color = int(color)
        if color not in [0, 1]:
            print(f"Error: Invalid color index: {color}.")
            return

        self.draw_pixel(x_value, y_value, color)
        self.registers['PC'] += 4  # Move past the DRAW command and its parameters

    def draw_pixel(self, x, y, color):
        colors = [(0, 0, 0), (255, 255, 255)]  # 0 = Black, 1 = White
        if 0 <= x < self.display_surface.get_width() and 0 <= y < self.display_surface.get_height():
            self.display_surface.set_at((x, y), colors[color])
        else:
            print(f"Attempted to draw pixel at out of bounds ({x}, {y}).")

    def run(self):
        while self.running:
            instruction = self.fetch()
            if instruction:
                self.execute(instruction)
            pygame.display.update()

program.asm

SET
x_coord
10

SET 
y_coord 
15

IF 
LOAD x_coord > 11 
THEN
    DRAW 
    LOAD x_coord
    LOAD y_coord 
    1
END

DRAW
1
1
1

HALT

main.py

import pygame
import sys
import computer

# Initialize Pygame
pygame.init()
screen = pygame.display.set_mode((16, 16))
color = (0, 0, 0)
screen.fill(color)
pygame.display.set_caption('Computer')

clock = pygame.time.Clock()

# Initialize RAM and CPU
ram = computer.RAM(1024)
cpu = computer.CPU(ram, screen)

# Load program from file
ram.load_program_from_file('program.asm')

# Run the CPU
cpu.run()

# Pygame main loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    pygame.display.flip()
    clock.tick(60)

New contributor

SalladShooter is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT