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()