Newsgroup: it.scienza.informatica
Titolo: Interprete Brainf**k

                 ++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 

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