Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

My first Brainfuck

Name: The Amazing Anus !Anus3nMVO2 2009-08-31 1:43

I was bored as fuck so I decided to implement a Brainfuck interpreter in C.

/* brainfuck.c ... version 0.9
 *
 * usage: brainfuck <file>
 *
 */

 
#include <stdio.h>

/* 64kb -1b each
 *
 * The Brainfuck spec says that memory should be 30000 bytes, but I prefer to
 * use a whole 64kb for both code and memory.
 *
 */
#define BRAINF_CODESIZE   65535
#define BRAINF_MEMSIZE   65535


FILE* fp;

unsigned char* code, *memory;
short unsigned int codeptr, memptr;


int main(int argc, char* argv[])
{
     if (argc != 2)
          exit(1);

     if ((fp = fopen(argv[1], "r")) == NULL)
          exit(1);

     code = malloc(BRAINF_CODESIZE);
     memory = malloc(BRAINF_MEMSIZE);

     memset(code, 0, BRAINF_CODESIZE);
     memset(memory, 0, BRAINF_MEMSIZE);

     codeptr = 0;
     memptr = 0;

     while (!feof(fp))
     {
          fread(code, BRAINF_CODESIZE -1, 1, fp);
     }


     /*** Interpreting begins ***/
     while (code[codeptr])
     {
          switch (code[codeptr])
          {
               case '>':
                    ++memptr;
                    ++codeptr;
                    break;

               case '<':
                    --memptr;
                    ++codeptr;
                    break;

               case '+':
                    ++memory[memptr];
                    ++codeptr;
                    break;

               case '-':
                    --memory[memptr];
                    ++codeptr;
                    break;

               case '.':
                    putchar(memory[memptr]);
                    ++codeptr;
                    break;

               case ',':
                    memory[memptr] = getchar();
                    ++codeptr;
                    break;

               /* :NOTE: Some kind of error handling should take
                * place if no ']' is found.
                */
               case '[':
                    if (!memory[memptr])
                    {
                         while ((code[codeptr] != ']') && (code[codeptr]))
                         {
                              ++codeptr;
                         }
                    }
                    else
                         ++codeptr;
                    break;


               /* :NOTE: Some kind of error handling should take
                * place if no '[' is found.
                */
               case ']':
                    if (memory[memptr])
                    {
                         while ((code[codeptr] != '[') && (codeptr))
                              --codeptr;
                    }
                    else
                         ++codeptr;
                    break;

               /* invalid instruction
                * For now we will just continue executing when this happens.
                * It should ignore characters 10, 13, & 32 anyways.
                */
               default:
                    ++codeptr;
                    break;
          }
     }

     free(code);
}

Name: The Amazing Anus !Anus3nMVO2 2009-09-02 19:37

Ok, finally got around to fixing it.

/* brainfuck.c ... version 0.91
 *
 * usage: brainfuck <file>
 *
 */

#include <stdio.h>
#include <stdint.h>

/* 64kb each
 *
 * The Brainfuck spec says that memory should be 30000 bytes, but I prefer to
 * use a whole 64kb for both code and memory.
 *
 */
#define BRAINF_CODESIZE   65536
#define BRAINF_MEMSIZE   65536


FILE* fp;

uint8_t* code, *memory;
uint16_t codeindex, memindex;
int16_t bracketdepth;


int main(int argc, char* argv[])
{
     if (argc != 2)
     {
          printf("usage: brainfuck <file>\n");
          exit(1);
     }

     if ((fp = fopen(argv[1], "r")) == NULL)
          exit(1);

     if ((code = malloc(BRAINF_CODESIZE)) == NULL)
          exit(1);

     if ((memory = malloc(BRAINF_MEMSIZE)) == NULL)
          exit(1);

     memset(code, 0, BRAINF_CODESIZE);
     memset(memory, 0, BRAINF_MEMSIZE);

     codeindex = 0;
     memindex = 0;

     fread(code, BRAINF_CODESIZE, 1, fp);

     if (ferror(fp))
          exit(1);

     bracketdepth = 0;


     /*** Interpreting begins.  Ends on NULL in codebyte. ***/
     while (code[codeindex])
     {
          switch (code[codeindex])
          {
               case '>':
                    ++memindex;
                    ++codeindex;
                    break;

               case '<':
                    --memindex;
                    ++codeindex;
                    break;

               case '+':
                    ++memory[memindex];
                    ++codeindex;
                    break;

               case '-':
                    --memory[memindex];
                    ++codeindex;
                    break;

               case '.':
                    putchar(memory[memindex]);
                    ++codeindex;
                    break;

               case ',':
                    memory[memindex] = getchar();
                    ++codeindex;
                    break;


               case '[':
                    if (!memory[memindex])
                    {
                         ++bracketdepth;
                         while (bracketdepth)
                         {
                              if (!code[++codeindex])  /* Exit if NULL */
                                   exit(1);

                              if (code[codeindex] == '[')
                                   ++bracketdepth;

                              if (code[codeindex] == ']')
                                   --bracketdepth;
                         }
                    }
                    else
                         ++codeindex;
                    break;


               case ']':
                    if (memory[memindex])
                    {
                         --bracketdepth;
                         while (bracketdepth)
                         {
                              if (codeindex-- == 0)  /* Exit if need to go */
                                   exit(1);          /* past first codebyte */

                              if (code[codeindex] == '[')
                                   ++bracketdepth;

                              if (code[codeindex] == ']')
                                   --bracketdepth;
                         }
                    }
                    else
                         ++codeindex;
                    break;


               /* non-instruction character */
               default:
                    ++codeindex;
                    break;
          }
     }

     free(code);

     return 0;
}


Again, tell me if I did anything wrong (eg. that is poor style), or what I could have done better, like more efficiently or would be more readable.


And here's a little program I found that will print out the Fibonacci numbers:

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


That code doesn't end itself so you'll have to terminate the process yourself if you run it.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List