Skip to content

Commit 719c168

Browse files
committed
stuff & python version
1 parent 7031034 commit 719c168

File tree

6 files changed

+172
-5
lines changed

6 files changed

+172
-5
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# WHAT IS BRAINFUCK?
22

3-
Brainfuck is an esoteric language, or joke language, that is turing-complete and it works with cells. Even though it isn't very useful, it's an interesting experience every passionate programmer should experience. The name comes because coding on it does feel you that.
3+
Brainfuck is an esoteric language, or joke language, that is turing-complete and it works with cells.
4+
Even though it isn't very useful, it's an interesting experience every passionate programmer should
5+
experience. The name comes because coding on it does feel you that.
46

57
# HOW DO I BRAINFUCK?
68

@@ -24,12 +26,17 @@ This version of brainfuck has only 10 instructions, and those are:
2426
] --> Goes to the last open bracket if it doesn't end on 0 / null.
2527
```
2628

27-
Every character other than those is(hopefully) ignored.
29+
Every character other than those is (hopefully) ignored.
2830

2931
# WHY?
3032

3133
Why i did it? Because I was bored. Why does this language exists in the first place? I guess someone felt the same way ~15 years before me.
3234

35+
# TODO
36+
[x] Make it to interpret brainfuck(only in the python version atm).
37+
[ ] Make it to COMPILE brainfuck.
38+
[ ] Add more stuff to the TODO.
39+
3340
# AUTHOR NOTE
3441

3542
Hope you enjoy playing with this, it's possible to do some impressive stuff.

main.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
'''
2+
Version en python del interpretador de brainfuck,
3+
para tener una idea general a la hora de portearlo
4+
a C.
5+
'''
6+
7+
# Libreria necesaria para los argumentos.
8+
from sys import *
9+
argc = len(argv)
10+
11+
# Comprueba que los argumentos sean correctos
12+
if argc < 2 or argc > 3:
13+
print(f"\n\nUsage: {argv[0]} [path/to/file.bf] [args]\n")
14+
exit(1)
15+
16+
17+
def loop(src, pos):
18+
endLoop = 0
19+
while 1:
20+
pos -= 1
21+
item = src[pos]
22+
if item == "]":
23+
endLoop += 1
24+
elif item == "[" and endLoop != 0:
25+
endLoop -= 1
26+
elif item == "[" and endLoop == 0:
27+
break
28+
return pos
29+
30+
# Busca errores, como bucles incompletos.
31+
def checkErrors(source):
32+
lpStat = clStat = err = 0
33+
for i in source:
34+
if i == "[":
35+
lpStat += 1
36+
elif i == "]":
37+
lpStat -= 1
38+
elif i == ">":
39+
clStat += 1
40+
elif i == "<":
41+
clStat -= 1
42+
if lpStat != 0:
43+
err += 1
44+
print("\n\t 001: UNFINISHED LOOP \n")
45+
if clStat < 0:
46+
err += 2
47+
print("\n\t 002: NEGATIVE CELL POSITION \n")
48+
49+
if err != 0:
50+
print(f"\nCode returned error {err}.")
51+
exit(err)
52+
53+
# Version en C de checkErrors():
54+
#
55+
# void checkErrors(char source[]){
56+
# int lpStatus, err;
57+
# for(int i; i=<strlen(source); i++){
58+
# if(source[i] == '['){
59+
# lpStatus++;
60+
# }else if(source[i] == ']'){
61+
# lpStatus--;
62+
# }
63+
# }
64+
# if(lpStatus != 0){
65+
# err+=1;
66+
# fputs("\n\t 001: UNFINISHED LOOP \n\n", stderr);
67+
# }
68+
# }
69+
70+
71+
# Calcula el numero necesario de celdas
72+
# para que el programa funcione correctamente
73+
# usando el minimo numero de recursos.
74+
def getCells(source):
75+
num = cells = 0
76+
for i in source:
77+
if i == ">":
78+
num += 1
79+
elif i == "<":
80+
num -= 1
81+
if num > cells:
82+
cells = num
83+
return cells + 2
84+
85+
86+
# Version en C de 'getCells()':
87+
#
88+
# int getCells(char source[]){
89+
# int num, cells;
90+
# for(int i; i=<strlen(source); i++){
91+
# if(source[i] == '>'){
92+
# num++;
93+
# }else if(source[i] == '<'){
94+
# num--;
95+
# }
96+
# if(num > cells){
97+
# cells = num;
98+
# }
99+
# }
100+
# return cells + 5;
101+
# }
102+
103+
104+
# Obtiene el input y se lo mete a 'stdin'
105+
if len(argv) == 3:
106+
stdin = argv[2]
107+
print(f"\nArgumentos: {stdin}")
108+
109+
# Leer el codigo del archivo.
110+
with open(argv[1], "r") as file:
111+
source = file.read()
112+
print(f"\nCodigo fuente:\n{source}\n\n")
113+
114+
# Comprueba que no hayan errores es el codigo.
115+
checkErrors(source)
116+
117+
# Variables del interpretador.
118+
prgPos = cellPos = pArg = 0
119+
120+
# Le agrega el numero necesario de celdas necesarias + 2,
121+
# para situaciones inesperadas
122+
cells = []
123+
for i in range(getCells(source)):
124+
cells.append(0)
125+
126+
127+
# Interpretador.
128+
while prgPos != len(source):
129+
# Le da el valor de la instruccion a 'obj'
130+
# para mayor facilidad de acceso.
131+
obj = source[prgPos]
132+
133+
# Comportamiento segun el valor de la instruccion.
134+
if obj == ">":
135+
cellPos += 1
136+
137+
elif obj == "<":
138+
cellPos -= 1
139+
140+
elif obj == "+":
141+
cells[cellPos] += 1
142+
143+
elif obj == "-":
144+
cells[cellPos] -= 1
145+
146+
elif obj == ".":
147+
print(chr(cells[cellPos]), end="")
148+
149+
elif obj == ",":
150+
cells[cellPos] = ord(stdin[pArg])
151+
pArg += 1
152+
153+
elif obj == "]":
154+
if cells[cellPos] != 0:
155+
prgPos = loop(source, prgPos)
156+
157+
# Pasa a la siguiente instruccion.
158+
prgPos += 1

makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
COMPILER=cc
2-
CONF=-o brainfuck
2+
CONF=-Os
3+
NAME=-o brainfuck
34

45
compile:
5-
$(COMPILER) $(CONF) main.c
6+
$(COMPILER) $(CONF) $(NAME) main.c
67

78
test: compile
89
./brainfuck src/thanks.bf

test/add.bf

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/errors.bf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]>><<<<]

test/ioTest.bf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
,.

0 commit comments

Comments
 (0)