Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Interprete Brainf**k

6 views
Skip to first unread message

Noixe

unread,
Jul 24, 2010, 3:35:19 AM7/24/10
to
Salve,

sicuramente molti di voi conosceranno questo linguaggio definito "esoterico"
(http://it.wikipedia.org/wiki/Brainfuck) il quale fa uso solo dei seguenti
simboli che hanno un corrispondente e ben preciso significato in C:

> ++ptr;
< --ptr;
+ ++(*ptr);
- --(*ptr);
. putchar(*ptr);
, *ptr =getchar();
[ while (*ptr) {
] }

dove ptr è: char* ptr;

Ho scritto un interprete in C++ per BF il quale però mi da dei problemi con
i sorgenti che trovo su internet, mentre quelli più semplici scritti da me
(ho provato anche codici con cicli annidati) funzionano bene. Il codice è il
seguente:


#include <iostream>
#include <string>
#include <vector>
#include <fstream>

using namespace std;

vector<int> Loop, Vettore;
vector<char> Istruzioni;

int main (int argc, char* argv[]) {

ifstream input (argv[1], ios_base::in);
string str;
int indice = 0;

do {
getline(input, str, '\n');
for (int i = 0; i < str.size(); i++)
Istruzioni.push_back(str[i]);
}
while (!input.eof());

input.close();

Vettore.resize(Istruzioni.size());

for (int i = 0; i < Istruzioni.size(); i++) {

switch (Istruzioni[i]) {

case '>' :
if (indice < Vettore.size() - 1)
indice++;
break;

case '<' :
if (indice > 0)
indice--;
break;

case '+' :
Vettore[indice]++;
break;

case '-' :
if (Vettore[indice] > 0)
Vettore[indice]--;
break;

case '.' :
putchar(Vettore[indice]);
break;

case ',' :
Vettore[indice] = getchar();
break;

case '[' :
if (!Vettore[indice]) {
while ((i < Istruzioni.size()) && (Istruzioni[i] !=
']'))
i++;
}
else
Loop.push_back(i);
break;

case ']' :
if (Loop.size() > 0)
if (Vettore[indice])
i = Loop.back();
else
Loop.pop_back();
break;
};
};

return 0;

}


Il codice è semplice, mi limito a spiegare meglio gli ultimi due case che
potrebbero essere quelli un po' meno chiari:

Il carattere '[' indica l'inizio di un ciclo quindi vedo se la condizione è
vera o meno (if (!Vettore[indice])):
1. Se è falsa allora il ciclo while scorre tutte le istruzioni che trova
fino a che non trova il carattere ']' che indica la fine del ciclo, oppure
finché non è finito il sorgente.
2. Se è vera, inserisco il punto in cui è stato trovato il carattere '['
(ovvero il valore di i) i un vector (Loop.push_back(i)).

Il carattere ']' indica la fine di un ciclo quindi vedo se sono stati
incontrati dei cicli la cui condizione è vera (if (Loop.size() > 0)):
1. Se non ce ne sono non accade nulla.
2. Se invece ci sono cicli controllo se la condizione dell'ultimo ciclo
incontrato è vera (if (Vettore[indice])):
2a: Se è vera faccio ripartire il ciclo for dalla posizione che avevo
salvato precedentemente nel vector Loop assegnando l'ultimo valore contenuto
ad i (i = Loop.back()).
2b: Se è falsa vuol dire che quel ciclo non deve più essere eseguito quindi
elimino la posizione che avevo salvato indicante l'inizio del ciclo
(Loop.pop_back()).


Infine linko il sorgente di un programma trovato su internet
(http://esoteric.sange.fi/brainfuck/bf-source/prog/PRIME.BF) che prende in
input un numero intero e stampa i numeri primi minori o uguali al numero
dato.
Questo è uno dei programmi che non funziona col mio interprete, infatti
stampa solo 4 caratteri "a caso" e termina.
L'ho tradotto in C sostituendo opportunamente i vari caratteri e funziona,
quindi è affidabile come esempio di codice abbastanza complesso per fare dei
test.

Se qualcuno avesse voglia di fare un po' di debug si faccia avanti :-)

Probabilmente il problema è legato al codice relativo alla gestione dei
cicli. Lo penso solo perché le altre parti di codice sono immediate. Ma come
ho già detto facendo un test su un codice da me scritto che contiene 3 cicli
annidati, funziona correttamente. Magari sbaglio il tipo di dati da usare o
mi sfugge qualcos'altro.

Grazie

Noixe

unread,
Jul 24, 2010, 3:08:38 PM7/24/10
to
"Noixe" <midnightm...@live.it> ha scritto:

> using namespace std;
>
> vector<int> Loop, Vettore;
> vector<char> Istruzioni;

Scusate, ho incollato il sorgente sbagliato. Questa parte di codice sarebbe:
vector<int> Loop;
vector<char> Istruzioni, Vettore;

0 new messages