996
|
1 #!/usr/bin/env python
|
|
2 import sys
|
|
3 global OPS,MEMORY,PC, MC
|
|
4 OPS = []
|
|
5 PC = 0
|
|
6 MC = 0
|
|
7 MEMORY = [0]
|
|
8 class OpRing:
|
|
9 def __init__(self):
|
|
10 self.currentop = 0
|
|
11 self.opring = ["NOOP","EXIT","ONE","ZERO","LOAD","STORE","PADD","DADD","LOGIC","IF","INTIO","ASCIO"]
|
|
12 self.val = 0
|
|
13 self.direction = 0
|
|
14 pass
|
|
15 def ROTATE(s):
|
|
16 if s.direction == 0:
|
|
17 s.currentop = (s.currentop + 1) % 12
|
|
18 elif s.direction == 1:
|
|
19 s.currentop = (s.currentop -1) % 12
|
|
20 else:
|
|
21 print "Error in ROTATE. self.direction not 0/1."
|
|
22 def FLIP(s):
|
|
23 s.direction = s.direction ^ 1
|
|
24 return s.direction
|
|
25 def EXEC(self):
|
|
26 global MEMORY,MC,PC,OPS
|
|
27 t = self.opring[self.currentop]
|
|
28
|
|
29 if t == "NOOP":
|
|
30 pass
|
|
31
|
|
32 elif t == "EXIT":
|
|
33 return "EXIT"
|
|
34
|
|
35 elif t == "ONE":
|
|
36 self.val = 1
|
|
37
|
|
38 elif t == "ZERO":
|
|
39 self.val = 0
|
|
40
|
|
41 elif t == "LOAD":
|
|
42 self.val = MEMORY[MC]
|
|
43
|
|
44 elif t == "STORE":
|
|
45 MEMORY[MC] = self.val
|
|
46
|
|
47 elif t == "PADD":
|
|
48 PC += self.val - 1
|
|
49 if PC < -1:
|
|
50 PC = -1
|
|
51 elif len(OPS) < PC:
|
|
52 return "EXIT"
|
|
53
|
|
54
|
|
55 elif t == "DADD":
|
|
56 MC += self.val
|
|
57 if MC < 0:
|
|
58 MC = 0
|
|
59 while len(MEMORY) <= MC:
|
|
60 MEMORY.append(0)
|
|
61
|
|
62 elif t == "LOGIC":
|
|
63 if MEMORY[MC] == 0:
|
|
64 self.val = 0
|
|
65 else:
|
|
66 self.val = (self.val and 1)
|
|
67
|
|
68 elif t == "IF":
|
|
69 if MEMORY[MC] != 0:
|
|
70 PC += (self.val-1)
|
|
71 if PC < -1:
|
|
72 PC = -1
|
|
73 elif len(OPS) < PC:
|
|
74 return "EXIT"
|
|
75
|
|
76 elif t == "INTIO":
|
|
77 if self.val == 0:
|
|
78 MEMORY[MC] = int(raw_input("Please enter an integer: "))
|
|
79 else:
|
|
80 return MEMORY[MC]
|
|
81 elif t == "ASCIO":
|
|
82 if self.val == 0:
|
|
83 MEMORY[MC] = raw_input("Please enter a character: ")[0]
|
|
84 else:
|
|
85 try:
|
|
86 return chr(MEMORY[MC])
|
|
87 except TypeError:
|
|
88 return MEMORY[MC]
|
|
89 def GETCURRENTOP(self):
|
|
90 return self.opring[self.currentop]
|
|
91
|
|
92 class MathRing:
|
|
93 global MEMORY,PC, MC
|
|
94 def __init__(self):
|
|
95 self.opring = ["NOOP","LOAD","STORE","ADD","MULT","DIV","ZERO","<",">","=","NOT","NEG"]
|
|
96 self.val = 0
|
|
97 self.currentop = 0
|
|
98 self.direction = 0
|
|
99 def ROTATE(s):
|
|
100 if s.direction == 0:
|
|
101 s.currentop = (s.currentop + 1) % 12
|
|
102 elif s.direction == 1:
|
|
103 s.currentop = (s.currentop -1) % 12
|
|
104 else:
|
|
105 print "Error in ROTATE. self.direction not 0/1."
|
|
106 def FLIP(s):
|
|
107 s.direction = s.direction ^ 1
|
|
108 return s.direction
|
|
109 def EXEC(self):
|
|
110 t = self.opring[self.currentop]
|
|
111
|
|
112 if t == "NOOP":
|
|
113 pass
|
|
114
|
|
115 elif t == "LOAD":
|
|
116 self.val = MEMORY[MC]
|
|
117
|
|
118 elif t == "STORE":
|
|
119 MEMORY[MC] = self.val
|
|
120
|
|
121 elif t == "ADD":
|
|
122 self.val += MEMORY[MC]
|
|
123
|
|
124 elif t == "MULT":
|
|
125 self.val *= MEMORY[MC]
|
|
126
|
|
127 elif t == "DIV":
|
|
128 if MEMORY[MC] != 0:
|
|
129 self.val /= MEMORY[MC]
|
|
130 else:
|
|
131 print "Attempted to divide by zero. Value in Math Ring unchanged."
|
|
132
|
|
133 elif t == "ZERO":
|
|
134 self.val = 0
|
|
135
|
|
136 elif t == "<":
|
|
137 self.val = (self.val < MEMORY[MC])
|
|
138
|
|
139 elif t == ">":
|
|
140 self.val = (self.val > MEMORY[MC])
|
|
141
|
|
142 elif t == "=":
|
|
143 self.val = (self.val == MEMORY[MC])
|
|
144
|
|
145 elif t == "NOT":
|
|
146 self.val = (self.val == 0)
|
|
147
|
|
148 elif t == "NEG":
|
|
149 self.val *= -1
|
|
150
|
|
151 def main():
|
|
152 global OPS,MEMORY,PC, MC
|
|
153
|
|
154 opring = OpRing()
|
|
155 mathring = MathRing()
|
|
156 rings = {"OPRING":opring,"MATHRING":mathring}
|
|
157 if len(sys.argv) < 2:
|
|
158 print "Must specify a filename as the argument. eg: python whirlinterp.py filename.txt"
|
|
159 raise SystemExit
|
|
160 filename = sys.argv[1]
|
|
161 f = file(filename,'r')
|
|
162 text = f.readlines()
|
|
163 f.close()
|
|
164 for line in text:
|
|
165 for char in line:
|
|
166 if char in ['0','1']:
|
|
167 OPS.append(char)
|
|
168 previousop = 3
|
|
169 current = "OPRING"
|
|
170 outputtext = ""
|
|
171 while PC < len(OPS):
|
|
172 if OPS[PC] == "0":
|
|
173 rings[current].FLIP()
|
|
174 if previousop == 0:
|
|
175 text = rings[current].EXEC()
|
|
176 if text == "EXIT":
|
|
177 print outputtext
|
|
178 raise SystemExit
|
|
179 elif text != None:
|
|
180 try:
|
|
181 sys.stdout.write(text)
|
|
182 except TypeError:
|
|
183 sys.stdout.write(str(text))
|
|
184
|
|
185 if current == "OPRING":
|
|
186 current = "MATHRING"
|
|
187 elif current == "MATHRING":
|
|
188 current = "OPRING"
|
|
189
|
|
190 previousop = 1
|
|
191 else:
|
|
192 previousop = 0
|
|
193
|
|
194 elif OPS[PC] == "1":
|
|
195 rings[current].ROTATE()
|
|
196 previousop = 1
|
|
197 PC += 1
|
|
198 print outputtext
|
|
199
|
|
200 if __name__ == "__main__":
|
|
201 main()
|