Skip to content

Instantly share code, notes, and snippets.

@1995eaton
Created November 14, 2014 17:32
Show Gist options
  • Save 1995eaton/e140b4b3cf4f158169fc to your computer and use it in GitHub Desktop.
Save 1995eaton/e140b4b3cf4f158169fc to your computer and use it in GitHub Desktop.
Brainfuck interpreter in C
#include <stdio.h>
#include <stdlib.h>
static struct {
size_t buffer_size;
char *buffer, *ptr;
} bf;
void bf_init(size_t initial_cap) {
bf.buffer_size = initial_cap;
bf.buffer = calloc(initial_cap, sizeof (char));
bf.ptr = bf.buffer;
}
void bf_realloc(void) {
if ((size_t)(bf.ptr - bf.buffer) >= bf.buffer_size)
bf.buffer = realloc(bf.buffer,
(size_t) (bf.buffer_size *= 1.5) * sizeof (char));
}
void bf_parse(const char *code) {
for (size_t i = 0;; i++) {
switch (code[i]) {
case '>':
++bf.ptr;
bf_realloc();
break;
case '<':
--bf.ptr;
break;
case '-':
--*bf.ptr;
break;
case '+':
++*bf.ptr;
break;
case '.':
fputc(*bf.ptr, stdout);
break;
case ',':
*bf.ptr = fgetc(stdin);
break;
case '[':
while (*bf.ptr)
bf_parse(code + i + 1);
for (size_t depth = 0; code[i] != '\0'; i++) {
if (code[i] == '[') {
depth++;
} else if (code[i] == ']' && --depth == 0) {
break;
}
}
break;
case ']':
case '\0':
return;
}
}
}
static char *read_file(FILE *fp) {
size_t cap = 4096, len = 0;
char *data = malloc(cap * sizeof (char));
while (!feof(fp)) {
data[len] = fgetc(fp);
if (++len == cap)
data = realloc(data, (cap *= 2) * sizeof (char));
}
data = realloc(data, (len + 1) * sizeof (char));
data[len-1] = '\0';
return data;
}
int main(int argc, char **argv) {
if (argc == 2) {
bf_init(4096);
FILE *fp = fopen(argv[1], "rb");
if (fp == NULL) {
fputs("error opening file for reading\n", stderr);
exit(-1);
}
char *input = read_file(fp);
bf_parse(input);
fclose(fp);
free(input);
free(bf.buffer);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment