Skip to content

Commit 597aca5

Browse files
author
Alex
committed
Initial commit
1 parent 4e9e8ce commit 597aca5

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

bf.py

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Python Brainfuck interpreter.
6+
"""
7+
8+
from __future__ import with_statement
9+
from sys import argv, stdin, stdout
10+
11+
# Cells and pointer
12+
IND = 0
13+
CELLS = []
14+
15+
16+
def every_char_from(flow):
17+
"""Yields every char from flow.
18+
"""
19+
for row in flow:
20+
for char in row:
21+
yield char
22+
23+
24+
def get_char():
25+
"""Quick and dirty getchar implementation.
26+
"""
27+
try:
28+
return raw_input()[0]
29+
except EOFError:
30+
return '0'
31+
32+
33+
def init():
34+
"""We have lazy cell creation with this.
35+
"""
36+
global CELLS, IND
37+
38+
if len(CELLS) - 1 < IND:
39+
CELLS.append(0)
40+
41+
42+
def nested(chars):
43+
"""Looking for the next same-level ']'.
44+
"""
45+
i = 0
46+
47+
while chars[0:i+1].count("[") != chars[0:i+1].count("]"):
48+
i += 1
49+
50+
return chars[1:i]
51+
52+
53+
54+
def run(chars):
55+
"""Run a sequence of chars.
56+
"""
57+
global CELLS, IND
58+
59+
init()
60+
position = 0
61+
62+
while position < len(chars):
63+
char = chars[position]
64+
65+
if char == '>':
66+
IND += 1
67+
init() # if it is a not-yet-visited cell, we put a 0
68+
69+
elif char == '<':
70+
if IND: # IND is always >= 0
71+
IND -= 1
72+
73+
elif char == '+':
74+
CELLS[IND] += 1
75+
76+
elif char == '-':
77+
if CELLS[IND]: # values are >= 0
78+
CELLS[IND] -= 1
79+
80+
elif char == '.':
81+
stdout.write(chr(CELLS[IND] % 256))
82+
83+
elif char == ',':
84+
CELLS[IND] = ord(get_char())
85+
86+
elif char == '[':
87+
nest = nested(chars[position:])
88+
89+
while CELLS[IND]:
90+
run(nest)
91+
92+
position += len(nest) + 1
93+
94+
position += 1
95+
96+
97+
if __name__ == '__main__':
98+
99+
if not stdin.isatty():
100+
run(list(every_char_from(stdin)))
101+
102+
elif len(argv) > 1:
103+
with open(argv[1]) as f:
104+
run(list(every_char_from(f)))
105+
106+
else:
107+
print 'Usage: %s file' % argv[0]
108+
print 'Usage: cat file | %s' % argv[0]
109+

hello.bf

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
+++++ +++++ initialize counter (cell #0) to 10
2+
[ use loop to set the next four cells to 70/100/30/10
3+
> +++++ ++ add 7 to cell #1
4+
> +++++ +++++ add 10 to cell #2
5+
> +++ add 3 to cell #3
6+
> + add 1 to cell #4
7+
<<<< - decrement counter (cell #0)
8+
]
9+
> ++ . print 'H'
10+
> + . print 'e'
11+
+++++ ++ . print 'l'
12+
. print 'l'
13+
+++ . print 'o'
14+
> ++ . print ' '
15+
<< +++++ +++++ +++++ . print 'W'
16+
> . print 'o'
17+
+++ . print 'r'
18+
----- - . print 'l'
19+
----- --- . print 'd'
20+
> + . print '!'
21+
> . print '\n'

0 commit comments

Comments
 (0)