From 7b6b7262097a1242f75c2a22f516f5d2d0a1b6de Mon Sep 17 00:00:00 2001 From: weckyy702 Date: Mon, 28 Dec 2020 23:22:55 +0100 Subject: [PATCH] reworked interpreter and fixed major bug --- .vscode/launch.json | 2 +- interpreter/NassiShneidermann.py | 11 ++-- interpreter/interpret_source.py | 93 +++++++++----------------------- 3 files changed, 32 insertions(+), 74 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 1ded7e8..e80f071 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Python: Aktuelle Datei", "type": "python", "request": "launch", - "program": "run.py", + "program": "debug.py", "console": "integratedTerminal" } ] diff --git a/interpreter/NassiShneidermann.py b/interpreter/NassiShneidermann.py index 833be58..8aa7085 100644 --- a/interpreter/NassiShneidermann.py +++ b/interpreter/NassiShneidermann.py @@ -1,3 +1,4 @@ +from interpreter.interpret_source import Function_scope from typing import List import logging from enum import IntEnum @@ -19,7 +20,7 @@ OB = Overwrite_behaviour class NassiShneidermanDiagram: def __init__(self, do_debug: bool): - self.scopes: List[List[Iinstruction]] = [] + self.function_scopes: List[Function_scope] = [] self.init_logging(do_debug) def init_logging(self, debug: bool): @@ -34,7 +35,7 @@ class NassiShneidermanDiagram: def _get_image_height(self, scope_index: int) -> int: h = 0 - for inst in self.scopes[scope_index]: + for inst in self.function_scopes[scope_index]: h += inst.getblksize() return int(h) @@ -60,7 +61,7 @@ class NassiShneidermanDiagram: return filepath def convert_to_image(self, output_path: str, filename: str, on_conflict: Overwrite_behaviour=OB.SKIP, x_size: int=200): - for i in range(len(self.scopes)): + for i in range(len(self.function_scopes)): filepath = f"{output_path}/{filename}#{i}" filepath = self.check_conflicts(filepath, on_conflict) if filepath is not None: @@ -69,11 +70,11 @@ class NassiShneidermanDiagram: image_y_sz = self._get_image_height(i) with NSD_writer(filepath, x_size, image_y_sz): - scope = self.scopes[i] + scope = self.function_scopes[i].contents x, y = 0, 0 for instruction in scope: x, y = instruction.to_image(x, y, x_size) logging.info("Done!") def load_from_file(self, filepath:str): - self.scopes = itp.load_instructions(filepath) \ No newline at end of file + self.function_scopes = itp.load_scoped_instructions(filepath) \ No newline at end of file diff --git a/interpreter/interpret_source.py b/interpreter/interpret_source.py index c037fab..99f2a24 100644 --- a/interpreter/interpret_source.py +++ b/interpreter/interpret_source.py @@ -1,6 +1,7 @@ import logging from os import remove import re +from re import split from typing import List, Tuple from errors.custom import InterpreterException, JavaSyntaxError, ScopeNotFoundException @@ -11,6 +12,16 @@ logging.warning("""As the Interpreter is still WIP, some Java language features *for loops Please remove these features from the source code as they will result in incorrect behaviour""") +class Function_scope(Iterable): + def __init__(self, child_instructions: List[Iinstruction], name: str, return_type: str, args: List[str]) -> None: + self.contents = child_instructions + self.name = name + self.return_type = return_type + self.args = args + + def __iter__(self): + return self.contents.__iter__() + COMMENT_PATTERN = re.compile(r"""^//|^/\*\*|^\*|^--""") REMOVE_KEYWORDS = [' ', "public", "private", ';'] VARIABLE_TAGS = ["byte", "short", "int", "long", "float", "double", "boolean", "char", "String"] @@ -84,20 +95,6 @@ def get_scope_start_offset(src: List[str], i: int) -> int: return 2 raise ScopeNotFoundException("Unable to find scope start. Is the program ill-formed?") -def get_scope_exit_offset(src: List[str], start_idx: int) -> int: - i = start_idx - while i < len(src): - line = src[i] - - if '{' in line: - i += get_scope_exit_offset(src, i+1) - line = src[i+1] - if '}' in line: - return i - start_idx - i += 1 - - raise ScopeNotFoundException("Unable to find scope end. Is the program ill-formed?") - def handle_while(line: str, src: List[str], i: int) -> Tuple[Iinstruction, int]: bracket_idx = line.rindex(')') # throws if while contruct is illformed @@ -189,63 +186,23 @@ def get_instructions_in_scope(src: List[str], start_idx: int = 0) -> Tuple[List[ return outer_scope, i -def get_function_scope_spans(src: List[str]) -> List[Tuple[int, int, str]]: - spans = [] +def get_function_scopes(src: List[str]) -> List[Function_scope]: + functions = [] i = 0 while i < len(src): line = src[i] - try: + if match:=function_pattern.match(line): + groups = match.groups() + function_return_type = groups[0] + function_args = groups[1] + function_name = line.removeprefix(function_return_type).removesuffix(function_args) #remove return type and argument list to get the function name - if match:= function_pattern.match(line): - groups = match.groups() - function_name = line.removeprefix(groups[0]).removesuffix(groups[1]) - function_return_type = groups[0] - function_args = groups[1][1:-1] - brace_offset = get_scope_start_offset(src, i) - scope_offset = get_scope_exit_offset(src, i+brace_offset) + brace_offset = get_scope_start_offset(src, i) + child_instructions, i = get_instructions_in_scope(src, i+brace_offset) + functions.append(Function_scope(child_instructions, function_name, function_return_type, function_args.split(','))) + i+=1 + return functions - span = (i+brace_offset, i+brace_offset+scope_offset, function_name) - - i += scope_offset + brace_offset - spans.append(span) - - except Exception as e: - logging.error("encountered error in line %i : %s", i, str(e)) - raise - i += 1 - - return spans - -def scope_handler(inst_info: Tuple[List[str], List[int]]) -> List[Iinstruction]: - src = inst_info[0] - scope_start = inst_info[1][0] - scope_end = inst_info[1][1] - return get_instructions_in_scope(src[scope_start: scope_end])[0] - -def named_scope_handler(inst_info: Tuple[List[str], Tuple[int, int, str]]) -> Tuple[str, List[Iinstruction]]: - src = inst_info[0] - scope_start = inst_info[1][0] - scope_end = inst_info[1][1] - function_name = inst_info[1][2] - function_instructions, _ = get_instructions_in_scope(src[scope_start: scope_end]) - return (function_name, function_instructions) - -def get_instructions_in_scopes(src: List[str], scope_spans: List[Tuple[int, int, str]]) -> List[List[Iinstruction]]: - instructions = list(map(scope_handler, [(src, span[0:2]) for span in scope_spans])) - return instructions - -def get_instructions_in_named_scopes(src: List[str], scope_spans: List[Tuple[int, int, str]]) -> List[Tuple[str, List[Iinstruction]]]: - instructions = list(map(named_scope_handler, [(src, span) for span in scope_spans])) - return instructions - -def load_instructions(filepath: str) -> List[List[Iinstruction]]: +def load_scoped_instructions(filepath: str) -> List[Function_scope]: src = load_src(filepath) - scope_spans = get_function_scope_spans(src) - instructions = get_instructions_in_scopes(src, scope_spans) - return instructions - -def load_scoped_instructions(filepath: str) -> List[Tuple[str, List[Iinstruction]]]: - src = load_src(filepath) - scope_spans = get_function_scope_spans(src) - instructions = get_instructions_in_named_scopes(src, scope_spans) - return instructions + return get_function_scopes(src)