Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple brainfuck interpreter in C
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// initialize the tape with 30,000 zeroes
unsigned char tape[30000] = {0};
// set the pointer to point at the left-most cell of the tape
unsigned char* ptr = tape;
void interpret(char* input) {
char current_char;
size_t i;
size_t loop;
for (i = 0; input[i] != 0; i++) {
current_char = input[i];
if (current_char == '>') {
++ptr;
} else if (current_char == '<') {
--ptr;
} else if (current_char == '+') {
++*ptr;
} else if (current_char == '-') {
--*ptr;
} else if (current_char == '.' ) {
putchar(*ptr);
} else if (current_char == ',') {
*ptr = getchar();
} else if (current_char == '[') {
continue;
} else if (current_char == ']' && *ptr) {
loop = 1;
while (loop > 0) {
current_char = input[--i];
if (current_char == '[') {
loop--;
} else if (current_char == ']') {
loop++;
}
}
}
}
}
int main() {
interpret(",[.[-],]"); // outputs input
return 0;
}
@trishume

This comment has been minimized.

Copy link

trishume commented Jun 2, 2012

I don't think this is a proper bf interpreter because it doesn't handle nested loops. You need to use a stack to store loop locations instead of just a variable.

@maxcountryman

This comment has been minimized.

Copy link
Owner Author

maxcountryman commented Jun 2, 2012

Probably true, I haven't tried. Feel free to make edits and I'll be happy to update. :)

@maxcountryman

This comment has been minimized.

Copy link
Owner Author

maxcountryman commented Jun 3, 2012

Updated version should now supported nested loops.

@trishume

This comment has been minimized.

Copy link

trishume commented Jun 3, 2012

Awesome!

@maxcountryman

This comment has been minimized.

Copy link
Owner Author

maxcountryman commented Jun 3, 2012

Also wrote one with dynamic memory allocation and trivial garbage collection: https://gist.github.com/1714336

@nickdesaulniers

This comment has been minimized.

Copy link

nickdesaulniers commented Apr 26, 2013

I don't think that the '[' is right because the spec says [ Jump forward past the matching ] if the byte at the pointer is zero. but you don't check ptr, you just continue, which turns [] into a do..while instead of a while. You can duplicate the body of the ']' case but preincrement i instead of predecrement it: current_char = input[++i]; and flip the square brackets in the conditionals. Tested with Hello World with a [[[]]] thrown in immediately after the first loop.

@TheSoftwareGuy

This comment has been minimized.

Copy link

TheSoftwareGuy commented Oct 6, 2013

Why not turn the chain of if else if's into a single switch statement. would be much more readable.

@ooxi

This comment has been minimized.

Copy link

ooxi commented Mar 18, 2018

Why not turn the chain of if else if's into a single switch statement. would be much more readable.

@TheSoftwareGuy that's debatable

@ooxi

This comment has been minimized.

Copy link

ooxi commented Mar 18, 2018

@nickdesaulniers you are right, the implementation of [ is not correct

@himehowareu

This comment has been minimized.

Copy link

himehowareu commented Nov 5, 2018

else if (current_char == '[' && *ptr == 0) { loop = 1; while (loop > 0) { current_char = input[++i]; if (current_char == '[') { loop++; } else if (current_char == ']') { loop--; } } }

this is a edit to make it actually work with the [

@D0tty

This comment has been minimized.

Copy link

D0tty commented Feb 14, 2019

Hi @maxcountryman, just letting you know I used your code for personal work and did a little update of it, here is my gist.
Thanks for this :)

@agoldstein03

This comment has been minimized.

Copy link

agoldstein03 commented Apr 15, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.