English translation

This commit is contained in:
Rnhmjoj 2014-01-13 23:54:13 +01:00
parent d95d0de5dc
commit 747de71cac
3 changed files with 371 additions and 0 deletions

2
hello.mb Normal file
View File

@ -0,0 +1,2 @@
('&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>}=<M:9wv6WsU2T|nm-,jcL(I&%$#"
`CB]V?Tx<uVtT`Rpo3NlF.Jh++FdbCBA@?]!~|4XzyTT43Qsqq(Lnmkj"Fhg${z@>

153
malbolge/machine.py Normal file
View File

@ -0,0 +1,153 @@
from .trinary import *
class Machine:
def run(self, program):
"""Run Malbolge code passed as a string."""
#Accumulator
self.a = trin(0)
#Registers
self.d = trinlist()
self.c = trinlist()
#Pointers
self.pointer_c = trin(0)
self.pointer_d = trin(0)
statements = {
"j": self.__swap_d,
"i": self.__swap_c,
"*": self.__rotate,
"p": self.__crazy,
"<": self.__read,
"/": self.__print,
"v": self.__exit,
"o": self.__nop
}
#Check max lenght
if len(program) > 3 ** 10:
raise MemoryError("Out of memory. 3^10 words limit exceeded.")
#Copy the program in register c
for index, word in enumerate(program):
if word not in ("\n", " "):
if trinord(word) not in range(32, 127):
raise SyntaxError("Invalid character:'%c' a %d."
% (word, index))
else:
self.c[index] = trinord(word)
#Program execution
while self.pointer_c < len(program):
#Calculate current instruction
statement = self.__calculate_statement(trinchr(self.c[self.pointer_c]))
try:
statements[statement]()
except KeyError:
statements["o"]()
#Operations for each statement
self.c[self.pointer_c] -= 33
self.__translate()
self.pointer_c += 1
self.pointer_d += 1
def __calculate_statement(self, character):
"""
Calculates the instruction to be executed
based on the character in the pointer.
"""
table = "+b(29e*j1VMEKLyC})8&m#~W>qxdRp0wkr \
Uo[D7,XTcA\"lI.v%{gJh4G\-=O@5`_3i< \
?Z';FNQuY]szf$!BS/|t:Pn6^Ha"
statement = (trinord(character) - 33 + self.pointer_c) % 94
return table[statement.decimal]
def __translate(self):
"""
Write the statement in the code register
following the conversion table.
"""
trans = 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@'
)
statement = str.translate(trinchr(self.c[self.pointer_c]), trans)
self.c[self.pointer_c] = trinord(statement)
#Statements
def __swap_d(self):
"""
Malbolge statement "j"
Assign the data pointer the value it points to.
"""
self.pointer_d = self.d[self.pointer_d]
def __swap_c(self):
"""
Malbolge statement "i"
Assign to the code pointer the value pointed by the data pointer.
"""
self.pointer_c = self.d[self.pointer_d]
def __rotate(self):
"""
Malbolge statement "*"
Rotate the word pointed by the pointer by a trit to the right.
"""
self.d[self.pointer_d] = trin(self.a[-1] + self.a[0:-1])
def __crazy(self):
"""
Malbolge statement "p"
Performs the operation crazy with the value in the accumulator
and the value pointed by the data pointer. Then stores the result
in the accumulator and log data.
"""
operation = [[1, 0, 0], [1, 0, 2], [2, 2, 1]]
result = []
for i, j in zip(self.a, self.d[self.pointer_d]):
result += operation[i][j],
self.d[self.pointer_d] = trin(result)
self.a = trin(result)
def __read(self):
"""
Malbolge statement "<"
Reads a character from stdin and stores it in the accumulator.
"""
character = input()
if len(character) > 1:
raise TypeError("Expected a character: read a string.")
elif len(character) == 0:
raise TypeError("Expected a character: read an empty string.")
else:
self.a = trinord(character)
def __print(self):
"""
Malbolge statement "/"
Print the character present in the accumulator.
"""
print(trinchr(self.a), end="")
def __exit(self):
"""
Malbolge statement "v"
Terminate the program.
"""
exit()
def __nop(self):
"""
Malbolge statement "o"
Performs the nop operation.
"""
pass

216
malbolge/trinary.py Normal file
View File

