-
Notifications
You must be signed in to change notification settings - Fork 11
/
Interpreter.py
78 lines (60 loc) · 2.42 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
#!/usr/bin/env python3
import sys
import argparse
def create_jumps_dictionary(program):
lbraces = list()
res = dict()
for index, command in enumerate(program):
if command == '[':
lbraces.append(index)
elif command == ']':
if len(lbraces) == 0:
raise SyntaxError("Brainfuck: mismatched parentheses (at index: %s)" % index)
lbrace_index = lbraces.pop()
res[lbrace_index] = index
res[index] = lbrace_index
if len(lbraces) > 0:
raise SyntaxError("Brainfuck: mismatched parentheses (at indexes: %s)" % str(lbraces))
return res
def brainfuck(program, bits=8):
jumps = create_jumps_dictionary(program)
data = dict()
data_pointer = 0
instruction_pointer = 0
while instruction_pointer < len(program):
command = program[instruction_pointer]
if command == '>':
data_pointer += 1
elif command == '<':
data_pointer -= 1
elif command == '+':
data[data_pointer] = (data.get(data_pointer, 0) + 1)
if data[data_pointer] == 2 ** bits:
data[data_pointer] = 0
elif command == '-':
data[data_pointer] = (data.get(data_pointer, 0) - 1)
if data[data_pointer] == -1:
data[data_pointer] = 2 ** bits - 1
elif command == ',':
data[data_pointer] = ord(sys.stdin.read(1)) % 256
elif command == '.':
print(chr(data.get(data_pointer, 0)), end='', flush=True)
elif command == '[':
if data.get(data_pointer, 0) == 0:
instruction_pointer = jumps[instruction_pointer]
elif command == ']':
if data.get(data_pointer, 0) != 0:
instruction_pointer = jumps[instruction_pointer]
else: # everything else is comment
pass
instruction_pointer += 1
if data_pointer != 0:
print("WARNING (interpreter) - at the end of the execution the data pointer is %s instead of 0 (possibly a compiler issue)" % str(data_pointer))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("filepath")
parser.add_argument("--bits", "-b", "--interpreter-bits", type=int, default=8, help="Amount of bits each cell uses")
args = parser.parse_args()
with open(args.filepath, 'r') as f:
code = f.read()
brainfuck(code, args.bits)