Skip to content

Instantly share code, notes, and snippets.

@lifthrasiir
Created September 25, 2010 09:36
Show Gist options
  • Star 118 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • 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;}
@mikedanese
Copy link

This is awesome.

Copy link

ghost commented Dec 10, 2021

wow

@SheatNoisette
Copy link

Eh beh

@blankettripod
Copy link

blankettripod commented Dec 10, 2021

how te fook. (also who is here from bf in 100 seconds)

@maciej-debowski
Copy link

5th

@cybe42
Copy link

cybe42 commented Dec 10, 2021

@blankettripod me, im here from the video

@AryanGitHub
Copy link

same here came from the video, understanding brainf better.

@ShresthaShome
Copy link

ShresthaShome commented Dec 10, 2021

How does this even compile in C? It's wrong syntactically.
Please give a refined code of this.

@cybe42
Copy link

cybe42 commented Dec 11, 2021

@ShresthaShome can you explain what syntax error you can see?

@asm95
Copy link

asm95 commented Dec 13, 2021

Also here from the video: https://www.youtube.com/watch?v=hdHjjBS4cs8

@usercybe maybe because of main(a,b){...} which should be void main(int a, char** b){...}. Or s[99] which should contain the type declaration. But when running with gcc:

bf.c:3:1: warning: data definition has no type or storage class
 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
 ^
bf.c:3:1: warning: type defaults to ‘int’ in declaration of ‘s’ [-Wimplicit-int]
bf.c:3:8: warning: type defaults to ‘int’ in declaration of ‘r’ [-Wimplicit-int]
 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
        ^
bf.c:3:13: warning: type defaults to ‘int’ in declaration of ‘d’ [-Wimplicit-int]
 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
             ^
bf.c:3:15: warning: type defaults to ‘int’ in declaration of ‘c’ [-Wimplicit-int]
 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
               ^
bf.c:3:17: warning: return type defaults to ‘int’ [-Wimplicit-int]
 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
                 ^~~~
bf.c: In function ‘main’:
bf.c:3:17: warning: type of ‘a’ defaults to ‘int’ [-Wimplicit-int]
bf.c:3:17: warning: type of ‘b’ defaults to ‘int’ [-Wimplicit-int]
bf.c:3:37: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
 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
                                     ^
bf.c:3:34: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
 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
                                  ^
bf.c:4:18: warning: pointer/integer type mismatch in conditional expression
    ?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;}
                  ^
bf.c:4:28: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
    ?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;}
                            ^~~~~~~
bf.c:4:27: warning: pointer/integer type mismatch in conditional expression
    ?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;}
                           ^
bf.c:4:50: warning: pointer/integer type mismatch in conditional expression
    ?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;}
                                                  ^
bf.c:3:68: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
 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
                                                                    ^
bf.c:4:64: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
    ?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;}
                                                                ^
bf.c:4:80: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
    ?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;}

It's all just warnings. It does compiles in the end.

Copy link

ghost commented Dec 10, 2022

how do i compile with it???

Copy link

ghost commented Dec 10, 2022

how to compile some bf

@blankettripod
Copy link

@tpglitch you compile the program with GCC
gcc -o bf bf.c
Then you pass the program as an argument
./bf +++++,.--

@xhxe
Copy link

xhxe commented Feb 15, 2023

main is recursive wow

@carter-canedy
Copy link

r e c u r s e m a i n

@dtomvan
Copy link

dtomvan commented Feb 15, 2023

using gcc to compile results in a binary that segfaults on any input

Same here, it does compile, but it always segfaults.

$ /bin/gcc --version | head -n1
gcc (GCC) 12.2.1 20230201

$ expac '%v' gcc
12.2.1-2

$ expac -Ss '%r-%v' '^gcc$'
core-12.2.1-2

Still nice idea, but for some reason just doesn't work.

@locnnil
Copy link

locnnil commented Mar 28, 2023

My compiled binary with gcc also gets segfaults for any input! Anyone have a tip!?

My GCC: gcc (Ubuntu 12.1.0-2ubuntu1~22.04) 12.1.0

@carter-canedy
Copy link

carter-canedy commented Mar 28, 2023

See below

@lifthrasiir
Copy link
Author

lifthrasiir commented Mar 29, 2023

you'll need to refactor the bf compiler so that it's not implicitly typing all untyped variables as ints, this only works as-is on platforms where the int width is the same as a char (1 octet/8 bits), which is the case on the pdp11. To run this as-is, your best bet is to see if you can find an emulator for the pdp11, if it exists.

No it isn't. It does assume that int has the same size as a pointer, which no longer holds in modern 64-bit architectures, but I'm pretty sure that you can still compile and run this code in 32-bit architectures by, for example, using -m32 in GCC to force it. (As you can imagine, because I wrote that code. But I'm on a road and I cannot readily test that, so YMMV.)

@kwmu4k
Copy link

kwmu4k commented Apr 20, 2023

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.

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