Skip to content

Instantly share code, notes, and snippets.

@lifthrasiir
Created September 25, 2010 09:36
Show Gist options
  • Save lifthrasiir/596667 to your computer and use it in GitHub Desktop.
Save lifthrasiir/596667 to your computer and use it in GitHub Desktop.
/* The world's smallest Brainfuck interpreter in C, by Kang Seonghoon
* http://j.mearie.org/post/1181041789/brainfuck-interpreter-in-2-lines-of-c */
s[99],*r=s,*d,c;main(a,b){char*v=1[d=b];for(;c=*v++%93;)for(b=c&2,b=c%7?a&&(c&17
?c&1?(*r+=b-1):(r+=b-1):syscall(4-!b,b,r,1),0):v;b&&c|a**r;v=d)main(!c,&a);d=v;}
@aquaslvt
Copy link

How does this work? :O

@carter-canedy
Copy link

To any newcomers:

Compile using gcc with the flag "-m32"

You may need to install the gcc-multilib package in order to target an x86 binary

After you have the right libraries installed, you should be able to compile like this:

gcc -m32 -o bf bf.c

@f3nai
Copy link

f3nai commented Oct 20, 2023

good stuff.

@adamsir
Copy link

adamsir commented Nov 6, 2023

Here is the clarified version. I used gpt-4 to reconstruct the code, meaning I just wanted to share the clarified version for learning purposes. I don't know C language, but I was curious.

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

#define TAPE_SIZE 30000

// Declare an array to act as the tape for Brainfuck. Initialize all to zero.
unsigned char s[TAPE_SIZE] = {0};

// This will be the data pointer used in Brainfuck
unsigned char* ptr = s;

// Forward declaration of the main function to make it recursive
int main(int argc, char *argv[]);

int main(int argc, char *argv[]) {
  char* v;

  // Ensure that a Brainfuck program is provided as an argument
  if (argc != 2) {
    fprintf(stderr, "Usage: %s 'brainfuck_code'\n", argv[0]);
    return 1;
  }

  v = argv[1];

  while (*v) {
    switch (*v) {
      case '>':
        ptr++;
        // Boundary check to prevent going beyond the tape
        if (ptr >= s + TAPE_SIZE) {
          fprintf(stderr, "Error: Pointer out of bounds\n");
          return 1;
        }
        break;
      case '<':
        // Boundary check to prevent going before the tape
        if (ptr <= s) {
          fprintf(stderr, "Error: Pointer out of bounds\n");
          return 1;
        }
        ptr--;
        break;
      case '+':
        (*ptr)++;
        break;
      case '-':
        (*ptr)--;
        break;
      case '.':
        putchar(*ptr);
        break;
      case ',':
        *ptr = (unsigned char)getchar();
        break;
      case '[':
        if (!*ptr) {
          int loop = 1;
          while (loop > 0) {
            v++;
            if (*v == '[') loop++;
            if (*v == ']') loop--;
          }
        }
        break;
      case ']':
        if (*ptr) {
          int loop = 1;
          while (loop > 0) {
            v--;
            if (*v == '[') loop--;
            if (*v == ']') loop++;
          }
        }
        break;
    }
    v++;
  }

  return 0;
}

How to compile?

gcc brainfuck.c

How to run?

./a.out "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
"

This should dispay

Hello world

@neonfuz
Copy link

neonfuz commented Mar 5, 2024

Here is the clarified version. I used gpt-4 to reconstruct the code, meaning I just wanted to share the clarified version for learning purposes. I don't know C language, but I was curious.

Honestly looks like chat gpt just spat out a generic bf interpreter, it doesn't share many characteristics with the minimal interpreter.

@justanothercatgirl
Copy link

Here is the clarified version. I used gpt-4 to reconstruct the code, meaning I just wanted to share the clarified version for learning purposes. I don't know C language, but I was curious.

Honestly looks like chat gpt just spat out a generic bf interpreter, it doesn't share many characteristics with the minimal interpreter.

Yeah, it doesn't even call main recursively, it just iterates through the string. For some reason, ChatGPT has been upsetting me more and more recently (

@jdahlin
Copy link

jdahlin commented Aug 29, 2024

After a few back and forth with GPT-4o, I got this:

#include <unistd.h>  // for syscall

#define MEMORY_SIZE 99
#define SYSCALL_WRITE 4

#define INCREMENT '+'
#define DECREMENT '-'
#define SHIFT_RIGHT '>'
#define SHIFT_LEFT '<'
#define OUTPUT '.'
#define INPUT ','
#define LOOP_START '['
#define LOOP_END ']'

#define IO_OPERATION_FLAG 2

#define TO_CHAR(x) ((char)(x))
#define TO_INT(x) ((int)(x))

char memory[MEMORY_SIZE], *pointer = memory, *return_address, command;

int main(char argument, char **arguments) {
    return_address = arguments;
    char *code = return_address[1];
    
    while ((command = TO_CHAR(*code++)) != '\0') {
        command = TO_CHAR(TO_INT(command) % 93);

        char is_io_operation = TO_CHAR(command & IO_OPERATION_FLAG);
        char is_pointer_operation = TO_CHAR(command % 7);

        if (is_pointer_operation) {
            if (argument) {
                if (command == INCREMENT || command == DECREMENT) {
                    if (command == INCREMENT) {
                        *pointer += INCREMENT - '0';
                    } else {
                        *pointer += DECREMENT + '0';
                    }
                } else if (command == SHIFT_RIGHT || command == SHIFT_LEFT) {
                    if (command == SHIFT_RIGHT) {
                        pointer += SHIFT_RIGHT - '>';
                    } else {
                        pointer += SHIFT_LEFT - '<';
                    }
                } else if (command == OUTPUT || command == INPUT) {
                    syscall(SYSCALL_WRITE - !is_io_operation, is_io_operation, pointer, 1);
                }
            }
        } else {
            code = return_address;  // Set code pointer back to the start of the current command
        }

        while (is_io_operation && (command | argument ** pointer)) {
            code = return_address;
            main(!command, &argument);  // Toggle argument based on the command
        }

        return_address = code;
    }

    return 0;
}

@ValleyDragon888
Copy link

Wow. wow.

@DarkblooM-IO
Copy link

To any newcomers:

Compile using gcc with the flag "-m32"

You may need to install the gcc-multilib package in order to target an x86 binary

After you have the right libraries installed, you should be able to compile like this:

gcc -m32 -o bf bf.c

Cheers!

@multitrack-collector
Copy link

multitrack-collector commented Feb 17, 2025

Og code using an online C beautifier: https://codebeautify.org/c-formatter-beautifier/y255f5fa5

s[99], * r = s, * d, c;
main(a, b) {
  char * v = 1[d = b];
  for (; c = * v++ % 93;)
    for (b = c & 2, b = c % 7 ? a && (c & 17 ?
        c & 1 ? ( * r += b - 1) : (r += b - 1) : syscall(4 - !b, b, r, 1), 0) : v; b && c | a ** r; v = d) main(!c, & a);
  d = v;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment