Проблемы с интерпретатором Brainfuck

Я новичок в C. В настоящее время я пытаюсь написать интерпретатор Brainfuck. Я пробовал это до сих пор.

#include <unistd.h>
#include <stdlib.h>

char    *line;
int     curr_pos;

void    interprete(char *coms)
{
    int a;
    int curr_loop;

    a = -1;
    curr_loop = 0;
    while (line[++a])
        line[a] = 0;
    a = -1;
    while (coms[++a])
    {
        if (coms[a] == '+')
            line[curr_pos]++;
        else if (coms[a] == '-')
            line[curr_pos]--;
        else if (coms[a] == '>')
            curr_pos++;
        else if (coms[a] == '<')
            curr_pos--;
        else if (coms[a] == '.')
            write(1, &line[curr_pos], 1);
        else if (coms[a] == '[')
        {
            if (line[curr_pos])
                curr_pos++;
            else
            {
                curr_loop = 1;
                while (curr_loop)
                {
                    ++a;
                    if (coms[a] == '[')
                        curr_loop++;
                    else if (coms[a] == ']')
                        curr_loop--;
                }
            }
        }
        else if (coms[a] == ']')
        {
            if (line[curr_pos])
            {
                curr_loop = 1;
                while (curr_loop)
                {
                    --a;
                    if (coms[a] == '[')
                        curr_loop--;
                    else if (coms[a] == ']')
                        curr_loop++;
                }
            }
            else
                curr_pos++;
        }
    }
}

int main(int ac, char **av)
{
    if (ac == 2)
    {
        curr_pos = 0;
        line = malloc(sizeof(char) * 4096);
        interprete(av[1]);
    }
    write(1, "\n", 1);
}

Работает только без циклов ("[" и "]"). Когда я пытаюсь:

++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

Это дает мне результат

^B^A^H^H^K^B^Q^K^N^H^@^C^@

Ожидаемый результат:

Hello World!

person Dan    schedule 22.09.2016    source источник
comment
Какой у Вас вопрос? Также, глядя на ваш код, я думаю, вам следует избегать лесов и вариантов использования.   -  person    schedule 22.09.2016
comment
Почему он дает неправильный результат и как улучшить мой код (возможно).   -  person Dan    schedule 22.09.2016
comment
@Mayerz Вы правы, но это своего рода проблема, задача, и мне не разрешено использовать кейсы.   -  person Dan    schedule 22.09.2016
comment
Каков ожидаемый результат?   -  person Klas Lindbäck    schedule 22.09.2016
comment
Вывод @Klas Lindbäck: Hello World!   -  person Dan    schedule 22.09.2016
comment
Ваша инициализация line кажется мне странной, особенно конец цикла: вы пишете 0 внутри строки, пока не найдете первый нулевой элемент. Но строка выделяется с помощью malloc, поэтому нет гарантии, что хотя бы один элемент равен нулю, или такой набор (1, 2, 0, 4)   -  person Garf365    schedule 22.09.2016
comment
Итак, как его правильно инициализировать?   -  person Dan    schedule 22.09.2016
comment
Вы можете использовать calloc или передать размер функции и выполнить цикл для этого размера вместо цикл поиска нулевого терминатора. line = calloc(4096, 1);   -  person LPs    schedule 22.09.2016
comment
И вы должны проверить malloc & friends возвращаемое значение != NULL.   -  person LPs    schedule 22.09.2016
comment
@LPs это ничего не меняет, но все равно хороший момент   -  person Dan    schedule 22.09.2016
comment
Я отвечал на ваш последний вопрос. Если код не выводит то, что вы ожидаете, вам следует отладить его ....   -  person LPs    schedule 22.09.2016
comment
@LPs Я сказал, может быть, так что это менее важный вопрос   -  person Dan    schedule 22.09.2016
comment
используйте {и}, если в вашем коде есть ошибка, связанная с блоком, ее очень сложно обнаружить   -  person 12431234123412341234123    schedule 22.09.2016


Ответы (1)


Думаю, проблемы в следующих блоках кода:

else if (coms[a] == '[')
{
    ...
}
else if (coms[a] == ']')
{
    ...
}

Программа ищет другую скобку (и находит ее), но ваш указатель кода дополнительно увеличивается в вашем while-выражении (строка 17). Таким образом, вы должны уменьшить a на 1 после ваших циклов поиска. Вторая проблема заключается в том, что вы увеличиваете указатель data (curr_pos)
если com[a] == '[' и line[curr_pos] != 0
и если com[a] == ']' и line[curr_pos] == 0
Вы должны увеличивать код < / em> -pointer (a) то, что по-прежнему автоматически увеличивается в вашем while-выражении. Так что на самом деле вы должны пройти в этом случае. Наконец, вам действительно не нужно проверять обе скобки, если текущее значение ячеек не равно нулю. Предлагаемый мной код будет выглядеть так:

else if (coms[a] == '[')
{
    if (!line[curr_pos])
    {
        curr_loop = 1;
        while (curr_loop)
        {
            ++a;
            if (coms[a] == '[')
                cur_loop++;
            else if (coms[a] == ']')
                cur_loop--;
        }
        a--;
    }
}
else if (coms[a] == ']')
{
    // You can always jump back to the opening bracket '['
    // because then the program checks again and jumps behind
    // the closing bracket if line[a] != 0
    curr_loop = 1;
    while (curr_loop)
    {
        --a;
        if (coms[a] == '[')
            curr_loop--;
        else if (coms[a] == ']')
            curr_loop++;
    }
    a--;
}

Кстати: попробуйте реализовать команду '_13 _'-. Это делает мозговые программы намного интереснее;)

person Aemyl    schedule 09.11.2016