Station - Ein Code-Interpreter für strukturierte MyKaGoto-Programme
Aufgabe des Code-Interpreters
Der Code-Erzeuger hat die Aufgabe, strukturierte MyKaGoto-Programme auszuführen. Wir verdeutlichen die Ausführung an einem entsprechenden Goto-Programm.
Bei der Ausführung müssen der aktuelle Variablenzustand und die aktuelle Ausführungsstelle im Programm
verwaltet werden.
Zur Verwaltung der Ausführungsstelle wird hier ein sog. Programmzähler benutzt. Dieser Programmzähler
wird im Folgenden durch das Symbol >
gekennzeichnet.
Programm: >links label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen schritt goto .L0 label .L2 Roboter: (0, 0, 'S') Welt - Ziegel: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links >label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen schritt goto .L0 label .L2 Roboter: (0, 0, 'O') Welt - Ziegel: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links label .L0 >if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen schritt goto .L0 label .L2 Roboter: (0, 0, 'O') Welt - Ziegel: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links label .L0 if nichtVorWand: goto .L1 else: goto .L2 >label .L1 ziegelHinlegen schritt goto .L0 label .L2 Roboter: (0, 0, 'O') Welt - Ziegel: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 >ziegelHinlegen schritt goto .L0 label .L2 Roboter: (0, 0, 'O') Welt - Ziegel: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen >schritt goto .L0 label .L2 Roboter: (0, 0, 'O') Welt - Ziegel: [[0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen schritt >goto .L0 label .L2 Roboter: (1, 0, 'O') Welt - Ziegel: [[0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== Programm: links >label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen schritt goto .L0 label .L2 Roboter: (1, 0, 'O') Welt - Ziegel: [[0, 1, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] ===================================================================================== ... ===================================================================================== Programm: links label .L0 if nichtVorWand: goto .L1 else: goto .L2 label .L1 ziegelHinlegen schritt goto .L0 label .L2 Roboter: (4, 0, 'O') Welt - Ziegel: [[0, 1, 1, 1, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
Alles klar?
Implementierung des Code-Interpreters
Wir benutzen Objekte der Klasse Roboter
und Welt
(vgl. ...) zur
Simulation der Roboterwelt.
Der Code-Interpreter wird durch ein Objekt der Klasse InterpreterMyKaGoto
realisiert.
Dieses Objekt verfügt insbesondere über eine Methode anweisungAusfuehren
, die
letztlich für das Auswerten von Anweisungen zuständig ist.
class InterpreterMyKaGoto(object):
def __init__(self, rob):
self.programm = None
self.pc = 0
self.roboter = rob
def initProgramm(self, p):
self.programm = p
self.pc = 0
def getProgramm(self):
return self.programm
def getPC(self):
return self.pc
def anweisungAusfuehren(self):
if self.pc < len(self.programm):
zeile = self.programm[self.pc]
label = zeile[0]
if label != None:
self.pc = self.pc + 1
else:
anweisung = zeile[1]
if anweisung[0] in ["schritt",
"links",
"rechts",
"ziegelHinlegen",
"ziegelAufheben",
"markeSetzen",
"markeLoeschen",
"pass"]:
self.verarbeiteAnweisung(anweisung[0])
self.pc = self.pc + 1
elif anweisung[0] == "if":
if self.verarbeiteBedingung(anweisung[1][0]):
self.verarbeiteGoto(anweisung[2])
else:
self.verarbeiteGoto(anweisung[3])
elif anweisung[0] == "goto":
self.verarbeiteGoto(anweisung)
elif anweisung[0] == "noop":
self.pc = self.pc + 1
def verarbeiteAnweisung(self, bezeichner):
if bezeichner == "schritt":
self.roboter.schritt()
elif bezeichner == "links":
self.roboter.links()
elif bezeichner == "rechts":
self.roboter.rechts()
elif bezeichner == "markeSetzen":
self.roboter.markeSetzen()
elif bezeichner == "markeLoeschen":
self.roboter.markeLoeschen()
elif bezeichner == "ziegelHinlegen":
self.roboter.ziegelHinlegen()
elif bezeichner == "ziegelAufheben":
self.roboter.ziegelAufheben()
elif bezeichner == "pass":
self.roboter.pause()
def verarbeiteBedingung(self, bezeichner):
if bezeichner == "vorZiegel":
return self.roboter.vorZiegel()
elif bezeichner == "nichtVorZiegel":
return self.roboter.nichtVorZiegel()
elif bezeichner == "vorWand":
return self.roboter.vorWand()
elif bezeichner == "nichtVorWand":
return self.roboter.nichtVorWand()
elif bezeichner == "aufMarke":
return self.roboter.aufMarke()
elif bezeichner == "nichtAufMarke":
return self.roboter.nichtAufMarke()
def verarbeiteGoto(self, anweisung):
label = anweisung[1]
self.pc = 0
while self.programm[self.pc][0] != label:
self.pc = self.pc + 1
Objekte der vorgestellten Klassen können jetzt direkt genutzt werden, um strukturierte Goto-Programme auszuführen.
from roboterwelt import *
from interpreterMyKaGoto import *
# Testprogramm
programm = [
(None, ['links']),
('.L0', ['noop']),
(None, ['if', ['nichtVorWand'], ['goto', '.L1'], ['goto', '.L2']]),
('.L1', ['noop']),
(None, ['ziegelHinlegen']),
(None, ['schritt']),
(None, ['goto', '.L0']),
('.L2', ['noop'])
]
# Erzeugung des Interpreters
roboter = Roboter()
welt = Welt(5, 5)
roboter.setWelt(welt)
interpreterMyKaGoto = InterpreterMyKaGoto(roboter)
# Initialisierung des Programms
interpreterMyKaGoto.initProgramm(programm)
# Ausführung des Programms und Ausgabe der Zustände
print('Roboter:')
print(roboter.getZustand())
#print('Welt - Marken:')
#print(welt.marken)
print('Welt - Ziegel:')
print(welt.ziegel)
print('---------------------------')
weiter = input("weiter mit return")
print('---------------------------')
while interpreterMyKaGoto.getPC() < len(interpreterMyKaGoto.getProgramm()):
print('aktuelle Programmzeile:')
print(interpreterMyKaGoto.programm[interpreterMyKaGoto.pc])
interpreterMyKaGoto.anweisungAusfuehren()
print()
print('Roboter:')
print(roboter.getZustand())
#print('Welt - Marken:')
#print(welt.marken)
print('Welt - Ziegel:')
print(welt.ziegel)
print('---------------------------')
weiter = input("weiter mit return")
print('---------------------------')
Aufgabe 1
Probiere das selbst einmal aus. Teste verschiedene strukturierte MyKaGoto-Programme.