Até aqui, o programa já abre um arquivo e coloca seu conteúdo na memória. Só falta fazê-lo analisar e interpretar o arquivo.
Adicione, antes de do { c = getchar(); } while ((c != '\n') && (c != EOF));
e return 1;
, uma variável de 30.000 elementos, chamada pilha, a qual será usada para armazenar as células (as variáveis do brainfuck), uma variável chamada pos, com a quantidade de elementos informados pela variável colchetes, a qual será usada para guardar as localizações das estruturas de repetição e, uma variável chamada ptr, a qual será usada como um indicador (ou ponteiro) para a célula selecionada. Também crie um estrutura de repetição para contar os “[” e guardar suas localizações, para uso futuro. Ficará assim:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int c;
FILE *arquivo; // Deve-se usar o asterisco aqui, por ser ponteiro
if (argc >= 2) // Se tiver 2 ou mais argumentos
{
arquivo = fopen(argv[1], "rb"); // Abre o arquivo especificado
if (arquivo == NULL) // Se não conseguir abrir o arquivo
{
puts("ERRO: Não foi possível abrir o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1; // Encerra o programa
}
}
else
{
return 0; // Encerra o programa
}
fseek(arquivo, 0, SEEK_END);
int tamanho = ftell(arquivo); // Offset do fim do arquivo, que equivale ao tamanho do arquivo
rewind(arquivo); // Rebobina o arquivo
// Aloca memória, com um byte adicional para o nulo (usado em strings em C)
char *fonte = (char *) malloc(tamanho + 1);
if (fonte == NULL) // Verifica se consegui alocar memoria
{
puts("ERRO: Não há memória o suficiente!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
memset(fonte, 0, tamanho * sizeof(char)); // Preencherá a variável fonte com zeros (para "limpar")
size_t size = fread(fonte, 1, tamanho, arquivo);
fonte[tamanho] = 0; // Põe o sinal de fim (nulo)
if (size != tamanho * sizeof(char))
{
puts("ERRO: Não foi possível ler o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
int colchetes = 0, i;
for (i = 0; i < tamanho; i++)
{
if (fonte[i] == '[')
{
colchetes++;
}
else if (fonte[i] == ']')
{
if (colchetes == 0) // Se nenhuma estrutura '[' está aberta
{
puts("ERRO: A estrutura de repetição ']' não foi aberta!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
else
{
colchetes--;
}
}
}
if (colchetes > 0) // Se alguma estrutura '[' não foi fechada
{
puts("ERRO: A estrutura de repetição '[' não foi fechada!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
unsigned char pilha[30000]; // Equivalente a aproximadamente 30 KB
memset(pilha, 0, 30000 * sizeof(unsigned char));
int backup = 0, ptr = 0, pos[tamanho];
colchetes = 0;
for (i = 0; i < tamanho; i++)
{
if (fonte[i] == '[')
{
backup = i;
while (i < tamanho)
{
if (fonte[i] == '[')
{
colchetes++;
}
else if (fonte[i] == ']')
{
colchetes--;
}
if (colchetes == 0)
{
break;
}
i++;
}
pos[i] = backup;
pos[backup] = i;
i = backup;
}
}
free(fonte);
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 0;
}
Depois disso, adicione uma estrutura de repetição, de preferência uma do tipo for
, com a condição de repetir até o índice apontar para o último elemento da variável fonte e, dentro dela coloque uma condição, a qual se o elemento examinado for igual a “+”, deverá incrementar o valor da célula selecionada. Em seguida, adicione outra condição, a qual se o elemento examinado for igual a “.”, deverá por na tela o conteúdo da célula selecionada. Ficará assim:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int c;
FILE *arquivo; // Deve-se usar o asterisco aqui, por ser ponteiro
if (argc >= 2) // Se tiver 2 ou mais argumentos
{
arquivo = fopen(argv[1], "rb"); // Abre o arquivo especificado
if (arquivo == NULL) // Se não conseguir abrir o arquivo
{
puts("ERRO: Não foi possível abrir o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1; // Encerra o programa
}
}
else
{
return 0; // Encerra o programa
}
fseek(arquivo, 0, SEEK_END);
int tamanho = ftell(arquivo); // Offset do fim do arquivo, que equivale ao tamanho do arquivo
rewind(arquivo); // Rebobina o arquivo
// Aloca memória, com um byte adicional para o nulo (usado em strings em C)
char *fonte = (char *) malloc(tamanho + 1);
if (fonte == NULL) // Verifica se consegui alocar memoria
{
puts("ERRO: Não há memória o suficiente!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
memset(fonte, 0, tamanho * sizeof(char)); // Preencherá a variável fonte com zeros (para "limpar")
size_t size = fread(fonte, 1, tamanho, arquivo);
fonte[tamanho] = 0; // Põe o sinal de fim (nulo)
if (size != tamanho * sizeof(char))
{
puts("ERRO: Não foi possível ler o arquivo!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
int colchetes = 0, i;
for (i = 0; i < tamanho; i++)
{
if (fonte[i] == '[')
{
colchetes++;
}
else if (fonte[i] == ']')
{
if (colchetes == 0) // Se nenhuma estrutura '[' está aberta
{
puts("ERRO: A estrutura de repetição ']' não foi aberta!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
else
{
colchetes--;
}
}
}
if (colchetes > 0) // Se alguma estrutura '[' não foi fechada
{
puts("ERRO: A estrutura de repetição '[' não foi fechada!");
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 1;
}
unsigned char pilha[30000]; // Equivalente a aproximadamente 30 KB
memset(pilha, 0, 30000 * sizeof(unsigned char));
int backup = 0, ptr = 0, pos[tamanho];
colchetes = 0;
for (i = 0; i < tamanho; i++)
{
if (fonte[i] == '[')
{
backup = i;
while (i < tamanho)
{
if (fonte[i] == '[')
{
colchetes++;
}
else if (fonte[i] == ']')
{
colchetes--;
}
if (colchetes == 0)
{
break;
}
i++;
}
pos[i] = backup;
pos[backup] = i;
i = backup;
}
}
for (i = 0; i < tamanho; i++)
{
switch (fonte[i])
{
case '+':
pilha[ptr]++;
break;
case '.':
putchar(pilha[ptr]);
break;
}
}
free(fonte);
do { c = getchar(); } while ((c != '\n') && (c != EOF));
return 0;
}
« parte anterior próxima parte »
0 comentários:
Postar um comentário