English translation
This commit is contained in:
parent
a65f02b198
commit
d95d0de5dc
49
666.py
49
666.py
@ -1,34 +1,27 @@
|
||||
import argparse
|
||||
import malbolge
|
||||
import sys
|
||||
|
||||
istruzioni = [
|
||||
"Utilizzo:",
|
||||
"666 [-f] input",
|
||||
" * -f: specifica un file.",
|
||||
" * input: file o codice da eseguire."
|
||||
]
|
||||
|
||||
|
||||
def utilizzo():
|
||||
print(*istruzioni, sep="\n")
|
||||
exit(1)
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Malbolge interpeter")
|
||||
parser.add_argument("-f", "--file",
|
||||
action="store_true", help="specify a file")
|
||||
parser.add_argument("input", type=str,
|
||||
help="malbolge program (string or file)")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
programma = sys.argv[1]
|
||||
except IndexError:
|
||||
utilizzo()
|
||||
if args.file:
|
||||
try:
|
||||
program = open(args.input).read()
|
||||
except FileNotFoundError:
|
||||
parser.error("File not Found.")
|
||||
if program == "":
|
||||
parser.error("File is empty.")
|
||||
else:
|
||||
program = args.input
|
||||
|
||||
if sys.argv[1] == "-f":
|
||||
try:
|
||||
programma = open(sys.argv[2]).read()
|
||||
except FileNotFoundError:
|
||||
exit("File non trovato.")
|
||||
except IndexError:
|
||||
utilizzo()
|
||||
if programma == "":
|
||||
exit("File vuoto.")
|
||||
else:
|
||||
programma = sys.argv[1]
|
||||
machine = malbolge.Machine()
|
||||
machine.run(program)
|
||||
|
||||
macchina = malbolge.Macchina()
|
||||
macchina.esegui(programma)
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
10
License.txt
10
License.txt
@ -1,10 +0,0 @@
|
||||
* 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
|
19
README.md
19
README.md
@ -1,11 +1,14 @@
|
||||
666
|
||||
===
|
||||
# 666
|
||||
|
||||
Macchina virtuale per codice Malbolge
|
||||
-------------------------------------
|
||||
## Malbolge virtual machine written in python
|
||||
|
||||
### Informazioni
|
||||
Una macchina virtuale per eseguire codice Malbolge in Python.
|
||||
### Info
|
||||
A virtual machine to run Malbolge code in python.
|
||||
|
||||
### Istruzioni
|
||||
Lanciare 666.py per le istruzioni.
|
||||
### Help
|
||||
Launch `666 -h` for help.
|
||||
|
||||
### License
|
||||
Dual licensed under the MIT and GPL licenses:
|
||||
http://www.opensource.org/licenses/mit-license.php
|
||||
http://www.gnu.org/licenses/gpl.html
|
||||
|
@ -1,2 +1,2 @@
|
||||
from .trinario import *
|
||||
from .macchina import *
|
||||
from .trinary import *
|
||||
from .machine import *
|
||||
|
@ -1,154 +0,0 @@
|
||||
from .trinario import *
|
||||
|
||||
|
||||
class Macchina:
|
||||
|
||||
def esegui(self, programma):
|
||||
"""Esegue il programma Malbolge fornito come stringa."""
|
||||
|
||||
#Accumulatore
|
||||
self.a = trin(0)
|
||||
|
||||
#Registri
|
||||
self.d = trinlist()
|
||||
self.c = trinlist()
|
||||
|
||||
#Puntatori
|
||||
self.puntatore_c = trin(0)
|
||||
self.puntatore_d = trin(0)
|
||||
|
||||
istruzioni = {
|
||||
"j": self.__scambia_d,
|
||||
"i": self.__scambia_c,
|
||||
"*": self.__ruota,
|
||||
"p": self.__pazza,
|
||||
"<": self.__leggi,
|
||||
"/": self.__stampa,
|
||||
"v": self.__esci,
|
||||
"o": self.__nulla,
|
||||
}
|
||||
|
||||
#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", " "):
|
||||
if trinord(word) not in range(32, 127):
|
||||
raise SyntaxError("Carattere non consentito nel programma:\
|
||||
'%c' a %d." % (word, indice)
|
||||
)
|
||||
else:
|
||||
self.c[indice] = trinord(word)
|
||||
|
||||
#Esecuzione del programma
|
||||
while self.puntatore_c < len(programma):
|
||||
#Calcola ed esegue l'istruzione
|
||||
istruzione = self.__calcola_istruzione(trinchr(self.c[self.puntatore_c]))
|
||||
try:
|
||||
istruzioni[istruzione]()
|
||||
except KeyError:
|
||||
istruzioni["o"]()
|
||||
|
||||
#Operazioni per ogni istruzione
|
||||
self.c[self.puntatore_c] -= 33
|
||||
self.__traduci()
|
||||
self.puntatore_c += 1
|
||||
self.puntatore_d += 1
|
||||
|
||||
def __calcola_istruzione(self, carattere):
|
||||
"""
|
||||
Calcola l'istruzione da eseguire
|
||||
in base al carattere presente nel puntatore.
|
||||
"""
|
||||
tabella = "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkr \
|
||||
Uo[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]
|
||||
|
||||
def __traduci(self):
|
||||
"""
|
||||
Trascive l'istruzione nel registro del
|
||||
codice seguendo la tavola di conversione.
|
||||
"""
|
||||
trascrizione = str.maketrans(
|
||||
'!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN \
|
||||
OPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
|
||||
'5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72FhOA1 \
|
||||
CB6v^=I_0/8|jsb9m<.TVac`uY*MK\'X~xDl}REokN:#?G"i@'
|
||||
)
|
||||
istruzione = str.translate(trinchr(self.c[self.puntatore_c]), trascrizione)
|
||||
self.c[self.puntatore_c] = trinord(istruzione)
|
||||
|
||||
#Istruzioni
|
||||
|
||||
def __scambia_d(self):
|
||||
"""
|
||||
Istruzione Malbolge "j"
|
||||
Assegna al data pointer il valore a cui punta.
|
||||
"""
|
||||
self.puntatore_d = self.d[self.puntatore_d]
|
||||
|
||||
def __scambia_c(self):
|
||||
"""
|
||||
Istruzione Malbolge "i"
|
||||
Assegna al code pointer il valore puntato dal data pointer.
|
||||
"""
|
||||
self.puntatore_c = self.d[self.puntatore_d]
|
||||
|
||||
def __ruota(self):
|
||||
"""
|
||||
Istruzione Malbolge "*"
|
||||
Ruota la word puntata dal data pointer di un trit verso destra.
|
||||
"""
|
||||
self.d[self.puntatore_d] = trin(self.a[-1] + self.a[0:-1])
|
||||
|
||||
def __pazza(self):
|
||||
"""
|
||||
Istruzione Malbolge "p"
|
||||
Esegue l'operazione pazza con il valore nell'accumulatore e il valore
|
||||
puntato dal data pointer. Poi salva il risultato nell'accumulatore
|
||||
e nel registro dei dati.
|
||||
"""
|
||||
operazione = [[1, 0, 0], [1, 0, 2], [2, 2, 1]]
|
||||
risultato = []
|
||||
for i, j in zip(self.a, self.d[self.puntatore_d]):
|
||||
risultato += operazione[i][j],
|
||||
self.d[self.puntatore_d] = trin(risultato)
|
||||
self.a = trin(risultato)
|
||||
|
||||
def __leggi(self):
|
||||
"""
|
||||
Istruzione Malbolge "<"
|
||||
Legge un carattere dallo stdin e lo registra nell'accumulatore.
|
||||
"""
|
||||
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.")
|
||||
else:
|
||||
self.a = trinord(carattere)
|
||||
|
||||
def __stampa(self):
|
||||
"""
|
||||
Istruzione Malbolge "/"
|
||||
Stampa il carattere presente nell'accumulatore.
|
||||
"""
|
||||
print(trinchr(self.a), end="")
|
||||
|
||||
def __esci(self):
|
||||
"""
|
||||
Istruzione Malbolge "v"
|
||||
Termina l'esecuzione del programma.
|
||||
"""
|
||||
exit()
|
||||
|
||||
def __nulla(self):
|
||||
"""
|
||||
Istruzione Malbolge "o"
|
||||
Esegue l'operazione nulla.
|
||||
"""
|
||||
pass
|
@ -1,217 +0,0 @@
|
||||
class Trinario:
|
||||
"""Word trinaria"""
|
||||
|
||||
def __init__(self, valore, converti):
|
||||
#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
|
||||
)
|
||||
|
||||
def __converti(self, decimale):
|
||||
"""Restituisce il valore decimale passato in trinario."""
|
||||
trinario = []
|
||||
if decimale == 0:
|
||||
return [0]
|
||||
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
|
||||
|
||||
def __setattr__(self, nome, valore):
|
||||
"""
|
||||
Assegna entrambi i valori (decimale e trinario) quando almeno uno
|
||||
cambia.
|
||||
"""
|
||||
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, indice):
|
||||
return self.valore[indice]
|
||||
|
||||
#Override degli operatori matematici
|
||||
|
||||
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
|
||||
|
||||
class Trilista:
|
||||
"""Lista per word trinarie"""
|
||||
|
||||
def __init__(self, lista, converti):
|
||||
"""Inizializzazione della lista trinaria."""
|
||||
self.valori ={a:trin(b, converti) for a, b in enumerate(lista)}
|
||||
|
||||
#Vari override degli operatori
|
||||
|
||||
def __setitem__(self, indice, valore):
|
||||
try:
|
||||
self.valori[indice.decimale] = valore
|
||||
except AttributeError:
|
||||
self.valori[indice] = valore
|
||||
|
||||
def __getitem__(self, indice):
|
||||
try:
|
||||
return self.valori[indice.decimale]
|
||||
except AttributeError:
|
||||
return self.valori[indice]
|
||||
except KeyError:
|
||||
return trin(0)
|
||||
|
||||
def __str__(self):
|
||||
return self.valori.__str__()
|
||||
|
||||
def __repr__(self):
|
||||
return self.valori
|
||||
|
||||
#Wrappers
|
||||
|
||||
def trin(valore, converti=False):
|
||||
"""
|
||||
Restituisce una word trinaria. Fornire converti=True come parametro se
|
||||
il valore è decimale.
|
||||
"""
|
||||
return Trinario(valore, converti)
|
||||
|
||||
def trinord(carattere):
|
||||
"""
|
||||
Restituisce l'ordinale di un carattere in una word trinaria.
|
||||
"""
|
||||
return trin(ord(carattere), True)
|
||||
|
||||
def trinchr(trinario):
|
||||
"""
|
||||
Restituisce il carattere ASCII data una wordtrinaria.
|
||||
"""
|
||||
return chr(trinario.decimale % 256)
|
||||
|
||||
def trinlist(lista=[], converti=False):
|
||||
"""
|
||||
Restituisce una lista accessibile da indici trinari data una lista.
|
||||
Fornire converti=False come parametro solo se gli elementi della lista
|
||||
sono trinari.Non usare liste con basi numeriche miste.
|
||||
"""
|
||||
return Trilista(lista, converti)
|
Loading…
Reference in New Issue
Block a user