improved interpreter WIP

This commit is contained in:
weckyy702
2020-12-28 16:42:30 +01:00
parent c3a61da020
commit 978d4bf9d2
4 changed files with 407 additions and 101 deletions

View File

@@ -2,8 +2,6 @@ from typing import Iterable, List
from abc import abstractmethod
from draw import code_to_image as cti
class Iinstruction:
"""Base class for all instructions"""
@@ -18,6 +16,10 @@ class Iinstruction:
def getblksize(self) -> float:
return self._getblksize()
@abstractmethod
def __str__(self) -> str:
pass
def _getblksize(self) -> float:
return cti.get_text_size(self.instruction_text)[1]
@@ -31,7 +33,8 @@ class generic_instruction(Iinstruction):
def to_image(self, x:int, y:int, x_sz: int) -> Iterable[float]:
return cti.draw_generic_instruction(self.instruction_text, x, y, x_sz, self.getblksize())
def __str__(self) -> str:
return self.instruction_text
class if_instruction(Iinstruction):
"""Conditional structure
@@ -79,6 +82,18 @@ class if_instruction(Iinstruction):
for instruction in self.false_case:
x, y = instruction.to_image(x, y, x_sz)
def __str__(self) -> str:
res = f"if({self.instruction_text}) {'{'}\n"
for inst in self.true_case:
res += '\t'+str(inst)+";\n"
res += "}"
if self.false_case:
res += " else {"
for inst in self.true_case:
res += '\t'+str(inst)+";\n"
res += "}"
return res
#TODO
# class switch_instruction(Iinstruction):
# """Switch structure"""
@@ -124,6 +139,13 @@ class while_instruction_front(Iinstruction):
x, y = inst.to_image(x, y, x_sz)
return self.get_children_size()
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_back(while_instruction_front):
def __init__(self, condition: str, instructions: List[Iinstruction]) -> None:
@@ -133,3 +155,10 @@ class while_instruction_back(while_instruction_front):
children_x, children_y, children_sz_x = cti.draw_while_loop_back(self.instruction_text, x, y, x_sz, self.getblksize())
self.draw_children(children_x, children_y, children_sz_x)
return x, y + self.getblksize()
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

View File

@@ -29,6 +29,15 @@ class NassiShneidermanDiagram:
h += inst.getblksize()
return int(h)
def _save_scope(self, scope_name: str, scope_instructions: List[Iinstruction]):
"""DEBUGING ONLY"""
image_y_sz = 1000
x, y, = 0, 0
with NSD_writer(f"./{scope_name}", 1000, image_y_sz):
x, y = 0, 0
for instruction in scope_instructions:
x, y = instruction.to_image(x, y, 1000)
def convert_to_image(self, output_path: str, filename: str, x_size: int=200):
for i in range(len(self.scopes)):
filepath = f"{output_path}/{filename}#{i}"

View File

@@ -6,6 +6,11 @@ from typing import List, Tuple
from errors.custom import InterpreterException, JavaSyntaxError, ScopeNotFoundException
from draw.Iinstruction import *
logging.warning("""As the Interpreter is still WIP, some Java language features are not supported. These include:
*else if statements
*for loops
Please remove these features from the source code as they will result in incorrect behaviour""")
COMMENT_PATTERN = re.compile(r"""^//|^/\*\*|^\*|^--""")
REMOVE_KEYWORDS = [' ', "public", "private", ';']
VARIABLE_TAGS = ["byte", "short", "int", "long", "float", "double", "boolean", "char", "String"]
@@ -29,10 +34,6 @@ function_regex = function_regex[0:-1]+ r""").*([(].*[)].*)"""
function_pattern = re.compile(function_regex)
logging.warn("""The Interpreter is WIP and cannot interpret classes or function definitions
as those do not exist in Nass-Shneidermann Diagrams. A fix is in the making
""")
def replace_all_tags(org: str):
return remove_pattern.sub(lambda m: REPLACE[re.escape(m.group(0))], org)
@@ -45,9 +46,9 @@ def load_src(filepath: str) -> List[str]:
line = replace_all_tags(_line.strip())
if line and not COMMENT_PATTERN.match(line):
lines.append(line)
if line.__contains__('{'):
if '{' in line:
brace_open_count += 1
if line.__contains__('}'):
if '}' in line:
brace_closed_count += 1
except:
raise FileNotFoundError(f"File {filepath} was not found!")
@@ -60,7 +61,7 @@ def load_src(filepath: str) -> List[str]:
def check_src(src: List[str], line_index: int, tag: str) -> bool:
if line_index >= len(src):
return False
return src[line_index].__contains__(tag)
return tag in src[line_index]
def check_line_start(src: List[str], line_index: int, tag: str) -> bool:
if line_index >= len(src):
@@ -88,11 +89,13 @@ def get_scope_exit_offset(src: List[str], start_idx: int) -> int:
while i < len(src):
line = src[i]
if "{" in line:
if '{' in line:
i += get_scope_exit_offset(src, i+1)
elif "}" in line:
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]:
@@ -170,7 +173,7 @@ def get_instructions_in_scope(src: List[str], start_idx: int = 0) -> Tuple[List[
line = src[i]
try:
if check_src(src, i, "}"): #We exited this scope, return it
if check_src(src, i, '}'): #We exited this scope, return it
break
instruction, i = handle_instruction(line, src, i)
@@ -186,7 +189,7 @@ 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]]:
def get_function_scope_spans(src: List[str]) -> List[Tuple[int, int, str]]:
spans = []
i = 0
while i < len(src):
@@ -196,9 +199,13 @@ def get_function_scope_spans(src: List[str]) -> List[Tuple[int, int]]:
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)
span = (i+brace_offset, i+brace_offset+scope_offset)
span = (i+brace_offset, i+brace_offset+scope_offset, function_name)
i += scope_offset + brace_offset
spans.append(span)
@@ -209,16 +216,36 @@ def get_function_scope_spans(src: List[str]) -> List[Tuple[int, int]]:
return spans
def scope_handler (int_info: Tuple[List[str], Tuple[int, int]]) -> List[Iinstruction]:
return get_instructions_in_scope(int_info[0][int_info[1][0]: int_info[1][1]])[0]
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 get_instructions_in_scopes(src: List[str], scope_spans: List[Tuple[int, int]]):
instructions = list(map(scope_handler, [(src, scope_span) for scope_span in scope_spans]))
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]]:
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

