From 4a8f3649c8ea8b3b91d5e9a9e7b997e2c9fb169d Mon Sep 17 00:00:00 2001 From: weckyy702 Date: Mon, 26 Apr 2021 11:50:42 +0200 Subject: [PATCH] reworked image generation --- draw/Iinstruction.py | 54 ++++++++++++++++++++++++++++++-- draw/code_to_image.py | 24 +++++++------- interpreter/NassiShneidermann.py | 3 +- interpreter/_token.py | 2 +- interpreter/function_scope.py | 4 +-- 5 files changed, 69 insertions(+), 18 deletions(-) diff --git a/draw/Iinstruction.py b/draw/Iinstruction.py index c20abed..c2d1e5e 100644 --- a/draw/Iinstruction.py +++ b/draw/Iinstruction.py @@ -47,6 +47,9 @@ class generic_instruction(instruction): def get_block_height(self): return super().get_block_height() + def __str__(self) -> str: + return self.instruction_text + class if_instruction(instruction): @@ -57,8 +60,9 @@ class if_instruction(instruction): def convert_to_image(self, x: int, y: int, width: int) -> int: true_width = self.get_true_width() + block_height = self.get_block_height() - true_x, true_y, false_x, false_y = cti.draw_if_statement(self.instruction_text, x, y, true_width, width) + true_x, true_y, false_x, false_y = cti.draw_if_statement(self.instruction_text, x, y, true_width, width, block_height) self.draw_children(true_x, true_y, true_width, false_x, false_y, width-true_width) @@ -120,6 +124,18 @@ class if_instruction(instruction): return height + def __str__(self) -> str: + res = "if\n" + for instruction in self.true_case: + res += '\t' + str(instruction) + '\n' + + if self.false_case: + res += "else\n" + for instruction in self.false_case: + res += '\t' + str(instruction) + '\n' + + return res + class while_instruction_front(instruction): @@ -156,6 +172,12 @@ class while_instruction_front(instruction): return height + def __str__(self) -> str: + res = "while\n" + for instruction in self.children: + res += '\t' + str(instruction) + '\n' + return res + class while_instruction_back(while_instruction_front): def __init__(self, condition_text: str, child_instructions: List[instruction]) -> None: super().__init__(condition_text, child_instructions) @@ -168,7 +190,12 @@ class while_instruction_back(while_instruction_front): return y + block_height - + def __str__(self) -> str: + res = "do\n" + for instruction in self.children: + res += '\t' + str(instruction) + '\n' + res += "while" + return res class for_instruction(while_instruction_front): def __init__(self, variable_text: str, condition_text: str, child_instruction: List[instruction]) -> None: @@ -176,5 +203,26 @@ class for_instruction(while_instruction_front): self.variable_instruction = generic_instruction(variable_text) def convert_to_image(self, x: int, y: int, width: int) -> int: + block_height = super().get_block_height() + y = self.variable_instruction.convert_to_image(x, y, width) - return super().convert_to_image(x,y, width) \ No newline at end of file + + 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 get_block_width(self): + return max(super().get_block_width(), self.variable_instruction.get_block_width()) + + def get_block_height(self): + return super().get_block_height() + self.variable_instruction.get_block_height() + + def __str__(self) -> str: + res = str(self.variable_instruction) + '\n' + res += "for\n" + + for instruction in self.children: + res += "\t" + str(instruction) + '\n' + + return res \ No newline at end of file diff --git a/draw/code_to_image.py b/draw/code_to_image.py index 1c53c44..0559ed2 100644 --- a/draw/code_to_image.py +++ b/draw/code_to_image.py @@ -73,7 +73,7 @@ def draw_generic_instruction(instruction: str, x: int, y: int, width:int, height -def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_width:int) -> Tuple[int, int, int, int]: +def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_width:int, block_height: int) -> Tuple[int, int, int, int]: """Draw an if statement into the NSD""" if not output_img: raise Exception(ERROR_TEXT) @@ -91,6 +91,8 @@ def draw_if_statement(condition: str, x: int, y: int, true_width: int, block_wid output_img.text((x + 5, y + text_height), "true", font = font, fill = (0), anchor="ld") output_img.text((x + block_width - 5, y + text_height), "false", font = font, fill = (0), anchor="rd") + output_img.line((x + true_width, y + text_height) + (x + true_width, y + block_height), fill=(0)) + #x and y of "true" and "false" label return x, y + text_height, x + true_width, y + text_height @@ -105,11 +107,9 @@ def draw_while_loop_front(condition: str, x: int, y: int, block_width: int, bloc #the box output_img.line((x,y) + (x + block_width, y), fill=(0)) - output_img.line((x,y) + (x, y + block_width), fill=(0)) + output_img.line((x,y) + (x, y + block_height), fill=(0)) output_img.line((x + block_offset, y + text_height) + (x + block_width, y + text_height), fill=(0)) - output_img.line((x + block_width, y) + (x + block_width, y + text_height), fill=(0)) - output_img.line((x, y + block_height) + (x + block_offset, y + block_height ), fill=(0)) - output_img.line((x + block_offset, y + block_height) + (x + block_offset, y + text_height), fill=(0)) + output_img.line((x + block_width, y) + (x + block_width, y+text_height), fill=(0)) #the text output_img.text((x + block_offset, y + text_height * .5), condition, font = font, fill = (0), anchor="lm") @@ -124,19 +124,21 @@ def draw_while_loop_back(condition: str, x: int, y: int, block_width: int, block text_height = get_text_size(condition)[1] + block_offset = int(block_width * BLOCK_OFFSET_RATIO) + #the box - output_img.line((x,y) + (x + block_width * .1, y), fill=0) - output_img.line((x + block_width * .1, y) + (x + block_width * .1, y + block_height - text_height), fill=0) - output_img.line((x + block_width * .1, y + block_height - text_height) + (x + block_width, y + block_height - text_height), fill=0) + output_img.line((x,y) + (x + block_offset, y), fill=0) + output_img.line((x + block_offset, y) + (x + block_offset, y + block_height - text_height), fill=0) + output_img.line((x + block_offset, y + block_height - text_height) + (x + block_width, y + block_height - text_height), fill=0) output_img.line((x + block_width, y + block_height - text_height) + (x + block_width, y + block_height), fill=0) output_img.line((x,y + block_height) + (x + block_width, y + block_height), fill=0) output_img.line((x,y) + (x, y + block_height), fill=0) #the text - output_img.multiline_text((x + block_width * .1, y + block_height - text_height * .5), condition, font = font, fill = (0), anchor="lm") + output_img.multiline_text((x + block_offset, y + block_height - text_height * .5), condition, font = font, fill = (0), anchor="lm") - #the x, y offset then the x,y draw size (the canvas) - return x + block_width * .1, y, block_width * .9 + #x, y and width of children + return x + block_offset, y, block_width - block_offset def NSD_save(filepath: str): """Save the created file""" diff --git a/interpreter/NassiShneidermann.py b/interpreter/NassiShneidermann.py index fe27982..abd5a7b 100644 --- a/interpreter/NassiShneidermann.py +++ b/interpreter/NassiShneidermann.py @@ -43,7 +43,8 @@ class NassiShneidermanDiagram: height = scope.get_height() with NSD_writer(output_path, width, height): y = 0 - for instruction in scope: + for instruction in scope: + print(instruction.instruction_text) y = instruction.convert_to_image(0, y, width) @staticmethod diff --git a/interpreter/_token.py b/interpreter/_token.py index bb8af19..bc3f783 100644 --- a/interpreter/_token.py +++ b/interpreter/_token.py @@ -6,7 +6,7 @@ from enum import IntEnum from typing import Union NUMERIC_CONSTANT_PATTERN = re.compile(r"""([0-9]+)|(true)|(false)""") -KEYWORD_PATTERN = re.compile(r"""(return)|(continue)|(break)|(new)""") +KEYWORD_PATTERN = re.compile(r"""(return)$|(continue)$|(break)$|(new)$""") STRING_LITERAL_PATTERN = re.compile(r"""('|\")(.*)(\"|')""") MATH_OP_PATTERN = re.compile(r"""\+|-|\*|/|<|>""") diff --git a/interpreter/function_scope.py b/interpreter/function_scope.py index c6322cd..0bbe22b 100644 --- a/interpreter/function_scope.py +++ b/interpreter/function_scope.py @@ -15,10 +15,10 @@ class Function_scope(Iterable): self.args = args def get_height(self) -> int: - h = 0.0 + h = 0 for inst in self.contents: h += inst.get_block_height() - return int(h) + return max(h, 5) #a NSD has to be at least 5 pixels tall def get_width(self) -> int: w = 200 #minimum width for every block