From 6f9f72e91903cfde0dc96416f51a65e9015c2237 Mon Sep 17 00:00:00 2001 From: weckyy702 Date: Sat, 26 Dec 2020 15:38:26 +0100 Subject: [PATCH] started cleaning source code interpretation --- .gitignore | 3 +- draw/Iinstruction.py | 2 - interpreter/interpret_source.py | 69 ++++++++++++++++++++++----------- res/input/input.java | 3 +- 4 files changed, 51 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index b0ee3e6..6ef2307 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ res/output/ res/input/ .vscode/ *.pyc -*.png \ No newline at end of file +*.png +debug.py \ No newline at end of file diff --git a/draw/Iinstruction.py b/draw/Iinstruction.py index 6e35dc6..66aae4d 100644 --- a/draw/Iinstruction.py +++ b/draw/Iinstruction.py @@ -1,5 +1,3 @@ - - from typing import Iterable, List from abc import abstractmethod from draw import code_to_image as cti diff --git a/interpreter/interpret_source.py b/interpreter/interpret_source.py index 8453b14..ed7c149 100644 --- a/interpreter/interpret_source.py +++ b/interpreter/interpret_source.py @@ -4,14 +4,10 @@ from typing import List, Tuple from draw.Iinstruction import * -class Scope(): +COMMENT_REGEX = r"""^//|^#|^COMMENT|^--""" - def __init__(self, enclosing_scope) -> None: - self.enclosing_scope = enclosing_scope - self.contents: List = [] - - def add_instruction(self, instruction: Iinstruction) -> None: - self.contents.append(instruction) +class JavaSyntaxError(Exception): + pass def load_src(filepath: str) -> List[str]: lines: List[str] = [] @@ -20,68 +16,97 @@ def load_src(filepath: str) -> List[str]: with open(filepath) as file: for _line in file: line = _line.strip().replace(' ', '') - if line and not re.match(r"""^//|^#|^COMMENT|^--""", line): + if line and not re.match(COMMENT_REGEX, line): lines.append(line) if line.__contains__('{'): brace_open_count += 1 if line.__contains__('}'): brace_closed_count += 1 except: - logging.error(f"Failed to open input file {filepath}!") + raise FileNotFoundError(f"File {filepath} was not found!") + if brace_open_count != brace_closed_count: - raise Exception("Number of opened braces does not match number of closed ones. Program is illformed!") + raise JavaSyntaxError("Number of opened braces does not match number of closed ones. Program is ill-formed!") return lines +def get_scope_start_offset(src: List[str], start_idx: int) -> int: + i = start_idx + while i < len(src): + line = src[i] + if line.__contains__("{"): + return i - start_idx + 1 + raise Exception("Unable to find scope start. Is the program ill-formed?") + def get_instructions_in_scope(src: List[str], start_idx: int = 0) -> Tuple[List[Iinstruction], int]: - outer_scope = Scope(None) + outer_scope: List[Iinstruction] = [] i = start_idx while i < len(src): line = src[i] try: if line.__contains__('}'): #We exited this scope, return it - return outer_scope.contents, i + return outer_scope, i if line.startswith("while("): + #construct: + #while(...) + #{ + #... + #} logging.debug("Found while instruction in line: %i", i+1) - bracket_idx = line.rindex(')') # throws if the while is illformed + + bracket_idx = line.rindex(')') # throws if while contruct is illformed + instruction_txt = line[6:bracket_idx] - child_instructions, i = get_instructions_in_scope(src, i+1) - outer_scope.add_instruction(while_instruction_front(instruction_txt, child_instructions)) + child_instructions, i = get_instructions_in_scope(src, i+2) + + outer_scope.append(while_instruction_front(instruction_txt, child_instructions)) elif line.startswith("if("): + #line: if(...) + logging.debug("Found if instruction in line: %i", i+1) + bracket_idx = line.rindex(')') # throws if the contruct is illformed + instruction_txt = line[3:bracket_idx] - true_instructions, i = get_instructions_in_scope(src, i+2) + brace_offset = get_scope_start_offset(src, i) + true_instructions, i = get_instructions_in_scope(src, i+brace_offset) + false_instructions = None if src[i].__contains__("else"): #if there is an else statement, check it false_instructions, i = get_instructions_in_scope(src, i+2) - outer_scope.add_instruction(if_instruction(instruction_txt, true_instructions, false_instructions)) + + outer_scope.append(if_instruction(instruction_txt, true_instructions, false_instructions)) elif line.startswith("do{"): + #construct: + #do{ + #... + #}while(...); logging.debug("Found start of do-while instruction in line: %i", i) + child_instructions, i = get_instructions_in_scope(src, i+1) + end_line = src[i] - #line: }while(...); bracket_idx = end_line.rindex(");") instruction_txt = end_line[7: bracket_idx] - outer_scope.add_instruction(while_instruction_back(instruction_txt, child_instructions)) + + outer_scope.append(while_instruction_back(instruction_txt, child_instructions)) else: logging.debug("Found generic instruction in line: %i", i+1) - outer_scope.add_instruction(generic_instruction(line)) + outer_scope.append(generic_instruction(line)) except: logging.error("Encountered error in line: %i", i) raise # rethrow i += 1 - return outer_scope.contents, 0 + return outer_scope, 0 if __name__ == "__main__": """debuging""" logging.basicConfig(level=logging.DEBUG) - #inst = get_scoped_instructions("res/input/input.java") lines = load_src("res/input/input.java") global_scope = get_instructions_in_scope(lines) print(global_scope) \ No newline at end of file diff --git a/res/input/input.java b/res/input/input.java index bb1fec8..af464b7 100644 --- a/res/input/input.java +++ b/res/input/input.java @@ -1,6 +1,7 @@ fahre1(); fahre2(); -while(shouldNiet()) { +while(shouldNiet()) +{ niet4(); niet5(); if(if6)