2

I'm trying to run a hello world program with the brainfuck implementation that I made this week but I'm getting a strange output.

This is the hello world file that I'm trying to run.

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

I have saved it to hello.txt, and am parsing it in the main function of the program.

The output is

1 -3 4 4 7 0 -1 7 10 4 -4 1 2

which, when you add 72, and convert to character , gives

I E L L O H G O R L D I J

So it seems like there is something I'm missing, even though its sort of close to the right solution.

But I'll go into the structure of the thing anyhow, the general idea is as followed:

We have two 'tapes', a program to follow which I label 'parsed' which has a pointer 'attached' to it, and an empty tape to write into, which I label 'mem', which also has a pointer 'attached' to it. We also have a list of structures that we can use to jump between bracket locations.

In the main function, there are three parts: first I parse the program and store it in an array. Then I run through this parsing and match brackets, then I start the brainfuck loop and write the output onto the empty array, until the final character has been reached.

In the brainfuck loop, when we find a bracket, we run through the list of pairs to find its match, and then jump to that location.

Maybe it's a bit clunky, but I hope it makes sense.

    #include <stdio.h>
    #include <stdlib.h>

    #define MAX 30000

    //input tape
    char parsed[MAX];
    char * ptr;

    //bracket matching
    struct bracketlinks{
        char * bracket_1;
        char * bracket_2;
    };
    struct bracketlinks * pairslist;
    int bracket_count;

    //output tape
    char mem[MAX] = {0};
    int * mptr;

    int main(){
        mptr = malloc(sizeof(int));

        //parse text file and make list of tokens
        FILE * parsecode;
        parsecode = fopen("helloworldbf.txt", "r");
        int count = 0;
        char buffer;
        while(!feof(parsecode)){
            buffer = fgetc(parsecode);
            if(buffer == 10){break;}
            if(buffer == 32){continue;}
            else{
                parsed[count] = buffer;
                if(buffer == 91 || buffer == 93){
                    bracket_count++;
                }
                count++;
            }
        }
        fclose(parsecode);

        pairslist = malloc(bracket_count * sizeof(char*));

        //creates array of structures which match brackets so we can perform memory jumps
        int reset_count;
        int list_counter = 0;
        for(int i = 0; i < count; i++){
            if(parsed[i] == '['){
                reset_count = 0;
                for(int j = 0; j < count - i + 1; j++){
                    if(parsed[i + j] == '['){reset_count++;}
                    if(parsed[i + j] == ']'){reset_count--;}
                    if(reset_count == 0){
                        struct bracketlinks new;
                        new.bracket_1 = &parsed[i];
                        new.bracket_2 = &parsed[i + j];
                        pairslist[list_counter] = new;
                        list_counter++;
                        break;
                    }
                    else{continue;}
                } 
            }
            else{continue;}
        }

        //runs through the input tape and performs operations on the output tape
        ptr = parsed;
        char final_token = ptr[count];
        while(ptr[0] != final_token){
            if(ptr[0] == '['){
                if(mem[mptr[0]]){++ptr;}
                if(!mem[mptr[0]]){
                    for(int i = 0; i < bracket_count/2; i++){
                        if(pairslist[i].bracket_1 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_2;
                        }
                        if(pairslist[i].bracket_2 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_1;
                        }
                        else{continue;}
                    }
                }
            }
            if(ptr[0] == ']'){
                if(!mem[mptr[0]]){
                    for(int i = 0; i < bracket_count/2; i++){
                        if(pairslist[i].bracket_1 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_2;
                        }
                        if(pairslist[i].bracket_2 == &ptr[0]){
                            ptr = ++pairslist[i].bracket_1;
                        }
                        else{continue;}
                    }
                }
                if(mem[mptr[0]]){++ptr;}
                else{continue;}
            }
            if(ptr[0] == '+'){++ptr;++mem[mptr[0]];}
            if(ptr[0] == '-'){++ptr;--mem[mptr[0]];}
            if(ptr[0] == '>'){++ptr; mptr[0]++;}
            if(ptr[0] == '<'){mptr[0]--;++ptr;}
            if(ptr[0] == '.'){++ptr; printf("%c %d \n", mem[mptr[0]] + 72, mem[mptr[0]]);}
            else{continue;}
        }
        free(pairslist);
        free(mptr);
        return 0;
    }

Any help would be massively appreciated,

Cheers..

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
AKRA
  • 300
  • 2
  • 12
  • 1
    Try with smaller examples. Print and check status in each step and check if they are what is expected. – MikeCAT Jan 12 '21 at 16:45
  • Reagrding `mptr`. the statement `mptr = malloc(sizeof(int*));` for a `int *` is erroneous in itself. It should be `sizeof *mptr;` . Second, that allocation for `mptr` is never populated with *determinate* data. Ex: `if(mem[mptr[0]]){++ptr;}` expects `mptr[0]` have a set value; there is none. From what I see, `mptr` is pointless anyway. You never utilize anything besides the first element; it may as well be `int` and belay the dynamic allocation of that entirely. Finally, [`while(!feof(parsecode))` is wrong](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – WhozCraig Jan 12 '21 at 16:49
  • Here is a BF interpreter written in C. Compare to that. https://gist.github.com/maxcountryman/1699708 – klutt Jan 12 '21 at 16:49
  • @WhozCraig sure I noticed that after I finished the code the first time, but then I went to try and change it and got a load of errors so decided to leave it until the other problems are sorted. – AKRA Jan 12 '21 at 17:00
  • @klutt this implementation is incorrect It seems, according to the general opinion. – AKRA Jan 12 '21 at 17:00
  • @AKRA Possibly. Did not check extremely carefully. But it should not be hard to find a working one to compare to. As it stands, this question is a bit too broad to be suitable here at SO. – klutt Jan 12 '21 at 17:02
  • 1
    @klutt sure, I get what you mean – AKRA Jan 12 '21 at 17:04
  • Your while loop is wrong https://stackoverflow.com/q/5431941/6699433 – klutt Jan 12 '21 at 17:12
  • @klutt yes i'm looking for an alternative right now! will update with the correction – AKRA Jan 12 '21 at 17:13

1 Answers1

0

OK so here's the fix for the main bug: basically just switch the exclamation marks and don't be a numpty.

 if(ptr[0] == ']'){
            if(mem[mptr[0]]){
                for(int i = 0; i < bracket_count/2; i++){
                    if(pairslist[i].bracket_1 == &ptr[0]){
                        ptr = ++pairslist[i].bracket_2;
                    }
                    if(pairslist[i].bracket_2 == &ptr[0]){
                        ptr = ++pairslist[i].bracket_1;
                    }
                    else{continue;}
                }
            }
            if(!mem[mptr[0]]){++ptr;}
            else{continue;}
        }

Still working on the !feof thing but will update with that too

AKRA
  • 300
  • 2
  • 12