666/malbolge/macchina.py
Rnhmjoj c6af7a576a Modifiche alla sintassi
Modificato secondo le specifiche originali di Malbolge.
2013-03-27 16:59:07 +01:00

94 lines
2.9 KiB
Python

from .trinario import *
class Macchina:
def esegui(self, programma):
#Accumulatore
self.a = trin(0)
#Registri
self.d = [trin(0) for i in range(3**10)]
self.c = [trin(0) for i in range(3**10)]
#Puntatori
self.puntatore_c = trin(0)
self.puntatore_d = trin(0)
#Controllo lunghezza massima
if len(programma) > 3**10:
raise MemoryError("Memoria esaurita. Limite di 3**10 word superato.")
#Copia il programma nel registro c
for indice, word in enumerate(programma):
if trinord(word) not in range(33,127):
raise SyntaxError("Carattere non consentito nel programma: %c a %d." % (word, indice))
if word not in ("\n"," "):
self.c[indice] = trinord(word)
#Esecuzione del programma
while self.puntatore_c < len(programma):
istruzione = self.__calcola_istruzione(trinchr(self.c[self.puntatore_c.decimale]))
if istruzione == "i":
self.puntatore_c = self.d[self.puntatore_d.decimale]
elif istruzione == "/":
self.__stampa()
elif istruzione == "<":
carattere = input()
if len(carattere) > 1:
raise TypeError("Si attendeva un carattere: letta una stringa.")
elif len(carattere) == 0:
raise TypeError("Si attendeva un carattere: letta una stringa nulla.")
self.a = trinord(carattere)
elif istruzione == "*":
self.__ruota()
self.a = self.d[self.puntatore_d.decimale]
elif istruzione == "j":
self.puntatore_d = self.d[self.puntatore_d.decimale]
elif istruzione == "p":
self.__pazza()
self.a = self.d[self.puntatore_d.decimale]
elif istruzione == "o":
self.__niente()
elif istruzione == "v":
self.__esci()
else:
self.__niente()
self.c[self.puntatore_c.decimale] -= 33
self.__traduci()
self.puntatore_c += 1
self.puntatore_d += 1
#Determina l'istruzione da eseguire
def __calcola_istruzione(self, carattere):
tabella = "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkrUo[D7,XTcA\"lI.v%{gJh4G\-=O@5`_3i<?Z';FNQuY]szf$!BS/|t:Pn6^Ha"
istruzione = (trinord(carattere) - 33 + self.puntatore_c) % 94
return tabella[istruzione.decimale]
#Istruzioni
def __stampa(self):
print(trinchr(self.a), end="")
def __ruota(self):
#Ruota la word di un trit verso destra
self.d[self.puntatore_d.decimale] = trin(self.a[-1] + self.a[0:-1])
def __pazza(self):
#Operazione pazza
operazione = [[1,0,0],[1,0,2],[2,2,1]]
risultato = []
for i,j in zip(self.a, self.d[self.puntatore_d.decimale]):
risultato += operazione[i][j],
self.d[self.puntatore_d.decimale] = trin(risultato)
def __niente(self):
#Operazione nulla
pass
def __esci(self):
#Termina l'esecuzione
exit()
def __traduci(self):
#Traduce
trascrizione = str.maketrans('!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~', '5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK\'X~xDl}REokN:#?G"i@')
self.c[self.puntatore_c.decimale] = trinord(str.translate(trinchr(self.c[self.puntatore_c.decimale]), trascrizione))