-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathbrain_fuck.py
102 lines (83 loc) · 4.25 KB
/
brain_fuck.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
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import tensorflow as tf
from stack import push, pop, assign
from ascii import ascii2char
class BrainFuck():
def __init__(self, src, tape_length=100):
self.tokens = tf.constant(list(src), dtype=tf.string)
self.length = len(list(src))
p0 = tf.constant(0, dtype=tf.int32)
j0 = tf.constant(np.zeros(self.length, dtype=np.int32))
p0 = tf.constant(0, dtype=tf.int32)
s0 = tf.constant(np.zeros(self.length), dtype=tf.int32)
_, _, _, jumps = tf.while_loop(self.cond_jumps, self.body_jumps, [p0, s0, p0, j0], back_prop=False)
self.tape = tf.Variable(tf.zeros(tape_length, dtype=tf.int32))
c0 = tf.constant(0, dtype=tf.int32)
o0 = tf.constant('', dtype=tf.string)
self.graph = tf.while_loop(self.cond, self.body, [p0, self.tape, c0, jumps, o0], back_prop=False)
def run(self):
with tf.Session() as sess:
tf.global_variables_initializer().run()
return sess.run(self.graph)
def cond_jumps(self, pc, s, p, j):
return tf.less(pc, tf.size(self.tokens))
def body_jumps(self, pc, s, p, j):
token = self.tokens[pc]
inc_pc = tf.add(pc, 1)
def brackets_begin(i):
_s, _p = push(s, p, i, length=self.length)
return (inc_pc, _s, _p, j)
def brackets_end(i):
_s, _p, from_ = pop(s, p, length=self.length)
to_ = i
j1, _, _ = assign(j, from_+1, to_, length=self.length)
j2, _, _ = assign(j1, to_+1, from_, length=self.length)
return (inc_pc, _s, _p, j2)
return tf.cond(tf.equal(token, '['),
lambda: (brackets_begin(pc)),
lambda: tf.cond(tf.equal(token, ']'),
lambda: (brackets_end(pc)),
lambda: (inc_pc, s, p, j)))
def cond(self, pc, tape, cur, jumps, output):
return tf.less(pc, tf.size(self.tokens))
def body(self, pc, tape, cur, jumps, output):
token = self.tokens[pc]
inc_pc = tf.add(pc, 1)
def stdin(c):
#return tf.assign(self.tape[c], input(''))
return self.tape
return tf.cond(tf.equal(token, '+'),
lambda: (inc_pc, tf.assign(self.tape[cur], self.tape[cur]+1), cur, jumps, output),
lambda: tf.cond(tf.equal(token, '-'),
lambda: (inc_pc, tf.assign(self.tape[cur], self.tape[cur]-1), cur, jumps, output),
lambda: tf.cond(tf.equal(token, '>'),
lambda: (inc_pc, tape, tf.add(cur, 1), jumps, output),
lambda: tf.cond(tf.equal(token, '<'),
lambda: (inc_pc, tape, tf.subtract(cur, 1), jumps, output),
lambda: tf.cond(tf.equal(token, '.'),
lambda: (inc_pc, tape, cur, jumps, tf.string_join([output, ascii2char(tape[cur])])),
lambda: tf.cond(tf.equal(token, ','),
lambda: (inc_pc, stdin(cur), cur, jumps, output),
lambda: tf.cond(tf.equal(token, '['),
lambda: tf.cond(tf.equal(self.tape[cur], 0),
lambda: (jumps[pc], tape, cur, jumps, output),
lambda: (inc_pc, tape, cur, jumps, output)),
lambda: tf.cond(tf.equal(token, ']'),
lambda: tf.cond(tf.not_equal(self.tape[cur], 0),
lambda: (jumps[pc], tape, cur, jumps, output),
lambda: (inc_pc, tape, cur, jumps, output)),
lambda: (inc_pc, tape, cur, jumps, output) ))))))))
if __name__ == '__main__':
src_A = '++++++[> ++++++++++ < -]> +++++.'
pc, tape, cur, jumps, output = BrainFuck(src_A).run()
print(output) #=> A
src_helloworld ='''
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
'''
pc, tape, cur, jumps, output = BrainFuck(src_helloworld).run()
print(output) #=> Hello, world!