@ -0,0 +1,216 @@
class Trinary:
"""Trinary word"""
def __init__(self, value, convert):
#Convert to base 3 if necessary
if convert:
value = self.__converti(value)
self.value = value
#Check max lenght
if self.lenght > 10:
raise OverflowError("Trit word limit exceeded: max 10 (passed %d)"
% self.lenght)
def __converti(self, decimal):
"""Return decimal value of the passed trinary."""
trinary = []
if decimal == 0:
return [0]
while decimal > 0:
trinary += decimal % 3,
decimal //= 3
return trinary[::-1]
#Operators override
def __iter__(self):
trilist = (int(i) for i in self.value)
return iter(trilist)
def __str__(self):
return self.value
def __repr__(self):
return self.value
def __setattr__(self, name, value):
"""
Assegna entrambi i valori (decimal e trinary) quando almeno uno
cambia.
"""
if name == "value":
if type(value) is list:
value = "".join([str(i) for i in value])
self.__dict__["value"] = value
elif type(value) is str:
self.__dict__["value"] = value
elif type(value) is int:
self.__dict__["value"] = str(value)
self.__dict__["decimal"] = int(self.value, base=3)
self.__dict__["lenght"] = len(self.value)
elif name == "decimal":
if type(value) is int:
self.__dict__["value"] = str(self.decimal)
self.__dict__["decimal"] = value
elif type(value) is list:
value = "".join([str(i) for i in value])
self.__dict__["value"] = value
self.__dict__["decimal"] = int(self.value, base=3)
self.__dict__["lenght"] = len(self.value)
def __getitem__(self, index):
return self.value[index]
#Math operators override
def __add__(self, other):
try:
return Trinary(self.decimal + other.decimal, True)
except AttributeError:
return Trinary(self.decimal + other, True)
def __iadd__(self, other):
try:
return self + other
except AttributeError:
return self.decimal + other
def __sub__(self, other):
try:
return Trinary(self.decimal - other.decimal, True)
except AttributeError:
return Trinary(self.decimal - other, True)
def __isub__(self, other):
return self - other
def __mul__(self, other):
try:
return Trinary(self.decimal * other.decimal, True)
except AttributeError:
return Trinary(self.decimal * other, True)
def __imul__(self, other):
return self * other
def __mod__(self, other):
try:
return Trinary(self.decimal % other.decimal, True)
except AttributeError:
return Trinary(self.decimal % other, True)
def __imod__(self, other):
return self % other
def __truediv__(self, floor):
try:
return Trinary(self.decimal / other.decimal, True)
except AttributeError:
return Trinary(self.decimal / other, True)
def __itruediv__(self, other):
return self / other
def __floordiv__(self, other):
try:
return Trinary(self.decimal // other.decimal, True)
except AttributeError:
return Trinary(self.decimal // other, True)
def __ifloordiv__(self, other):
return self // other
def __lt__(self, other):
try:
return self.decimal < other.decimal
except AttributeError:
return self.decimal < other
def __le__(self, other):
try:
return self.decimal <= other.decimal
except AttributeError:
return self.decimal <= other
def __eq__(self, other):
try:
return self.decimal == other.decimal
except AttributeError:
return self.decimal == other
def __ne__(self, other):
try:
return self.decimal != self.other
except AttributeError:
return self.decimal != other
def __gt__(self, other):
try:
return self.decimal > other.decimal
except AttributeError:
return self.decimal > other
def __ge__(self, other):
try:
return self.decimal >= other.decimal
except AttributeError:
return self.decimal >= other
class Trilist:
"""Trinary word list"""
def __init__(self, trilist, convert):
"""Trinary list inizialization."""
self.valori ={a:trin(b, convert) for a, b in enumerate(trilist)}
#Operators override
def __setitem__(self, index, value):
try:
self.valori[index.decimal] = value
except AttributeError:
self.valori[index] = value
def __getitem__(self, index):
try:
return self.valori[index.decimal]
except AttributeError:
return self.valori[index]
except KeyError:
return trin(0)
def __str__(self):
return self.valori.__str__()
def __repr__(self):
return self.valori
#Wrappers
def trin(value, convert=False):
"""
Returns a trinary word. Provide convert=True as a parameter if
the value is decimal.
"""
return Trinary(value, convert)
def trinord(carattere):
"""
Returns the ordinal value of a character in a trinary word.
"""
return trin(ord(carattere), True)
def trinchr(trinary):
"""
Returns the ASCII character given a trinary word.
"""
return chr(trinary.decimal % 256)
def trinlist(trilist=[], convert=False):
"""
Returns a trilist accessible by trinary indices given a list word.
Provide convert=False as a parameter only if the elements of trilist
are trinary. Do not use lists with mixed basis.
"""
return Trilist(trilist, convert)