From 45cb5c04676f82e8a8574cc5dc08bb0fa50ab8b8 Mon Sep 17 00:00:00 2001 From: weckyy702 Date: Sun, 25 Apr 2021 14:21:54 +0200 Subject: [PATCH] rewrote instruction classes --- draw/Iinstruction.py | 309 +++++++++++++------------------ interpreter/NassiShneidermann.py | 10 +- interpreter/function_scope.py | 14 +- 3 files changed, 140 insertions(+), 193 deletions(-) diff --git a/draw/Iinstruction.py b/draw/Iinstruction.py index 3cd7962..c20abed 100644 --- a/draw/Iinstruction.py +++ b/draw/Iinstruction.py @@ -1,233 +1,180 @@ -"""Iinstruction.py: Instruction classes to turn the lexing results into an image""" +"""Interafce for all instruction types""" -__author__ = "Weckyy702" +__author__ ="Weckyy702" - -from typing import Iterable, List, Tuple from abc import ABCMeta, abstractmethod -from draw import code_to_image as cti +from typing import Tuple, List, Optional -class Iinstruction(metaclass=ABCMeta): - """Base class for all instructions""" +from . import code_to_image as cti +class instruction(metaclass=ABCMeta): def __init__(self, instruction_text: str) -> None: self.instruction_text = instruction_text @abstractmethod - def to_image(self, x:int, y:int, x_sz: int) -> Tuple[float, float, float]: + def convert_to_image(self, x: int, y: int, width: int) -> int: pass @abstractmethod - def getblkheight(self) -> float: - pass + def get_block_width(self): + return self.get_text_width() @abstractmethod - def getblkwidth(self) -> float: - pass - - @abstractmethod - def __str__(self) -> str: - pass - - def _getblkheight(self) -> float: - return cti.get_text_size(self.instruction_text)[1] + cti.PADDING_Y #padding - - def _getblkwidth(self) -> float: - return cti.get_text_size(self.instruction_text)[0] + cti.PADDING_X #padding + def get_block_height(self): + return self.get_text_height() -class generic_instruction(Iinstruction): - """Any instruction that is not a control structure""" + def get_text_width(self): + return cti.get_text_size(self.instruction_text)[0] + + def get_text_height(self): + return cti.get_text_size(self.instruction_text)[1] + + + +class generic_instruction(instruction): def __init__(self, instruction_text: str) -> None: super().__init__(instruction_text) - - def to_image(self, x:int, y:int, x_sz: int) -> Tuple[float, float, float]: - return cti.draw_generic_instruction(self.instruction_text, x, y, x_sz, self.getblkheight()) - def getblkheight(self) -> float: - return self._getblkheight() - - def getblkwidth(self) -> float: - return self._getblkwidth() + def convert_to_image(self, x: int, y: int, width: int) -> int: + height = self.get_block_height() + return cti.draw_generic_instruction(self.instruction_text, x, y, width, height) - def __str__(self) -> str: - return self.instruction_text + def get_block_width(self): + return super().get_block_width() -class if_instruction(Iinstruction): - """Conditional structurewdas - NOT. - A. - LOOP - """ + def get_block_height(self): + return super().get_block_height() - def __init__(self, instruction_text: str, true_case: List[Iinstruction], false_case: List[Iinstruction]=None) -> None: + + +class if_instruction(instruction): + def __init__(self, instruction_text: str, true_case: List[instruction], false_case: Optional[List[instruction]]) -> None: super().__init__(instruction_text) self.true_case = true_case self.false_case = false_case - def get_trueheight(self) -> float: - sz = 0.0 - for inst in self.true_case: - sz += inst.getblkheight() - return sz + def convert_to_image(self, x: int, y: int, width: int) -> int: + true_width = self.get_true_width() - def get_falseheight(self) -> float: - sz = 0.0 - if self.false_case: - for inst in self.false_case: - sz += inst.getblkheight() - return sz + true_x, true_y, false_x, false_y = cti.draw_if_statement(self.instruction_text, x, y, true_width, width) - def get_truewidth(self) -> float: - w = 200.0 + self.draw_children(true_x, true_y, true_width, false_x, false_y, width-true_width) - for inst in self.true_case: - w = max(w, inst.getblkwidth()) - - return w - - def get_falsewidth(self) -> float: - w = 200.0 + return y + self.get_block_height() - if self.false_case: - for inst in self.false_case: - w = max(w, inst.getblkwidth()) - - return w - - def getblkheight(self) -> float: - return self._getblkheight() + max(self.get_trueheight(), self.get_falseheight()) - - def getblkwidth(self) -> float: - text_width, true_width, false_width = self.get_widths() - - return max(text_width, true_width+false_width) - - def get_widths(self) -> Tuple[float, float, float]: - text_width = self._getblkwidth() - true_width = self.get_truewidth() - false_width = self.get_falsewidth() - - true_width = max(text_width/2, true_width) - false_width = max(text_width/2, false_width) - true_width = max(text_width-false_width, true_width) - - return text_width, true_width, false_width - - - def to_image(self, x:int, y:int, x_sz: int) -> Tuple[float]: - _, true_w, false_w = self.get_widths() - true_x, true_y, true_w, false_x, false_y, false_w = cti.draw_if_statement( - self.instruction_text, x, y, true_w, false_w, self.getblkheight() - ) - self.draw_true_case(true_x, true_y, true_w) - self.draw_false_case(false_x, false_y, false_w) - blk_size = self.getblkheight() - return x, y + blk_size - - def draw_true_case(self, x: float, y:float, x_sz:float): + def draw_children(self, true_x:int, true_y:int, true_width:int, false_x:int, false_y:int, false_width:int): for instruction in self.true_case: - x, y = instruction.to_image(x, y, x_sz)[0:2] + true_y = instruction.convert_to_image(true_x, true_y, true_width) - def draw_false_case(self, x: float, y:float, x_sz:float): if self.false_case: for instruction in self.false_case: - x, y = instruction.to_image(x, y, x_sz)[0:2] + false_y = instruction.convert_to_image(false_x, false_y, false_width) - def __str__(self) -> str: - res = f"if({self.instruction_text}) {'{'}\n" - for inst in self.true_case: - res += '\t'+str(inst)+";\n" - res += "}" + def get_block_width(self) -> int: + text_width = self.get_text_width() + + true_width = self.get_true_width() + false_width = self.get_false_width() + + return max(text_width, true_width + false_width) + + def get_block_height(self): + text_height = self.get_text_height() + true_height = self.get_true_height() + false_height = self.get_false_height() + + return text_height + max(true_height, false_height) + + def get_text_width(self): + return int(super().get_text_width() * 1.5) + + def get_true_width(self) -> int: + width = 200 + for instruction in self.true_case: + width = max(width, instruction.get_block_width()) + return width + + def get_false_width(self) -> int: + width = 200 if self.false_case: - res += " else {\n" - for inst in self.true_case: - res += '\t'+str(inst)+";\n" - res += "}" - return res + for instruction in self.false_case: + width = max(width, instruction.get_block_width()) + return width -class while_instruction_front(Iinstruction): + def get_true_height(self) -> int: + height = 0 - def __init__(self, condition: str, instructions: List[Iinstruction]) -> None: - super().__init__(condition) - self.child_instructions = instructions + for instruction in self.true_case: + height += instruction.get_block_height() - def get_children_height(self) -> float: - children_sz = 0 - for inst in self.child_instructions: - children_sz += inst.getblkheight() - return children_sz + return height - def get_children_width(self) -> float: - w = 0.0 - for inst in self.child_instructions: - w = max(w, inst.getblkheight()) - return w + def get_false_height(self) -> int: + height = 0 + + if self.false_case: + for instruction in self.false_case: + height += instruction.get_block_height() - def getblkheight(self) -> float: - return self._getblkheight() + self.get_children_height() - - def getblkwidth(self) -> float: - return max(self._getblkwidth(), self.get_children_width()) - - def to_image(self, x:int, y:int, x_sz: int) -> Tuple[float]: - children_x, children_y, children_sz_x = cti.draw_while_loop_front(self.instruction_text, x, y, x_sz, self.getblkheight()) - self.draw_children(children_x, children_y, children_sz_x) - - return x, y + self.getblkheight() + return height - def draw_children(self, x:float, y:float, x_sz:float): - for inst in self.child_instructions: - x, y = inst.to_image(x, y, x_sz)[0:2] - return self.get_children_height() - def __str__(self) -> str: - res = "while(" + self.instruction_text + "){\n" - for inst in self.child_instructions: - res += '\t'+str(inst)+";\n" - res += '}' - return res +class while_instruction_front(instruction): + def __init__(self, condition_text: str, child_instructions: List[instruction]) -> None: + super().__init__(condition_text) + self.children = child_instructions + def convert_to_image(self, x: int, y: int, width: int) -> int: + block_height = self.get_block_height() + + children_x, children_y, children_width = cti.draw_while_loop_front(self.instruction_text, x, y, width, block_height) + + self.draw_children(children_x, children_y, children_width) + + return y + block_height + + def draw_children(self, children_x:int, children_y:int, children_width:int): + for instruction in self.children: + children_y = instruction.convert_to_image(children_x, children_y, children_width) + + def get_block_width(self): + width = self.get_text_width() + + for instruction in self.children: + width = max(width, instruction.get_block_width() / (1 - cti.BLOCK_OFFSET_RATIO)) #instructions inside a bock take up more space, so compensate for that + + return int(width) + + def get_block_height(self): + height = self.get_text_height() + + for instruction in self.children: + height += instruction.get_block_height() + + return height class while_instruction_back(while_instruction_front): - def __init__(self, condition: str, instructions: List[Iinstruction]) -> None: - super().__init__(condition, instructions) - - def to_image(self, x:int, y:int, x_sz: int): - children_x, children_y, children_sz_x = cti.draw_while_loop_back(self.instruction_text, x, y, x_sz, self.getblkheight()) - self.draw_children(children_x, children_y, children_sz_x) - return x, y + self.getblksize() + def __init__(self, condition_text: str, child_instructions: List[instruction]) -> None: + super().__init__(condition_text, child_instructions) + + def convert_to_image(self, x: int, y: int, width: int) -> int: + block_height = self.get_block_height() + children_x, children_y, children_width = cti.draw_while_loop_back(self.instruction_text, x, y, width, block_height) + + self.draw_children(children_x, children_y, children_width) + + return y + block_height + - def __str__(self) -> str: - res = "do{\n" - for inst in self.child_instructions: - res += '\t' +str(inst) + ";\n" - res += f"{'}'}while({self.instruction_text});" - return res class for_instruction(while_instruction_front): - def __init__(self, variable_def: str, condition: str, instructions: List[Iinstruction]) -> None: - super().__init__(condition, instructions) - self.variable_instruction = generic_instruction(variable_def) if variable_def else None + def __init__(self, variable_text: str, condition_text: str, child_instruction: List[instruction]) -> None: + super().__init__(condition_text, child_instruction) + self.variable_instruction = generic_instruction(variable_text) - def to_image(self, x: int, y: int, x_sz: int) -> Tuple[float]: - if self.variable_instruction: - x, y, _ = self.variable_instruction.to_image(x, y, x_sz) - return super().to_image(x, y, x_sz) - - def getblkheight(self) -> float: - if self.variable_instruction: - return super().getblkheight()+self.variable_instruction.getblkheight() - return super().getblkheight() - - def getblkwidth(self) -> float: - if self.variable_instruction: - return max(super().getblkwidth(), self.variable_instruction.getblkwidth()) - return super().getblkwidth() - - def __str__(self) -> str: - if self.variable_instruction: - return self.variable_instruction.__str__()+';\n' + super().__str__() - return super().__str__() \ No newline at end of file + def convert_to_image(self, x: int, y: int, width: int) -> int: + y = self.variable_instruction.convert_to_image(x, y, width) + return super().convert_to_image(x,y, width) \ No newline at end of file diff --git a/interpreter/NassiShneidermann.py b/interpreter/NassiShneidermann.py index 630bc2c..fe27982 100644 --- a/interpreter/NassiShneidermann.py +++ b/interpreter/NassiShneidermann.py @@ -39,12 +39,12 @@ class NassiShneidermanDiagram: @staticmethod def _save_scope(scope: Function_scope, output_path: str): - x_size = scope.get_width() - y_size = scope.get_height() - with NSD_writer(output_path, x_size, y_size): - x, y = 0, 0 + width = scope.get_width() + height = scope.get_height() + with NSD_writer(output_path, width, height): + y = 0 for instruction in scope: - x, y = instruction.to_image(x, y, x_size)[0:2] + y = instruction.convert_to_image(0, y, width) @staticmethod def check_conflicts(filepath:str, behavoiur: Overwrite_behaviour): diff --git a/interpreter/function_scope.py b/interpreter/function_scope.py index ac8e1e7..c6322cd 100644 --- a/interpreter/function_scope.py +++ b/interpreter/function_scope.py @@ -3,7 +3,7 @@ __author__ = "Weckyy702" from typing import Iterable, List -from draw.Iinstruction import Iinstruction +from draw.Iinstruction import instruction class Function_scope(Iterable): """This class serves as a container for Instructions""" @@ -17,19 +17,19 @@ class Function_scope(Iterable): def get_height(self) -> int: h = 0.0 for inst in self.contents: - h += inst.getblkheight() + h += inst.get_block_height() return int(h) def get_width(self) -> int: - w = 200.0 #minimum width for every block + w = 200 #minimum width for every block for inst in self.contents: - w = max(w, inst.getblkwidth()) - return int(w) + w = max(w, inst.get_block_width()) + return w - def _add_instruction(self, inst: Iinstruction): + def _add_instruction(self, inst: instruction): self.contents.append(inst) - def _add_instructions(self, inst: List[Iinstruction]): + def _add_instructions(self, inst: List[instruction]): self.contents.extend(inst) def __iter__(self):