Skip to content

Instantly share code, notes, and snippets.

@zanders3
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zanders3/2a6742b3af57e8a2ac88 to your computer and use it in GitHub Desktop.
Save zanders3/2a6742b3af57e8a2ac88 to your computer and use it in GitHub Desktop.
A BF interpreter in C with some dumb optimisations
//Compile with: gcc bf.c -o bf -O3 && ./bf mandelbrot.bf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int opCount(char** pt, char v) {
int opCount = 0;
char* p = *pt;
while (*(*pt) == v) {
opCount++;
(*pt)++;
}
(*pt)--;
return opCount;
}
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("Usage: bf <filename>\n");
return -1;
}
FILE* f = fopen(argv[1], "rb");
if (!f) {
printf("Failed to open file\n");
return -1;
}
fseek(f, 0, SEEK_END);
int len = ftell(f);
rewind(f);
char* program = malloc(sizeof(char)*len);
fread(program, 1, len, f);
fclose(f);
char* stack[256] = {0};
register int stackidx = 0;
char state[100000] = {0};
char* ptr = state;
for (char* p = program; *p; p++) {
//printf("%c %d %d\n", *p, (int)p - (int)program, (int)ptr - (int)state);
//getchar();
switch (*p) {
case '>':
ptr += opCount(&p, '>');
break;
case '<':
ptr -= opCount(&p, '<');
break;
case '+':
*ptr += opCount(&p, '+');
break;
case '-':
*ptr -= opCount(&p, '-');
break;
case '.':
putchar(*ptr);
break;
case ',':
*ptr = getchar();
break;
case '[':
if ((int)*ptr == 0) {
int bal = 0;
do {
if (*p == '[') bal++;
if (*p == ']') bal--;
p++;
} while(bal != 0);
p--;
} else {
stack[stackidx] = p;
stackidx++;
}
break;
case ']':
if ((int)*ptr != 0) {
p = stack[stackidx-1];
}
else {
stackidx--;
}
break;
}
}
free(program);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment