-
Notifications
You must be signed in to change notification settings - Fork 1
/
interpreter.py
121 lines (119 loc) · 3.57 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from Stack import Stack
from random import randint
class Interpreter(object):
def __init__(self,source,input,startx=None,starty=None,dir=None):
source = source.strip().split("\n")
dim = max(map(len,source)+[len(source)])
self.source = [list(x.ljust(dim,"."))for x in source]
self.dim = (len(self.source),len(self.source[0]))
if dir == None:
self.direction = [[1,0],[0,1],[-1,0],[0,-1]][randint(0,3)]
else:
self.direction = dir
if (startx,starty) == (None,None):
self.location = [randint(0,self.dim[0]-1),randint(0,self.dim[1]-1)]
else:
self.location = [startx,starty]
self.memory = Stack(input)
self.scope = Stack()
self.read = False
self.safety = False
def wrapAround(self):
self.location[0] %= self.dim[0]
self.location[1] %= self.dim[1]
def move(self):
self.location = [
self.location[0]+self.direction[0],
self.location[1]+self.direction[1]
]
#Important bit
if self.location[0] < 0:
self.wrapAround()
if self.location[1] < 0:
self.wrapAround()
if self.location[0] >= self.dim[0]:
self.wrapAround()
if self.location[1] >= self.dim[1]:
self.wrapAround()
def character(self):
return self.source[self.location[0]][self.location[1]]
def action(self):
if self.read:
if self.character() == '"':
self.read = False
else:
self.memory.append(ord(self.character()))
elif self.character() == "/":
self.direction = map(lambda x:-x,self.direction[::-1])
elif self.character() == "\\":
self.direction = self.direction[::-1]
elif self.character() == "|":
self.direction[1] *= -1
elif self.character() == ">":
self.direction = [0,1]
elif self.character() == "<":
self.direction = [0,-1]
elif self.character() == "v":
self.direction = [1,0]
elif self.character() == "^":
self.direction = [-1,0]
elif self.character() == "%":
self.safety = True
elif self.character() == "#":
self.safety = False
elif self.character() == "@":
if self.safety:
self.direction = [0,0]
elif self.character() == "[":
if self.direction[1] == 1:
self.direction[1] = -1
if self.direction[1]:
self.source[self.location[0]][self.location[1]] = "]"
elif self.character() == "]":
if self.direction[1] == -1:
self.direction[1] = 1
if self.direction[1]:
self.source[self.location[0]][self.location[1]] = "["
elif self.character() in "0123456879":
self.memory.append(int(self.character()))
elif self.character() == "+":
self.memory.append(self.memory.pop()+self.memory.pop())
elif self.character() == "*":
self.memory.append(self.memory.pop()*self.memory.pop())
elif self.character() == "-":
self.memory.append(-self.memory.pop())
elif self.character() == ":":
self.memory.append(self.memory[-1])
elif self.character() == "$":
a,b=self.memory.pop(),self.memory.pop()
self.memory.append(a)
self.memory.append(b)
elif self.character() == "!":
self.move()
elif self.character() == "?":
if self.memory.pop():
self.move()
elif self.character() == "(":
self.scope.append(self.memory.pop())
elif self.character() == ")":
self.memory.append(self.scope.pop())
elif self.character() == '"':
self.read = True
def output(self,screen,a,b):
try:
import curses
curselib = curses
except ImportError:
import unicurses
curselib = unicurses
for x in range(self.dim[0]):
for y in range(self.dim[1]):
try:
if [x,y] == self.location:
if curselib.has_colors():
screen.addstr(a+x,b+y*2,"X",curselib.color_pair(1))
else:
screen.addstr(a+x,b+y*2,"X")
else:
screen.addstr(a+x,b+y*2,self.source[x][y])
except:pass