diff --git a/dopey.py b/dopey.py index d07f36d..3dc9341 100755 --- a/dopey.py +++ b/dopey.py @@ -11,9 +11,9 @@ class MemoryException(Exception): """ TODO line number and column """ pass -class Memory: +class _Memory: BUFFER_SIZE = 30_000 - buffer = [0 for _ in range(BUFFER_SIZE)] + buffer = [] pointer = 0 input_buffer = [] @@ -21,7 +21,13 @@ class Memory: def get_pointer(cls) -> int: return cls.pointer -class Operation: + @classmethod + def reset(cls): + cls.buffer = [0 for _ in range(cls.BUFFER_SIZE)] + cls.pointer = 0 + cls.input_buffer = [] + +class _Operation: SHIFT_LEFT = "<" SHIFT_RIGHT = ">" INCREMENT = "+" @@ -41,49 +47,49 @@ class Operation: return # dont perform any non loop operations if inside an ignore loop - if len(cls.loop_ignore_stack) and operation != Operation.CLOSE_LOOP and operation != Operation.OPEN_LOOP: + if len(cls.loop_ignore_stack) and operation != _Operation.CLOSE_LOOP and operation != _Operation.OPEN_LOOP: return switch[operation](program) @classmethod def shift_left(cls, _) -> None: - Memory.pointer -= 1 - if Memory.pointer < 0: + _Memory.pointer -= 1 + if _Memory.pointer < 0: raise MemoryException @classmethod def shift_right(cls, _) -> None: - Memory.pointer += 1 - if Memory.pointer >= Memory.BUFFER_SIZE: + _Memory.pointer += 1 + if _Memory.pointer >= _Memory.BUFFER_SIZE: raise MemoryException @classmethod def increment(cls, _) -> None: - Memory.buffer[Memory.get_pointer()] += 1 + _Memory.buffer[_Memory.get_pointer()] += 1 @classmethod def decrement(cls, _) -> None: - Memory.buffer[Memory.get_pointer()] -= 1 + _Memory.buffer[_Memory.get_pointer()] -= 1 @classmethod def output(cls, _) -> None: - sys.stdout.write(chr(Memory.buffer[Memory.get_pointer()])) # TODO rollover if too big in ASCII + sys.stdout.write(chr(_Memory.buffer[_Memory.get_pointer()])) # TODO rollover if too big in ASCII sys.stdout.flush() # TODO possible performance issue @classmethod def input(cls, _) -> None: - if not len(Memory.input_buffer): + if not len(_Memory.input_buffer): input_ = sys.stdin.readline() - Memory.input_buffer += list(input_) - if len(Memory.input_buffer): - Memory.buffer[Memory.get_pointer()] = ord(Memory.input_buffer.pop(0)) + _Memory.input_buffer += list(input_) + if len(_Memory.input_buffer): + _Memory.buffer[_Memory.get_pointer()] = ord(_Memory.input_buffer.pop(0)) @classmethod def open_loop(cls, program: List) -> None: - if not Memory.buffer[Memory.get_pointer()]: + if not _Memory.buffer[_Memory.get_pointer()]: # enter ignore loop if byte at pointer is zero - cls.loop_ignore_stack.append(Operation.OPEN_LOOP) + cls.loop_ignore_stack.append(_Operation.OPEN_LOOP) else: # save start loop position should we need to return cls.loop_stack.append(program[1]-1) @@ -101,7 +107,7 @@ class Operation: # check if we need to repeat last_open_loop_pos = cls.loop_stack.pop() - if Memory.buffer[Memory.get_pointer()]: + if _Memory.buffer[_Memory.get_pointer()]: program[1] = last_open_loop_pos @classmethod @@ -117,6 +123,24 @@ class Operation: cls.CLOSE_LOOP: cls.close_loop } +class Interpreter: + def __init__(self): + pass + + def execute(self, str_program: str) -> None: + _Memory.reset() + + program = [str_program, 0] # TODO create program class + switch = _Operation.get_operations_in_switch() + + while program[1] < len(program[0]): + operation = program[0][program[1]] + program[1] += 1 + _Operation.perform(operation, program, switch) + + if len(_Operation.loop_stack): + raise MismatchBracketException + def main() -> None: file_location = None if len(sys.argv) != 2: @@ -126,18 +150,11 @@ def main() -> None: file_location = sys.argv[1] file = open(file_location, "r") - program = [file.read(), 0] # TODO create program class + str_program = file.read() file.close() - switch = Operation.get_operations_in_switch() - while program[1] < len(program[0]): - operation = program[0][program[1]] - program[1] += 1 - Operation.perform(operation, program, switch) - - if len(Operation.loop_stack): - raise MismatchBracketException + interpreter = Interpreter() + interpreter.execute(str_program) if __name__ == "__main__": - main() - + main() \ No newline at end of file