-4

I decided to write another one BF interpreter in order of personal development, and despite the fact that this is his second version written from scratch, one way or another it doesn't work correctly with cycles. Please tell me how this can be rewritten, or what is the logical problem. Below is the code and examples of programs in BF.

#include <stdio.h>

void brainfuck(char* str, int length)
{
    char arr[30000] = { 0 };
    int ptr = 0, i = 0;

    int **brackets = { 0 };
    int br_len = 0;

    while (i < length)
    {
        if (str[i] == '[')
        {
            brackets = (int **)realloc(brackets, (br_len + 1) * sizeof(int *));
            brackets[br_len] = (int *)malloc(2 * sizeof(int));
            brackets[br_len][0] = '[';
            brackets[br_len][1] = i;
            br_len++;
        }
        else if (str[i] == ']')
        {
            brackets = (int **)realloc(brackets, (br_len + 1) * sizeof(int *));
            brackets[br_len] = (int *)malloc(2 * sizeof(int));
            brackets[br_len][0] = ']';
            brackets[br_len][1] = i;
            br_len++;
        }

        i++;
    }

    int counter, pos, j; i = 0;

    while (i < length)
    {
        switch (str[i])
        {
            case '>': ptr++; break;
            case '<': ptr--; break;
            case '+': arr[ptr]++; break;
            case '-': arr[ptr]--; break;
            case '.': putchar(arr[ptr]); break;
            case ',': arr[ptr] = getchar(); break;
            case '[':
                if (arr[ptr] == 0)
                {
                    j = 0;
                    pos = 0;

                    do
                    {
                        pos = j;
                        j++;
                    }
                    while (brackets[j - 1][1] != i);

                    j = pos + 1;
                    counter = 1;

                    while (j < br_len)
                    {
                        if (brackets[j][0] == '[')
                            counter++;
                        else if (brackets[j][0] == ']')
                        {
                            counter--;
                            if (counter == 0)
                                break;
                        }

                        j++;
                    }

                    i = brackets[j][1];
                }

                break;
            case ']':
                if (arr[ptr] == 0)
                {
                    j = br_len - 1;
                    pos = br_len - 1;

                    do
                    {
                        pos = j;
                        j--;
                    } while (brackets[j + 1][1] != i);

                    j = pos - 1;
                    counter = -1;

                    while (j >= 0)
                    {
                        if (brackets[j][0] == '[')
                        {
                            counter++;
                            if (counter == 0)
                                break;
                        }
                        else if (brackets[j][0] == ']')
                            counter--;

                        j--;
                    }

                    i = brackets[j][1] - 1;
                }

                break;
            default: break;
        }

        i++;
    }

    free(brackets);
}

void main()
{
    FILE* fr;
    int length;
    char* str;

    fr = fopen("input.txt", "r");

    fseek(fr, 0, SEEK_END);
    length = ftell(fr);
    rewind(fr);

    str = (char*)malloc(length * sizeof(char));
    fread(str, 1, length, fr);

    brainfuck(str, length);

    free(str);
    fclose(fr);
}

"Hello World!" with one loop

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

"Hello World!" with nested loops

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
BurovB
  • 1
  • 2
  • 2
    "Troubleshoot my program for me" isn't really what we do here. – Robert Harvey Mar 15 '21 at 14:27
  • it will not _fix_ your stated problem, but [casting the return of `malloc()`, `realloc()` or ``calloc()` is not a good idea in C.](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – ryyker Mar 15 '21 at 14:30

1 Answers1

0

']' should jump back if cell is nonzero

Hugely convoluted approach; you want to put the matches in the brackets array so it's like

case '[':
  if (arr[ptr] == 0)
    i = brackets[i];
  break;

Why i = brackets[j][1] - 1; and not just i = brackets[j][1]; (extra speed cost)

Having j and pos laboriously correlate is a red flag

Forgot to free all those little 2-int arrays

  • Thank you very much, seems like it's working now. -1 stands for jumping to point of program previous than that one having [, to make loops work correctly. And I will clear those mini-arrays rn – BurovB Mar 20 '21 at 14:59
  • Jumping back to the instruction before the [ means the [ is the next instruction to execute. But that [ is guaranteed to do nothing (because arr[ptr] != 0 or you wouldn't have made the jump). So it's a pure waste of time. Jumping back to the [ means the instruction after the 1 is next to execute. – Daniel Cristofani Mar 21 '21 at 03:24