-
Notifications
You must be signed in to change notification settings - Fork 0
/
brainfuck.py
63 lines (50 loc) · 1.78 KB
/
brainfuck.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
import os
import sys
def usage():
print "%s script.b" % sys.argv[0]
sys.exit(127)
class Machine:
def __init__(self, filename):
self.filename = filename
self.code = []
self.codePos = 0
self.tape = []
self.tapePos = 0
try:
with open(filename, 'r') as fp:
self.code = [ ord(ch) for ch in fp.read() ]
except Exception as err:
print err
sys.exit(127)
def run(self, skip = False):
while self.tapePos >= 0 and self.codePos < len(self.code):
if self.tapePos >= len(self.tape):
self.tape.append(0)
if self.code[self.codePos] == ord('['):
self.codePos += 1
oldPos = self.codePos
while self.run(self.tape[self.tapePos] == 0):
self.codePos = oldPos
elif self.code[self.codePos] == ord(']'):
return self.tape[self.tapePos] != 0
elif not skip:
ch = self.code[self.codePos]
if ch == ord('+'):
if self.tape[self.tapePos] < 255:
self.tape[self.tapePos] += 1
elif ch == ord('-'):
if self.tape[self.tapePos] < 255:
self.tape[self.tapePos] -= 1
elif ch == ord('>'): self.tapePos += 1
elif ch == ord('<'): self.tapePos -= 1
elif ch == ord('.'): os.write(2, chr(self.tape[self.tapePos]))
elif ch == ord(','): self.tape[self.tapePos] = ord(os.read(0, 1))
self.codePos += 1
return True
if __name__ == '__main__':
args = sys.argv[1:]
if len(args) < 1:
usage()
filename = args[0]
m = Machine(filename)
m.run()