From d100ffd49fe4a138c38814be3cf801a1d9df47f1 Mon Sep 17 00:00:00 2001 From: Giovani Date: Tue, 15 Jun 2021 16:21:02 -0400 Subject: [PATCH] refactor: improve code readability --- dopey.py | 116 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 43 deletions(-) diff --git a/dopey.py b/dopey.py index f065adc..e814891 100644 --- a/dopey.py +++ b/dopey.py @@ -2,19 +2,20 @@ import sys from io import TextIOWrapper from blessed import Terminal -# create memory buffer and pointer +class MismatchBracketException(Exception): + """ TODO line number and column """ + pass + class Memory: BUFFER_SIZE = 30_000 buffer = [0 for _ in range(BUFFER_SIZE)] pointer = 0 - loop_stack = [] @classmethod def get_pointer(cls) -> int: # TODO add logic to roll around buffer return cls.pointer -# define bf commands class Operation: SHIFT_LEFT = "<" SHIFT_RIGHT = ">" @@ -25,8 +26,73 @@ class Operation: OPEN_LOOP = "[" CLOSE_LOOP = "]" + terminal = Terminal() + loop_stack = [] + + @classmethod + def perform(cls, operation: str, file: TextIOWrapper) -> None: + switch = { + cls.SHIFT_LEFT: cls.shift_left, + cls.SHIFT_RIGHT: cls.shift_right, + cls.INCREMENT: cls.increment, + cls.DECREMENT: cls.decrement, + cls.OUTPUT: cls.output, + cls.INPUT: cls.input, + cls.OPEN_LOOP: cls.open_loop, + cls.CLOSE_LOOP: cls.close_loop + } + + if operation not in switch: + return + switch[operation](file) + + @classmethod + def shift_left(cls, _) -> None: + Memory.pointer -= 1 + + @classmethod + def shift_right(cls, _) -> None: + Memory.pointer += 1 + + @classmethod + def increment(cls, _) -> None: + Memory.buffer[Memory.get_pointer()] += 1 + + @classmethod + def decrement(cls, _) -> None: + Memory.buffer[Memory.get_pointer()] -= 1 + + @classmethod + def output(cls, _) -> None: + print(chr(Memory.buffer[Memory.get_pointer()]), end="") # TODO rollover if too big in ASCII + + @classmethod + def input(cls, _) -> None: + with cls.terminal.cbreak(): + Memory.buffer[Memory.get_pointer()] = ord(cls.terminal.inkey()) + + @classmethod + def open_loop(cls, file: TextIOWrapper) -> None: + if not Memory.buffer[Memory.get_pointer()]: + while True: + operation = file.read(1) + if operation == Operation.CLOSE_LOOP: + break + elif not operation: + raise MismatchBracketException + else: + cls.loop_stack.append(file.tell()-1) + + @classmethod + def close_loop(cls, file: TextIOWrapper) -> None: + if not len(cls.loop_stack): + raise MismatchBracketException + + last_open_loop_pos = cls.loop_stack.pop() + if Memory.buffer[Memory.get_pointer()]: + file.seek(last_open_loop_pos, 0) + def main() -> None: - # get bf file location file_location = None if len(sys.argv) != 2: print("Invalid or missing arguments...") @@ -34,52 +100,16 @@ def main() -> None: else: file_location = sys.argv[1] - # open file file = open(file_location, "r") while True: operation = file.read(1) if not operation: break - - # perform operation - perform_operation(operation, file) + Operation.perform(operation, file) file.close() - -def perform_operation(operation: str, file: TextIOWrapper) -> None: - if operation == Operation.SHIFT_LEFT: - Memory.pointer -= 1 - elif operation == Operation.SHIFT_RIGHT: - Memory.pointer += 1 - elif operation == Operation.INCREMENT: - Memory.buffer[Memory.get_pointer()] += 1 - elif operation == Operation.DECREMENT: - Memory.buffer[Memory.get_pointer()] -= 1 - elif operation == Operation.OUTPUT: - print(chr(Memory.buffer[Memory.get_pointer()]), end="") - elif operation == Operation.INPUT: - term = Terminal() - with term.cbreak(): - Memory.buffer[Memory.get_pointer()] = ord(term.inkey()) - elif operation == Operation.OPEN_LOOP: - if Memory.buffer[Memory.get_pointer()] == 0: - while True: - operation = file.read(1) - if operation == Operation.CLOSE_LOOP: - break - elif not operation: - print("Mismatched bracket...") # TODO add line number and column on line - sys.exit() - else: - Memory.loop_stack.append(file.tell()-1) - elif operation == Operation.CLOSE_LOOP: - if len(Memory.loop_stack) == 0: - print("Mismatched bracket...") # TODO add line number and column on line - sys.exit() - - open_loop_position = Memory.loop_stack.pop() - if Memory.buffer[Memory.get_pointer()] != 0: - file.seek(open_loop_position, 0) + if len(Operation.loop_stack): + raise MismatchBracketException if __name__ == "__main__": main()