lol lol - 4 months ago 24
Brainfuck Question

Handling loops in Brainf*ck

I tried testing my Brainfuck interpreter in c with this bottle shaped code in Brainfuck:

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


And instead ouf outputing the whole '99 bottles of beers on the wall' song from 99 to 1, it put out just the verses from 99 to 96 bottles. Is there something wrong with the loops in Brainfuck code or in the interpreter?

Here is my c code:

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

int loop(char *commands, int indexOfCommand, int mode){
int sum = 0;
int movingIndex = indexOfCommand;
while(sum > -1){
movingIndex -= mode;
if(commands[movingIndex] == ']')
sum += mode;
else if(commands[movingIndex]=='[')
sum -= mode;
}
return movingIndex;
}

int main(){
unsigned char array[30000] = {0}; // all elements are 0
unsigned char commands[60000] = {0}; // all elements are 0
int counter = 0;
int c;

int loop(char *commands, int indexOfCommand, int mode);

while((c = getchar()) != EOF){
commands[counter] = c;
counter++;
}

int indexOfArray = counter;
int indexOfCommands = 0;
int numOfCommands = 0;

int length = sizeof(commands)/sizeof(commands[0]); // the length of an array

while (indexOfCommands < length && numOfCommands < 60000){
switch(commands[indexOfCommands]){
case '+':
if(array[indexOfArray]==255){
array[indexOfArray]=0;
} else array[indexOfArray]++;
break;
case '-':
if(array[indexOfArray]==0){
array[indexOfArray]=255;
}else array[indexOfArray]--;
break;
case '>':
indexOfArray++;
break;
case '<':
indexOfArray--;
break;
case '.':
putchar(array[indexOfArray]);
break;
case ']':
if(array[indexOfArray]!=0) {
indexOfCommands=loop(commands,indexOfCommands,1);
}
break;
case '[':
if(array[indexOfArray]==0){
indexOfCommands=loop(commands,indexOfCommands,-1);
}
break;
default:
// if there is any other character, just ignore it
break;
}
indexOfCommands++;
numOfCommands++;
}

return 0;
}

Answer

The condition for premature end of the program execution is here:

while (indexOfCommands < length && numOfCommands < 60000) {
                                   ^^^^^^^^^^^^^^^^^^^^^
    // interpret BF opcodes

    numOfCommands++;
}

You have underestimated how many instruction BF needs to do simple things. (I'm not sure why that condition is in there. Remove it and you'll see all 99 verses.)

Comments