INS = ['moo', 'mOo', 'moO', 'mOO', 'Moo', 'MOo',
'MoO', 'MOO', 'OOO', 'MMM', 'OOM', 'oom',
'MMm', 'MmM', 'Oom', 'oOm',
'OoM', 'oOM', 'ooo', 'mmm']
HLP = dict((s, i) for i, s in enumerate(INS))
import sys
import msvcrt
################################################################################
class COD:
def __init__(self, code):
for ins in code:
assert 0 <= ins < len(INS)
self.cod = code
self.pos = 0
def get(self):
return self.cod[self.pos]
def inc(self):
self.pos += 1
if self.pos == len(self.cod):
raise SystemExit
def dec(self):
self.pos -= 1
assert self.pos >= 0
################################################################################
class MEM:
def __init__(self):
self.mem = {}
self.pos = 0
def get(self):
if self.pos in self.mem:
return self.mem[self.pos]
return 0
def set(self, value):
if value:
self.mem[self.pos] = value
elif self.pos in self.mem:
del self.mem[self.pos]
def inc(self):
self.pos += 1
def dec (self):
self.pos -= 1
################################################################################
class DDX:
STOMACHS = 7
def __init__(self):
self.mem = [MEM() for stomach in range(self.STOMACHS)]
self.pos = 0
def __getattr__(self, name):
return getattr(self.mem[self.pos], name)
def ddx_prv(self):
self.pos = (self.pos - 1 + self.STOMACHS) % self.STOMACHS
def ddx_nxt(self):
self.pos = (self.pos + 1) % self.STOMACHS
def ddx_dec(self):
for stomach in self.mem:
stomach.dec()
def ddx_inc(self):
for stomach in self.mem:
stomach.inc()
def ddx_sub(self):
for stomach in self.mem:
stomach.set(stomach.get() - 1)
def ddx_add(self):
for stomach in self.mem:
stomach.set(stomach.get() + 1)
def ddx_nul(self):
for stomach in self.mem:
stomach.set(0)
def ddx_reg(self, reg):
if reg is None:
return sum(map(MEM.get, self.mem))
else:
all_zero = True
for stomach in self.mem:
if stomach.get():
all_zero = False
break
if all_zero:
for stomach in self.mem:
stomach.set(reg)
else:
weighting = sum(map(MEM.get, self.mem))
base, remainder = divmod(reg, weighting)
for stomach in self.mem:
temp = stomach.get()
if temp < 0:
stomach.set(abs(temp) * remainder)
else:
stomach.set(temp * base)
return None
################################################################################
def parse(string):
index = 0
code = []
ins = string[index:index+3]
while len(ins) == 3:
if ins in INS:
code.append(INS.index(ins))
index += 3
else:
index += 1
ins = string[index:index+3]
return tuple(code)
DECODE = ['END', 'P--', 'P++', 'EXE', 'I/O', 'M--',
'M++', 'LOP', 'M=0', 'REG', 'OUT', 'INP',
'S--', 'S++', 'AP-', 'AP+',
'AM-', 'AM+', 'A=0', 'WIZ']
def decode(code):
for ins in code:
print INS[ins] + '\t' + DECODE[ins]
print
def engine(code):
global REG
REG = None
mem = DDX()
cod = COD(code)
ins = cod.get()
while True:
ins = run(mem, cod, ins)
def run(mem, cod, ins):
global REG
# INS - 0 - moo
if ins == 0:
cod.dec()
cod.dec()
# INIT
level = 1
temp = cod.get()
if temp == HLP['moo']:
level += 1
elif temp == HLP['MOO']:
level -= 1
while level:
# LOOP
cod.dec()
temp = cod.get()
if temp == HLP['moo']:
level += 1
elif temp == HLP['MOO']:
level -= 1
return HLP['MOO']
# INS - 1 - mOo
elif ins == 1:
mem.dec()
cod.inc()
return cod.get()
# INS - 2 - moO
elif ins == 2:
mem.inc()
cod.inc()
return cod.get()
# INS - 3 - mOO
elif ins == 3:
temp = mem.get()
assert temp != 3
if 0 <= temp < len(INS):
return run(mem, cod, temp)
else:
raise SystemExit
# INS - 4 - Moo
elif ins == 4:
temp = mem.get()
if temp:
sys.stdout.write(chr(temp & 0x7F))
else:
char = get_char()
mem.set(ord(char) & 0x7F)
cod.inc()
return cod.get()
# INS - 5 - MOo
elif ins == 5:
mem.set(mem.get() - 1)
cod.inc()
return cod.get()
# INS - 6 - MoO
elif ins == 6:
mem.set(mem.get() + 1)
cod.inc()
return cod.get()
# INS - 7 - MOO
elif ins == 7:
temp = mem.get()
if temp:
cod.inc()
return cod.get()
else:
cod.inc()
cod.inc()
# INIT
level = 1
temp = cod.get()
if temp == HLP['moo']:
level -= 1
elif temp == HLP['MOO']:
level += 1
while level:
# LOOP
cod.inc()
temp = cod.get()
if temp == HLP['moo']:
level -= 1
elif temp == HLP['MOO']:
level += 1
cod.inc()
return cod.get()
# INS - 8 - OOO
elif ins == 8:
mem.set(0)
cod.inc()
return cod.get()
# INS - 9 - MMM
elif ins == 9:
if REG is None:
REG = mem.get()
else:
mem.set(REG)
REG = None
cod.inc()
return cod.get()
# INS - 10 - OOM
elif ins == 10:
sys.stdout.write(str(mem.get()) + '\n')
cod.inc()
return cod.get()
# INS - 11 - oom
elif ins == 11:
mem.set(get_int())
cod.inc()
return cod.get()
# INS - 12 - MMm
elif ins == 12:
mem.ddx_prv()
cod.inc()
return cod.get()
# INS - 13 - MmM
elif ins == 13:
mem.ddx_nxt()
cod.inc()
return cod.get()
# INS - 14 - Oom
elif ins == 14:
mem.ddx_dec()
cod.inc()
return cod.get()
# INS - 15 - oOm
elif ins == 15:
mem.ddx_inc()
cod.inc()
return cod.get()
# INS - 16 - OoM
elif ins == 16:
mem.ddx_sub()
cod.inc()
return cod.get()
# INS - 17 - oOM
elif ins == 17:
mem.ddx_add()
cod.inc()
return cod.get()
# INS - 18 - ooo
elif ins == 18:
mem.ddx_nul()
cod.inc()
return cod.get()
# INS - 19 - mmm
elif ins == 19:
REG = mem.ddx_reg(REG)
cod.inc()
return cod.get()
# ERROR
else:
raise Exception
def get_char():
while msvcrt.kbhit():
msvcrt.getch()
func = False
char = msvcrt.getch()
if char in ('\x00', '\xE0'):
func = True
while func:
msvcrt.getch()
func = False
char = msvcrt.getch()
if char in ('\x00', '\xE0'):
func = True
return char.replace('\r', '\n')
def get_int():
while msvcrt.kbhit():
msvcrt.getch()
buff = ''
char = msvcrt.getch()
while char != '\r' or not buff:
if '0' <= char <= '9':
sys.stdout.write(char)
buff += char
char = msvcrt.getch()
sys.stdout.write('\n')
return int(buff)
################################################################################
def main():
path = raw_input('Run File: ') + '.cow'
code = parse(file(path).read())
decode(code)
engine(code)
################################################################################
if __name__ == '__main__':
try:
main()
except SystemExit:
raw_input()
except:
import traceback
raw_input(traceback.format_exc())