diff --git a/src/interpreter/__interpreter.py b/src/interpreter/__interpreter.py index fde294d..735a925 100644 --- a/src/interpreter/__interpreter.py +++ b/src/interpreter/__interpreter.py @@ -7,13 +7,20 @@ from colorama import Fore, Style, Back from .util import hexdump -Operation: TypeAlias = str | int +Operation: TypeAlias = int Subroutine: TypeAlias = Callable OPCODE_HEADER = "__interpreter__opcode" +OPCODE_ERROR_TYPE_CHECK = f"Opcodes must be of type f{int}." +OPCODE_ERROR_REUSE = "Opcode {opcode} has already been used." +OPCODE_ERROR_ILLEGAL = ( + "Opcode {opcode} cannot be found, has it been registered correct?" +) def opcode(opcode: Operation): + assert type(opcode) == Operation, OPCODE_ERROR_TYPE_CHECK + def _helper(func: Callable): setattr(func, OPCODE_HEADER, opcode) return func @@ -36,7 +43,7 @@ class Memory: def __setitem__(self, idx, value) -> None: self.__memory[idx] = value - + def dump(self): return self.__memory @@ -45,24 +52,36 @@ class Interpreter: def __init__(self, bits=8, memsize=None) -> None: self.__bits = bits + self.__max_cpu_instructions = 2**self.__bits self.__memory_max_size = 2**self.__bits self.__memory_size = min(memsize or 2**bits, self.__memory_max_size) self._memory: Memory = Memory(self.__memory_size) self._registers: Registers = Registers() - self.__operations: dict[Operation, Subroutine] = dict() + self.__operations: list[Subroutine | None] = [ + None for _ in range(self.__max_cpu_instructions) + ] self.__init_opcodes() def __init_opcodes(self): for _, func in getmembers(self, lambda obj: hasattr(obj, OPCODE_HEADER)): opcode = getattr(func, OPCODE_HEADER) + assert self.__operations[opcode] is None, OPCODE_ERROR_REUSE.format( + opcode=opcode + ) + self.__operations[opcode] = func def run(self) -> None: try: # Keep running until you reach a null byte while (opcode := self._memory[self._registers.program_counter]) != 0: - self.__operations[opcode]() + subroutine = self.__operations[opcode] + assert subroutine is not None, OPCODE_ERROR_ILLEGAL.format( + opcode=opcode + ) + + subroutine() self._registers.program_counter += 1 except Exception as e: self.dump()