From 16326aed3c2589533580c4e4841e707703b4f89a Mon Sep 17 00:00:00 2001 From: Rnhmjoj Date: Wed, 20 Mar 2013 19:08:06 +0100 Subject: [PATCH] Commit iniziale --- .gitignore | 2 + 666.py | 23 +++++++ License.txt | 10 +++ README.md | 11 +++ malbolge/__init__.py | 2 + malbolge/macchina.py | 82 ++++++++++++++++++++++ malbolge/trinario.py | 160 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 290 insertions(+) create mode 100644 .gitignore create mode 100755 666.py create mode 100644 License.txt create mode 100644 README.md create mode 100644 malbolge/__init__.py create mode 100644 malbolge/macchina.py create mode 100644 malbolge/trinario.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f678d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +__pycache__/ \ No newline at end of file diff --git a/666.py b/666.py new file mode 100755 index 0000000..053f4f3 --- /dev/null +++ b/666.py @@ -0,0 +1,23 @@ +import malbolge +import sys + +try: + programma = sys.argv[1] +except IndexError: + print("Utilizzo:", "666 [-f] input", " * -f: specifica un file.", " * input: file o codice da eseguire.", sep="\n") + exit(1) + +if sys.argv[1] == "-f": + try: + programma = open(sys.argv[2]).read() + except FileNotFoundError: + exit("File non trovato.") + except IndexError: + exit("Specifica un file.") + if programma == "": + exit("File vuoto.") +else: + programma = sys.argv[1] + +macchina = malbolge.Macchina() +macchina.esegui(programma) \ No newline at end of file diff --git a/License.txt b/License.txt new file mode 100644 index 0000000..ac19f84 --- /dev/null +++ b/License.txt @@ -0,0 +1,10 @@ + * 666 + * + * Macchina virtuale per codice Malbolge. + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * @author Michele Guerini Rocco aka Rnhmjoj + * @since 2013 \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..55a99f2 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +666 +=== + +Macchina virtuale per codice Malbolge +------------------------------------- + +### Informazioni +Una macchina virtuale per eseguire codice Malbolge in Python. + +### Istruzioni +Lanciare 666.py per le istruzioni. \ No newline at end of file diff --git a/malbolge/__init__.py b/malbolge/__init__.py new file mode 100644 index 0000000..c1668a9 --- /dev/null +++ b/malbolge/__init__.py @@ -0,0 +1,2 @@ +from .trinario import * +from .macchina import * diff --git a/malbolge/macchina.py b/malbolge/macchina.py new file mode 100644 index 0000000..d08fe46 --- /dev/null +++ b/malbolge/macchina.py @@ -0,0 +1,82 @@ +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 word not in ("\n"," "): + self.c[indice] = trinord(word) + + #Esecuzione del programma + while self.puntatore_c < len(programma): + + #Determina l'istruzione da eseguire + istruzione = (self.c[self.puntatore_c.decimale] + self.puntatore_c) % 94 + if istruzione == 4: + self.puntatore_c = self.d[self.puntatore_d.decimale] + elif istruzione == 5: + self.__stampa() + elif istruzione == 23: + self.a = trinord(input()) + elif istruzione == 39: + self.__ruota() + self.a = self.d[self.puntatore_d.decimale] + elif istruzione == 40: + self.puntatore_d = self.d[self.puntatore_d.decimale] + elif istruzione == 62: + self.__pazza() + self.a = self.d[self.puntatore_d.decimale] + elif istruzione == 68: + self.__niente() + elif istruzione == 81: + self.__esci() + else: + self.__niente() + if 33 <= istruzione <= 126: + self.__traduci() + self.puntatore_c += 1 + self.puntatore_d += 1 + + 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)) \ No newline at end of file diff --git a/malbolge/trinario.py b/malbolge/trinario.py new file mode 100644 index 0000000..d1dbe56 --- /dev/null +++ b/malbolge/trinario.py @@ -0,0 +1,160 @@ +class Trinario: + + def __init__(self, valore, converti=False): + #Converte da base n a base 3 se necessario + if converti: + valore = self.__converti(valore) + self.valore = valore + + #Controllo lunghezza massima + if self.lunghezza > 10: + raise OverflowError("Limite di trit per word superato: massimo 10 (passati %d)" % self.lunghezza) + + #Conversione di base + def __converti(self, decimale): + trinario = [] + while decimale > 0: + trinario += decimale % 3, + decimale //= 3 + return trinario[::-1] + + #Vari override degli operatori + def __iter__(self): + lista = [int(i) for i in self.valore] + return iter(lista) + + def __str__(self): + return self.valore + + def __repr__(self): + return self.valore + + #Assegna entrambi i valori(decimale e trinario) quando almeno uno cambia + def __setattr__(self, nome, valore): + if nome == "valore": + if type(valore) is list: + valore = "".join([str(i) for i in valore]) + self.__dict__["valore"] = valore + elif type(valore) is str: + self.__dict__["valore"] = valore + elif type(valore) is int: + self.__dict__["valore"] = str(valore) + self.__dict__["decimale"] = int(self.valore, base=3) + self.__dict__["lunghezza"] = len(self.valore) + elif nome == "decimale": + if type(valore) is int: + self.__dict__["valore"] = str(self.decimale) + self.__dict__["decimale"] = valore + elif type(valore) is list: + valore = "".join([str(i) for i in valore]) + self.__dict__["valore"] = valore + self.__dict__["decimale"] = int(self.valore, base=3) + self.__dict__["lunghezza"] = len(self.valore) + + def __getitem__(self, chiave): + return self.valore[chiave] + + def __add__(self, altro): + try: + return Trinario(self.decimale + altro.decimale, True) + except AttributeError: + return Trinario(self.decimale + altro, True) + + def __iadd__(self, altro): + try: + return self + altro + except AttributeError: + return self.decimale + altro + + def __sub__(self, altro): + try: + return Trinario(self.decimale - altro.decimale, True) + except AttributeError: + return Trinario(self.decimale - altro, True) + + def __isub__(self, altro): + return self - altro + + def __mul__(self, altro): + try: + return Trinario(self.decimale * altro.decimale, True) + except AttributeError: + return Trinario(self.decimale * altro, True) + + def __imul__(self, altro): + return self * altro + + def __mod__(self, altro): + try: + return Trinario(self.decimale % altro.decimale, True) + except AttributeError: + return Trinario(self.decimale % altro, True) + + def __imod__(self, altro): + return self % altro + + def __truediv__(self, floor): + try: + return Trinario(self.decimale / altro.decimale, True) + except AttributeError: + return Trinario(self.decimale / altro, True) + + def __itruediv__(self, altro): + return self / altro + + def __floordiv__(self, altro): + try: + return Trinario(self.decimale // altro.decimale, True) + except AttributeError: + return Trinario(self.decimale // altro, True) + + def __ifloordiv__(self, altro): + return self // altro + + def __lt__(self, altro): + try: + return self.decimale < altro.decimale + except AttributeError: + return self.decimale < altro + + def __le__(self, altro): + try: + return self.decimale <= altro.decimale + except AttributeError: + return self.decimale <= altro + + def __eq__(self, altro): + try: + return self.decimale == altro.decimale + except AttributeError: + return self.decimale == altro + + def __ne__(self, altro): + try: + return self.decimale != self.altro + except AttributeError: + return self.decimale != altro + + def __gt__(self, altro): + try: + return self.decimale > altro.decimale + except AttributeError: + return self.decimale > altro + + def __ge__(self, altro): + try: + return self.decimale >= altro.decimale + except AttributeError: + return self.decimale >= altro + +#Ritorna una word trinaria +def trin(valore, converti=False): + return Trinario(valore, converti) + +#Ritorna l'ordinale di un carattere in una word trinaria +def trinord(carattere): + return trin(ord(carattere), True) + +#Ritorna il carattere ASCII data una word trinaria +def trinchr(trinario): + return chr(trinario.decimale % 256)