Mercurial > repo
comparison 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 |
comparison
equal
deleted
inserted
replaced
995:6883f5911eb7 | 996:859f9b4339e6 |
---|---|
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() |