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 :)

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.