-
Notifications
You must be signed in to change notification settings - Fork 1
/
Interpreter.py
60 lines (58 loc) · 1.77 KB
/
Interpreter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from Stack import Stack
class Interpreter(object):
def __init__(self,source,output,*args):
self.stack = Stack(args)
self.source = source
self.scope = []
self.pointer = 0
self.output = output
def step(self):
if self.pointer >= len(self.source):return False
command = self.source[self.pointer]
if command == "[":
if self.stack[-1]:
self.scope.append(self.pointer)
else:
#If the TOS is zero jump to the next ]
tempScope = 1
while tempScope and (self.pointer < len(self.source)):
self.pointer += 1
if self.source[self.pointer] == "]":
tempScope -= 1
elif self.source[self.pointer] == "[":
tempScope += 1
elif command == "]":
if self.stack[-1]:
self.pointer = self.scope[-1]
else:
self.scope.pop()
elif command == "&":
self.stack.append(self.stack.pop()&self.stack.pop())
elif command == "|":
self.stack.append(self.stack.pop()|self.stack.pop())
elif command == "^":
self.stack.append(self.stack.pop()^self.stack.pop())
elif command == "~":
self.stack.append(~self.stack.pop())
elif command == "-":
self.stack.append(-self.stack.pop())
elif command == "<":
self.stack.append(self.stack.pop()<<1)
elif command == ">":
self.stack.append(self.stack.pop()>>1)
elif command == ":":
if self.stack:
self.stack.append(self.stack[-1])
else:
self.stack = [0]
elif command == "?":
if self.stack:
self.stack = Stack([self.stack.pop()] + self.stack)
elif command == "!":
if self.stack:
self.stack = Stack(self.stack[1:] + [self.stack[0]])
self.pointer += 1
return True
def __str__(self):
functions = {"i":str,"b":lambda x:"-"+bin(x)[3:] if x<0 else bin(x)[2:],"a":lambda x:chr(x%256)}
return (""if self.output=="a" else" ").join(map(functions[self.output],self.stack))