diff --git a/src/brainfuck/__brainfuck.py b/src/brainfuck/__brainfuck.py index 2f57b84..cdf1626 100644 --- a/src/brainfuck/__brainfuck.py +++ b/src/brainfuck/__brainfuck.py @@ -1,6 +1,6 @@ from sys import stdin, stdout from os import PathLike -from interpreter import Interpreter, opcode +from interpreter import Interpreter, Registers, opcode from pathlib import Path @@ -32,48 +32,62 @@ class BrainFuckByteCodeCompiler: ) +class BrainFuckRegisters(Registers): + def __init__(self) -> None: + super().__init__() + self.memory_pointer: int = 0 + + class BrainFuckInterpreter(Interpreter): + def __init__(self, bits=8, memsize=None) -> None: + super().__init__(bits, memsize) + self._registers: BrainFuckRegisters = BrainFuckRegisters() + + def load_program(self, program: bytearray) -> None: + super().load_program(program) + self._registers.memory_pointer = len(program) + 1 + @opcode(BrainFuckByteCode[">"]) def forward(self): - self._memory_pointer += 1 + self._registers.memory_pointer += 1 @opcode(BrainFuckByteCode["<"]) def backward(self): - self._memory_pointer -= 1 + self._registers.memory_pointer -= 1 @opcode(BrainFuckByteCode["+"]) def increment(self): - val = self._memory[self._memory_pointer] - self._memory[self._memory_pointer] = (val + 1) % 256 + val = self._memory[self._registers.memory_pointer] + self._memory[self._registers.memory_pointer] = (val + 1) % 256 @opcode(BrainFuckByteCode["-"]) def decrement(self): - val = self._memory[self._memory_pointer] - self._memory[self._memory_pointer] = (val - 1) & 255 + val = self._memory[self._registers.memory_pointer] + self._memory[self._registers.memory_pointer] = (val - 1) & 255 @opcode(BrainFuckByteCode["."]) - def io_in(self): - stdout.write(chr(self._memory[self._memory_pointer])) + def io_out(self): + stdout.write(chr(self._memory[self._registers.memory_pointer])) @opcode(BrainFuckByteCode[","]) - def io_out(self): + def io_in(self): stdout.flush() - self._memory[self._memory_pointer] = ord(stdin.read(1)) + self._memory[self._registers.memory_pointer] = ord(stdin.read(1)) @opcode(BrainFuckByteCode["["]) def loop_start(self): # Ignore opcode if mem_pointer == 0 - if self._memory[self._memory_pointer] > 0: + if self._memory[self._registers.memory_pointer] > 0: pass - elif self._memory[self._memory_pointer] == 0: - self._program_counter = self.findNext() - 1 + elif self._memory[self._registers.memory_pointer] == 0: + self._registers.program_counter = self.findNext() - 1 @opcode(BrainFuckByteCode["]"]) def start_end(self): - self._program_counter = self.findNext(-1) + self._registers.program_counter = self.findNext(-1) def findNext(self, incrementValue: int = 1) -> int: - search_pointer = self._program_counter + incrementValue + search_pointer = self._registers.program_counter + incrementValue bracket_counter = 1 while bracket_counter != 0: opcode = self._memory[search_pointer] diff --git a/src/interpreter/__init__.py b/src/interpreter/__init__.py index 533520a..817d17a 100644 --- a/src/interpreter/__init__.py +++ b/src/interpreter/__init__.py @@ -1,3 +1,3 @@ -from .__interpreter import Interpreter, opcode +from .__interpreter import Interpreter, Registers, opcode -__all__ = ["Interpreter", "opcode"] \ No newline at end of file +__all__ = ["Interpreter", "Registers", "opcode"] \ No newline at end of file diff --git a/src/interpreter/__interpreter.py b/src/interpreter/__interpreter.py index 299d1dd..2a42470 100644 --- a/src/interpreter/__interpreter.py +++ b/src/interpreter/__interpreter.py @@ -9,7 +9,7 @@ from .util import hexdump Operation: TypeAlias = str | int Subroutine: TypeAlias = Callable -OPCODE_HEADER = "__enterpreter__opcode" +OPCODE_HEADER = "__interpreter__opcode" def opcode(opcode: Operation): @@ -20,54 +20,60 @@ def opcode(opcode: Operation): return _helper +class Registers: + def __init__(self) -> None: + self.program_counter: int = 0 + + +class Memory: + def __init__(self, size: int) -> None: + self.__memory_size: int = size + self.__memory: bytearray = bytearray(self.__memory_size) + + def __getitem__(self, idx) -> int: + return self.__memory[idx] + + def __setitem__(self, idx, value) -> None: + self.__memory[idx] = value + + def dump(self): + return self.__memory + + class Interpreter: def __init__(self, bits=8, memsize=None) -> None: - memsize = memsize or 2**bits self.__bits = bits + self.__memory_max_size = 2**self.__bits - self.__memory_size = min(memsize, self.__memory_max_size) - - self._memory = bytearray(self.__memory_size) - self._memory_pointer: int = 0 - - self._program_counter: int = 0 + 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.__init_opcodes() def __init_opcodes(self): - for func_name, func in getmembers( - self, lambda obj: hasattr(obj, OPCODE_HEADER) - ): - self._register_opcode(getattr(func, OPCODE_HEADER), func) - - def _register_opcode(self, opcode: Operation, callback: Subroutine): - self.__operations[opcode] = callback - - def is_running(self) -> bool: - return self._memory[self._program_counter] != 0 + for _, func in getmembers(self, lambda obj: hasattr(obj, OPCODE_HEADER)): + opcode = getattr(func, OPCODE_HEADER) + self.__operations[opcode] = func def run(self) -> None: try: # Keep running until you reach a null byte - while self.is_running(): - opcode = self._memory[self._program_counter] + while (opcode := self._memory[self._registers.program_counter]) != 0: self.__operations[opcode]() - self._program_counter += 1 + self._registers.program_counter += 1 except Exception as e: self.dump() print_exception(e) def dump(self): hexdump( - data=self._memory, - program_counter=self._program_counter, - memory_pointer=self._memory_pointer, + data=self._memory.dump(), + program_counter=self._registers.program_counter, + memory_pointer=self._registers.memory_pointer ) pprint(self.__operations) def load_program(self, program: bytearray) -> None: self._memory[: len(program)] = program[:] - - # Set new pointer immediately after code - self._memory_pointer = len(program) + 1 diff --git a/src/lua/__init__.py b/src/lua/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/lua/__lua.py b/src/lua/__lua.py new file mode 100644 index 0000000..f39e776 --- /dev/null +++ b/src/lua/__lua.py @@ -0,0 +1,16 @@ +from interpreter import Interpreter, Registers, opcode + + +class LuaRegisters(Registers): + def __init__(self) -> None: + super().__init__() + +class LuaByteCodeInterpreter(Interpreter): + def __init__(self, bits=8, memsize=None) -> None: + super().__init__(bits, memsize) + self._registers = LuaRegisters() + + ... + +def lua(): + ... diff --git a/src/lua/__main__.py b/src/lua/__main__.py new file mode 100644 index 0000000..e69de29