Station - Ein Code-Interpreter für strukturierte MyGoto-Programme
Aufgabe des Code-Interpreters
Der Code-Interpreter hat die Aufgabe, Programme auszuführen.
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.
Implementierung des Code-Interpreters
Zur Verwaltung des Variablenzustans wird ein Objekt der Klasse Variablenzustand
benutzt.
Dieses Objekt stellt Operationen bereit, mit denen ein Variablenwert ermittelt und auch ein Variablenwert
neu gesetzt werden kann.
class Variablenzustand(object): def __init__(self): self.variablen = [] def initVariablen(self, v): self.variablen = v def getVariable(self, bezeichner): ergebnis = None for eintrag in self.variablen: if eintrag[0] == bezeichner: ergebnis = eintrag[1] return ergebnis def setVariable(self, bezeichner, wert): existiertVariable = False for eintrag in self.variablen: if eintrag[0] == bezeichner: existiertVariable = True eintrag[1] = wert if not existiertVariable: self.variablen = self.variablen + [[bezeichner, wert]] def setVariablenzustand(self, zustand): self.variablen = zustand def getIndex(self, bezeichner): ergebnis = None i = 0 for eintrag in self.variablen: if eintrag[0] == bezeichner: ergebnis = i i = i + 1 return ergebnis
Der Code-Interpreter wird durch ein Objekt der Klasse InterpreterGoto
realisiert.
Dieses Objekt verfügt insbesondere über eine Methode anweisungAusfuehren
, die
letztlich für das Auswerten von Anweisungen zuständig ist.
class InterpreterGoto(object):
def __init__(self, v):
self.programm = None
self.pc = 0
self.variablenzustand = v
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):
z = self.variablenzustand
c = self.programm
# Auswertung des Codes
PC = self.pc
op = c[PC][0] # Opcode des Befehls
addr = c[PC][1] # Adressteil des Befehls
if op == 'inc':
z.setVariable(addr, z.getVariable(addr) + 1)
PC = PC + 1
elif op == 'dec':
if z.getVariable(addr) > 0:
z.setVariable(addr, z.getVariable(addr) - 1)
else:
print('Fehler - kein Dekrementieren möglich')
exit()
PC = PC + 1
elif op == 'jmp':
jmp = c[PC][1]
PC = PC + eval(jmp)
elif op == 'tst':
if z.getVariable(addr) == 0:
PC = PC + 2
else:
PC = PC + 1
elif op == 'hlt':
pass
else:
print('unbekannter Befehl')
self.pc = PC
Objekte der vorgestellten Klassen können jetzt direkt genutzt werden, um strukturierte Goto-Programme auszuführen.
from interpreterGoto import *
from variablenzustand import *
# Testprogramm
programm = [('tst', 'x'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', 'x'), ('jmp', '(-4)'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('inc', 'x'), ('tst', 'y'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', 'y'), ('jmp', '(-4)'), ('inc', 'y'), ('inc', 'y'), ('inc', 'y'), ('inc', 'y'), ('inc', 'y'), ('inc', 'y'), ('tst', '_h0'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', '_h0'), ('jmp', '(-4)'), ('tst', 'x'), ('jmp', '(+4)'), ('tst', 'y'), ('jmp', '(+9)'), ('jmp', '(+9)'), ('tst', 'y'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', 'x'), ('dec', 'y'), ('inc', '_h1'), ('jmp', '(-11)'), ('inc', '_h0'), ('tst', '_h1'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', '_h1'), ('inc', 'x'), ('inc', 'y'), ('jmp', '(-6)'), ('tst', '_h0'), ('jmp', '(+2)'), ('jmp', '(+122)'), ('tst', '_h2'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', '_h2'), ('jmp', '(-4)'), ('tst', 'x'), ('jmp', '(+4)'), ('tst', 'y'), ('jmp', '(+9)'), ('jmp', '(+8)'), ('tst', 'y'), ('jmp', '(+2)'), ('jmp', '(+6)'), ('dec', 'x'), ('dec', 'y'), ('inc', '_h3'), ('jmp', '(-11)'), ('inc', '_h2'), ('tst', '_h3'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', '_h3'), ('inc', 'x'), ('inc', 'y'), ('jmp', '(-6)'), ('tst', '_h2'), ('jmp', '(+2)'), ('jmp', '(+45)'), ('tst', 'y'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', 'y'), ('inc', '_h4'), ('inc', '_h6'), ('jmp', '(-6)'), ('tst', '_h6'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h6'), ('inc', 'y'), ('jmp', '(-5)'), ('tst', 'x'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', 'x'), ('inc', '_h5'), ('inc', '_h6'), ('jmp', '(-6)'), ('tst', '_h6'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h6'), ('inc', 'x'), ('jmp', '(-5)'), ('tst', '_h5'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h5'), ('dec', '_h4'), ('jmp', '(-5)'), ('tst', 'y'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', 'y'), ('jmp', '(-4)'), ('tst', '_h4'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h4'), ('inc', 'y'), ('jmp', '(-5)'), ('jmp', '(+44)'), ('tst', 'x'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', 'x'), ('inc', '_h4'), ('inc', '_h6'), ('jmp', '(-6)'), ('tst', '_h6'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h6'), ('inc', 'x'), ('jmp', '(-5)'), ('tst', 'y'), ('jmp', '(+2)'), ('jmp', '(+5)'), ('dec', 'y'), ('inc', '_h5'), ('inc', '_h6'), ('jmp', '(-6)'), ('tst', '_h6'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h6'), ('inc', 'y'), ('jmp', '(-5)'), ('tst', '_h5'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h5'), ('dec', '_h4'), ('jmp', '(-5)'), ('tst', 'x'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', 'x'), ('jmp', '(-4)'), ('tst', '_h4'), ('jmp', '(+2)'), ('jmp', '(+4)'), ('dec', '_h4'), ('inc', 'x'), ('jmp', '(-5)'), ('tst', '_h2'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', '_h2'), ('jmp', '(-4)'), ('jmp', '(-148)'), ('tst', '_h0'), ('jmp', '(+2)'), ('jmp', '(+3)'), ('dec', '_h0'), ('jmp', '(-4)'), ('hlt', '')]
variablen = [['x', 0],['y', 0],['_h0', 0],['_h1', 0],['_h2', 0],['_h3', 0],['_h4', 0],['_h5', 0],['_h6', 0]]
# Erzeugung des Interpreters
variablenzustand = Variablenzustand()
interpreterGoto = InterpreterGoto(variablenzustand)
# Initialisierung des Programms
interpreterGoto.initProgramm(programm)
variablenzustand.initVariablen(variablen)
# Ausführung des Programms und Ausgabe der Zustände
print('Variablenzustand vorher')
print(variablenzustand.variablen)
print()
while interpreterGoto.getProgramm()[interpreterGoto.getPC()][0] != 'hlt':
interpreterGoto.anweisungAusfuehren()
print('Variablenzustand nachher')
print(variablenzustand.variablen)
Aufgabe 1
Probiere das selbst einmal aus. Teste verschiedene strukturierte MyGoto-Programme.