Mercurial > repo
diff interps/whirl/whirlinterp.py @ 996:859f9b4339e6
<Gregor> tar xf egobot.tar.xz
author | HackBot |
---|---|
date | Sun, 09 Dec 2012 19:30:08 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interps/whirl/whirlinterp.py Sun Dec 09 19:30:08 2012 +0000 @@ -0,0 +1,201 @@ +#!/usr/bin/env python +import sys +global OPS,MEMORY,PC, MC +OPS = [] +PC = 0 +MC = 0 +MEMORY = [0] +class OpRing: + def __init__(self): + self.currentop = 0 + self.opring = ["NOOP","EXIT","ONE","ZERO","LOAD","STORE","PADD","DADD","LOGIC","IF","INTIO","ASCIO"] + self.val = 0 + self.direction = 0 + pass + def ROTATE(s): + if s.direction == 0: + s.currentop = (s.currentop + 1) % 12 + elif s.direction == 1: + s.currentop = (s.currentop -1) % 12 + else: + print "Error in ROTATE. self.direction not 0/1." + def FLIP(s): + s.direction = s.direction ^ 1 + return s.direction + def EXEC(self): + global MEMORY,MC,PC,OPS + t = self.opring[self.currentop] + + if t == "NOOP": + pass + + elif t == "EXIT": + return "EXIT" + + elif t == "ONE": + self.val = 1 + + elif t == "ZERO": + self.val = 0 + + elif t == "LOAD": + self.val = MEMORY[MC] + + elif t == "STORE": + MEMORY[MC] = self.val + + elif t == "PADD": + PC += self.val - 1 + if PC < -1: + PC = -1 + elif len(OPS) < PC: + return "EXIT" + + + elif t == "DADD": + MC += self.val + if MC < 0: + MC = 0 + while len(MEMORY) <= MC: + MEMORY.append(0) + + elif t == "LOGIC": + if MEMORY[MC] == 0: + self.val = 0 + else: + self.val = (self.val and 1) + + elif t == "IF": + if MEMORY[MC] != 0: + PC += (self.val-1) + if PC < -1: + PC = -1 + elif len(OPS) < PC: + return "EXIT" + + elif t == "INTIO": + if self.val == 0: + MEMORY[MC] = int(raw_input("Please enter an integer: ")) + else: + return MEMORY[MC] + elif t == "ASCIO": + if self.val == 0: + MEMORY[MC] = raw_input("Please enter a character: ")[0] + else: + try: + return chr(MEMORY[MC]) + except TypeError: + return MEMORY[MC] + def GETCURRENTOP(self): + return self.opring[self.currentop] + +class MathRing: + global MEMORY,PC, MC + def __init__(self): + self.opring = ["NOOP","LOAD","STORE","ADD","MULT","DIV","ZERO","<",">","=","NOT","NEG"] + self.val = 0 + self.currentop = 0 + self.direction = 0 + def ROTATE(s): + if s.direction == 0: + s.currentop = (s.currentop + 1) % 12 + elif s.direction == 1: + s.currentop = (s.currentop -1) % 12 + else: + print "Error in ROTATE. self.direction not 0/1." + def FLIP(s): + s.direction = s.direction ^ 1 + return s.direction + def EXEC(self): + t = self.opring[self.currentop] + + if t == "NOOP": + pass + + elif t == "LOAD": + self.val = MEMORY[MC] + + elif t == "STORE": + MEMORY[MC] = self.val + + elif t == "ADD": + self.val += MEMORY[MC] + + elif t == "MULT": + self.val *= MEMORY[MC] + + elif t == "DIV": + if MEMORY[MC] != 0: + self.val /= MEMORY[MC] + else: + print "Attempted to divide by zero. Value in Math Ring unchanged." + + elif t == "ZERO": + self.val = 0 + + elif t == "<": + self.val = (self.val < MEMORY[MC]) + + elif t == ">": + self.val = (self.val > MEMORY[MC]) + + elif t == "=": + self.val = (self.val == MEMORY[MC]) + + elif t == "NOT": + self.val = (self.val == 0) + + elif t == "NEG": + self.val *= -1 + +def main(): + global OPS,MEMORY,PC, MC + + opring = OpRing() + mathring = MathRing() + rings = {"OPRING":opring,"MATHRING":mathring} + if len(sys.argv) < 2: + print "Must specify a filename as the argument. eg: python whirlinterp.py filename.txt" + raise SystemExit + filename = sys.argv[1] + f = file(filename,'r') + text = f.readlines() + f.close() + for line in text: + for char in line: + if char in ['0','1']: + OPS.append(char) + previousop = 3 + current = "OPRING" + outputtext = "" + while PC < len(OPS): + if OPS[PC] == "0": + rings[current].FLIP() + if previousop == 0: + text = rings[current].EXEC() + if text == "EXIT": + print outputtext + raise SystemExit + elif text != None: + try: + sys.stdout.write(text) + except TypeError: + sys.stdout.write(str(text)) + + if current == "OPRING": + current = "MATHRING" + elif current == "MATHRING": + current = "OPRING" + + previousop = 1 + else: + previousop = 0 + + elif OPS[PC] == "1": + rings[current].ROTATE() + previousop = 1 + PC += 1 + print outputtext + +if __name__ == "__main__": + main()