View File

@@ -1,3 +1,13 @@
//import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
// public class Rover extends Actor
// {
// private Display anzeige;
// /**
// * this function is to be implemented by the user
// * depending on the needed actions
// */
public void act()
{
S66Nr3(7);
@@ -29,57 +39,288 @@ private void fahreUmHuegel(String richtung)
drehe(pri);
}
private void fahreBisHuegel()
{
while(!huegelVorhanden("vorne"))
{
fahre();
}
}
// private void fahreBisHuegel()
// {
// while(!huegelVorhanden("vorne"))
// {
// fahre();
// }
// }
private void fahreZeileDreheHoch()
{
fahreBisHuegel();
fahreUmHuegel("Hoch");
fahreBisHuegel();
drehe("um");
// private void fahreZeileDreheHoch()
// {
// fahreBisHuegel();
// fahreUmHuegel("Hoch");
// fahreBisHuegel();
// drehe("um");
fahreBisHuegel();
fahreUmHuegel("Runter");
fahreBisHuegel();
drehe("rechts");
fahre();
drehe("rechts");
}
// fahreBisHuegel();
// fahreUmHuegel("Runter");
// fahreBisHuegel();
// drehe("rechts");
// fahre();
// drehe("rechts");
// }
private void fahreZeileDreheRunter(boolean geheInNächsteZeile)
{
fahreBisHuegel();
fahreUmHuegel("Runter");
fahreBisHuegel();
drehe("um");
// private void fahreZeileDreheRunter(boolean geheInNächsteZeile)
// {
// fahreBisHuegel();
// fahreUmHuegel("Runter");
// fahreBisHuegel();
// drehe("um");
fahreBisHuegel();
fahreUmHuegel("Hoch");
fahreBisHuegel();
if(geheInNächsteZeile) {
drehe("rechts");
fahre();
drehe("rechts");
} else {
drehe("um");
}
}
// fahreBisHuegel();
// fahreUmHuegel("Hoch");
// fahreBisHuegel();
// if(geheInNächsteZeile) {
// drehe("rechts");
// fahre();
// drehe("rechts");
// } else {
// drehe("um");
// }
// }
private void S66Nr3(int anzahlZeilen)
{
if(anzahlZeilen < 3) {
nachricht("Ich muss mindestens drei Zeilen fahren! :(");
return;
}
fahreZeileDreheHoch();
for(int i = 1; i < anzahlZeilen-1; i++) {
fahreZeileDreheRunter(true);
}
fahreZeileDreheRunter(false);
}
// private void S66Nr3(int anzahlZeilen)
// {
// if(anzahlZeilen < 3) {
// nachricht("Ich muss mindestens drei Zeilen fahren! :(");
// return;
// }
// fahreZeileDreheHoch();
// //for(int i = 1; i < anzahlZeilen-1; i++) {
// fahreZeileDreheRunter(true);
// //}
// fahreZeileDreheRunter(false);
// }
// // /**
// // * Der Rover bewegt sich ein Feld in Fahrtrichtung weiter.
// // * Sollte sich in Fahrtrichtung ein Objekt der Klasse Huegel befinden oder er sich an der Grenze der Welt befinden,
// // * dann erscheint eine entsprechende Meldung auf dem Display.
// // */
// // public void fahre()
// // {
// // int posX = getX();
// // int posY = getY();
// // if(huegelVorhanden("vorne"))
// // {
// // nachricht("Zu steil!");
// // }
// // else if(getRotation()==270 && getY()==1)
// // {
// // nachricht("Ich kann mich nicht bewegen");
// // }
// // else
// // {
// // move(1);
// // Greenfoot.delay(1);
// // }
// // if(posX==getX()&&posY==getY()&&!huegelVorhanden("vorne"))
// // {
// // nachricht("Ich kann mich nicht bewegen");
// // }
// // }
// // /**
// // * Der Rover dreht sich um 90 Grad in die Richtung, die mit richtung (ᅵlinksᅵ oder ᅵrechtsᅵ) ᅵbergeben wurde.
// // * Sollte ein anderer Text (String) als "rechts" oder "links" ᅵbergeben werden, dann erscheint eine entsprechende Meldung auf dem Display.
// // */
// // public void drehe(String richtung)
// // {
// // if(richtung.equals("rechts")){
// // setRotation(getRotation()+90);
// // }else if(richtung.equals("links")){
// // setRotation(getRotation()-90);
// // } else if(richtung.equals("um")) {
// // setRotation(getRotation()+180);
// // }else {
// // nachricht("Keinen Korrekte Richtung gegeben!");
// // }
// // }
// // /**
// // * Der Rover gibt durch einen Wahrheitswert (true oder false )zurᅵck, ob sich auf seiner Position ein Objekt der Klasse Gestein befindet.
// // * Eine entsprechende Meldung erscheint auch auf dem Display.
// // */
// // public boolean gesteinVorhanden()
// // {
// // if(getOneIntersectingObject(Gestein.class)!=null)
// // {
// // nachricht("Gestein gefunden!");
// // return true;
// // }
// // return false;
// // }
// // /**
// // * Der Rover ᅵberprᅵft, ob sich in richtung ("rechts", "links", oder "vorne") ein Objekt der Klasse Huegel befindet.
// // * Das Ergebnis wird auf dem Display angezeigt.
// // * Sollte ein anderer Text (String) als "rechts", "links" oder "vorne" ᅵbergeben werden, dann erscheint eine entsprechende Meldung auf dem Display.
// // */
// // public boolean huegelVorhanden(String richtung)
// // {
// // int rot = getRotation();
// // if (richtung=="vorne" && rot==0 || richtung=="rechts" && rot==270 || richtung=="links" && rot==90)
// // {
// // if(getOneObjectAtOffset(1,0,Huegel.class)!=null && ((Huegel)getOneObjectAtOffset(1,0,Huegel.class)).getSteigung() >30)
// // {
// // return true;
// // }
// // }
// // if (richtung=="vorne" && rot==180 || richtung=="rechts" && rot==90 || richtung=="links" && rot==270)
// // {
// // if(getOneObjectAtOffset(-1,0,Huegel.class)!=null && ((Huegel)getOneObjectAtOffset(-1,0,Huegel.class)).getSteigung() >30)
// // {
// // return true;
// // }
// // }
// // if (richtung=="vorne" && rot==90 || richtung=="rechts" && rot==0 || richtung=="links" && rot==180)
// // {
// // if(getOneObjectAtOffset(0,1,Huegel.class)!=null && ((Huegel)getOneObjectAtOffset(0,1,Huegel.class)).getSteigung() >30)
// // {
// // return true;
// // }
// // }
// // if (richtung=="vorne" && rot==270 || richtung=="rechts" && rot==180 || richtung=="links" && rot==0)
// // {
// // if(getOneObjectAtOffset(0,-1,Huegel.class)!=null && ((Huegel)getOneObjectAtOffset(0,-1,Huegel.class)).getSteigung() >30)
// // {
// // return true;
// // }
// // }
// // if(richtung!="vorne" && richtung!="links" && richtung!="rechts")
// // {
// // nachricht("Befehl nicht korrekt!");
// // }
// // return false;
// // }
// // /**
// // * Der Rover ermittelt den Wassergehalt des Gesteins auf seiner Position und gibt diesen auf dem Display aus.
// // * Sollte kein Objekt der Klasse Gestein vorhanden sein, dann erscheint eine entsprechende Meldung auf dem Display.
// // */
// // public void analysiereGestein()
// // {
// // if(gesteinVorhanden())
// // {
// // nachricht("Gestein untersucht! Wassergehalt ist " + ((Gestein)getOneIntersectingObject(Gestein.class)).getWassergehalt()+"%.");
// // Greenfoot.delay(1);
// // removeTouching(Gestein.class);
// // }
// // else
// // {
// // nachricht("Hier ist kein Gestein");
// // }
// // }
// // /**
// // * Der Rover erzeugt ein Objekt der Klasse ᅵMarkierungᅵ auf seiner Position.
// // */
// // public void setzeMarke()
// // {
// // getWorld().addObject(new Marke(), getX(), getY());
// // }
// // /**
// // * *Der Rover gibt durch einen Wahrheitswert (true oder false )zurᅵck, ob sich auf seiner Position ein Objekt der Marke befindet.
// // * Eine entsprechende Meldung erscheint auch auf dem Display.
// // */
// // public boolean markeVorhanden()
// // {
// // if(getOneIntersectingObject(Marke.class)!=null)
// // {
// // return true;
// // }
// // return false;
// // }
// // public void entferneMarke()
// // {
// // if(markeVorhanden())
// // {
// // removeTouching(Marke.class);
// // }
// // }
// // private void nachricht(String pText)
// // {
// // if(anzeige!=null)
// // {
// // anzeige.anzeigen(pText);
// // Greenfoot.delay(1);
// // anzeige.loeschen();
// // }
// // }
// // private void displayAusschalten()
// // {
// // getWorld().removeObject(anzeige);
// // }
// // protected void addedToWorld(World world)
// // {
// // setImage("images/rover.png");
// // world = getWorld();
// // anzeige = new Display();
// // anzeige.setImage("images/nachricht.png");
// // world.addObject(anzeige, 7, 0);
// // if(getY()==0)
// // {
// // setLocation(getX(),1);
// // }
// // anzeige.anzeigen("Ich bin bereit");
// // }
// // class Display extends Actor
// // {
// // GreenfootImage bild;
// // public Display()
// // {
// // bild = getImage();
// // }
// // public void act()
// // {
// // }
// // public void anzeigen(String pText)
// // {
// // loeschen();
// // getImage().drawImage(new GreenfootImage(pText, 25, Color.BLACK, new Color(0, 0, 0, 0)),10,10);
// // }
// // public void loeschen()
// // {
// // getImage().clear();
// // setImage("images/nachricht.png");
// // }
// // }
// // public class Direction {
// // Direction(int val){
// // this.value = val;
// // }
// // final int value;
// // };
// // }