-
Notifications
You must be signed in to change notification settings - Fork 0
/
brainfuck.py
117 lines (106 loc) · 3.3 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
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
import textwrap
import sys
class Program:
def __init__(self):
self.buffer = []
self.index = 0
self.waitfor = 'main'
self.append("new-session -d 'read && tmux wait-for -S %s'" % self.waitfor)
self.append("set -s focus-events on")
self.append('set -s @input "$INPUT"')
def next_window_index(self):
self.index += 1
return self.index
def to_string(self):
return '\n'.join(self.buffer)
def new_window(self, body, index = None):
index = index or self.next_window_index()
target = ':{end}'
colour = 16 + (index % (231 - 16))
return textwrap.dedent("""\
# instruction number %s
new-window -a -t '%s' 'tmux wait-for %s'
set -w -t '%s' window-style bg=colour%s
set-hook -t '%s' pane-focus-in {\
""" % (index, target, self.waitfor, target, colour, target) + body) + '}\n'
def append(self, text):
self.buffer.append(textwrap.dedent(text))
def move_right(self):
self.append(self.new_window("""
run 'tmux rename-session -- "#{e|+:#S,1}"'
run 'tmux next-window'
"""))
def move_left(self):
self.append(self.new_window("""
run 'tmux rename-session -- "#{e|-:#S,1}"'
run 'tmux next-window'
"""))
def inc(self):
self.append(self.new_window("""
run 'tmux set -s "@data-#S" "#{e|%:#{e|+:#{E:##{@data-#S#}},1},256}"'
run 'tmux next-window'
"""))
def dec(self):
self.append(self.new_window("""
run 'tmux set -s "@data-#S" "#{e|%:#{e|+:#{E:##{@data-#S#}},255},256}"'
run 'tmux next-window'
"""))
def read(self):
self.append(self.new_window("""
run 'tmux set -s "@data-#S" "#{=1:@input}"'
run 'tmux set -s "@input" "#{=-#{e|-:#{n:@input},1}:#{?#{e|==:#{n:@input},1},0,#{@input}}}"'
run 'tmux next-window'
"""))
def write(self):
self.append(self.new_window("""
run 'tmux send-keys -t ":=0" "#{a:#{e|+:0,#{E:##{@data-#S#}}}}"'
run 'tmux set -s "@output" "#{@output}#{a:#{e|+:0,#{E:##{@data-#S#}}}}"'
run 'tmux next-window'
"""))
def jump(self, position, foreward):
if foreward:
nz, z = self.index + 2, position + 1
else:
nz, z = position, self.index + 2
self.append(self.new_window("""
run 'tmux select-window -t ":=#{?#{E:##{@data-#S#}},%s,%s}"'
""" % (nz, z)))
def compile(program):
output = Program()
stack = []
pairs = dict()
for i, char in enumerate(program):
if char == '[':
stack.append(i)
elif char == ']':
o = stack.pop()
pairs[o] = i + 1
pairs[i] = o + 1
if len(stack) != 0:
raise Exception("mismatching brackets")
for i, char in enumerate(program):
if char == '+':
output.inc()
elif char == '-':
output.dec()
elif char == '>':
output.move_right()
elif char == '<':
output.move_left()
elif char == '.':
output.write()
elif char == ',':
output.read()
elif char == '[':
# TODO: this won't work if there are other characters in the input
output.jump(pairs[i], True)
elif char == ']':
output.jump(pairs[i], False)
output.append('select-window -t :=0')
return output.to_string()
with open(sys.argv[1]) as f:
program = f.read()
comp = compile(program)
print(comp)
with open(sys.argv[2], 'wt') as o:
o.write(comp)