Newsgroup: it.comp.lang.c++
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;
vector<char> Istruzioni, Vettore;
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]) {
                    int quadre = 0;
                    while (i < Istruzioni.size()) {
                        if (Istruzioni[i] == '[')
                            quadre++;
                        else
                        if (Istruzioni[i] == ']')
                            quadre--;
                        i++;
                        if (quadre == 0)
                            break;
                    };
                }
                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. La variabile "quadre" serve a tenere conto
di eventuali cicli anni dati in modo da scorrere fino alla parentesi quadra 
chiusa
che corrisponda a quella aperta indicante il ciclo while falso.
2. Se � vera, inserisco il punto in cui � stato trovato il carattere '['
(ovvero il valore di i) in 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.
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 

Problema risolto.