-
Notifications
You must be signed in to change notification settings - Fork 0
/
brainfsck.py
114 lines (103 loc) · 4.03 KB
/
brainfsck.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
import sys, time
MEM_ARRAY_SIZE = 16
MEM_BITS = 16
VERBOSE = True
PRINT_CHAR = True
def print_code(in_str, codeptr, dataptr, mem, iters):
print(in_str)
print(" " * codeptr + "^")
print("{} {}: {} ({} iters)".format(codeptr, dataptr, mem, iters))
def main(in_str):
mem = [0] * MEM_ARRAY_SIZE
codeptr = 0
dataptr = 0
levelarray = []
iters = 0
bits_mod = 1 << MEM_BITS
while codeptr < len(in_str):
iters += 1
if in_str[codeptr] == ">":
# Mod allows for circular memory buffer
dataptr = (dataptr + 1) % MEM_ARRAY_SIZE
elif in_str[codeptr] == "<":
dataptr = (dataptr - 1) % MEM_ARRAY_SIZE
elif in_str[codeptr] == "+":
mem[dataptr] = (mem[dataptr] + 1) % bits_mod
elif in_str[codeptr] == "-":
mem[dataptr] = (mem[dataptr] - 1) % bits_mod
elif in_str[codeptr] == ".":
if PRINT_CHAR:
print(chr(mem[dataptr]))
else:
print(str(mem[dataptr]))
elif in_str[codeptr] == ",":
req = None
print("\nGive me one byte of input, use quotes for a char: ")
while (req == None):
req = input()
try:
req = int(req) & 0xFF
except ValueError:
try:
if req[0] == '"' or "'":
req = ord(req[1])
else:
print("Invalid input")
req = None
except IndexError:
print("Invalid input")
req = None
mem[dataptr] = req
elif in_str[codeptr] == "[":
# If data at pointer is 0, jump to matching ]
if mem[dataptr] == 0:
err_ptr = codeptr
i = 0
# Use -1 because of oddness in code
while i > -1:
codeptr += 1
# If the open bracket doesn't have a matching ending bracket, error out
if codeptr >= len(in_str):
print("\nEOL reached when scanning for ending bracket; unmatched [ at {}".format(err_ptr))
codeptr = err_ptr
print_code(in_str, codeptr, dataptr, mem, iters)
return
if in_str[codeptr] == "[":
# Keep track of "level" you're on, to make sure that ] is the proper matching bracket
i += 1
elif in_str[codeptr] == "]":
i -= 1
# Else, move to next command. Save location of this [
else:
levelarray.append(codeptr)
elif in_str[codeptr] == "]":
# If data at pointer is 0, move to next command
if mem[dataptr] == 0:
# Remove the pointer position of the matching [
levelarray.pop()
# Else, jump back to matching [
else:
if len(levelarray) == 0:
print("\nFound a ] without a matching [ at {0}".format(codeptr))
print_code(in_str, codeptr, dataptr, mem, iters)
return
codeptr = levelarray[-1]
if VERBOSE:
# print("")
print_code(in_str, codeptr, dataptr, mem, iters)
time.sleep(0.01)
codeptr += 1
# print("\n\n{}: {} ({} iters)".format(dataptr, mem, iters))
if __name__ == "__main__":
# in_str = "Addition ,>,[-<+>]<."
# in_str = "Multiplication ,>,<[>[>+>+<<-]>[<+>-]<<-]>>>."
in_str = "Factorial ,[->+>+<<]>>->>+<<<[>[<[->[-<<+>>>+<]>[-<+>]<<]<[->+<]>>-]<.>>>-]>>>[.-]"
# in_str = "++++[.-]"
# in_str = open('99_bottles_of_beer.brainfuck').read()
##in_str = ""
##i = raw_input("Input brainfsck code now, type 'run' to end: ")
##while(i != "run"):
## in_str += i
## i = raw_input()
##in_str = in_str.replace('\n','')
main(in_str)