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.

X

Fehler melden

X

Suche