/*
A brainfuck intepreter written in C, complete with error checking so you
don't hurt yourself while, uh, brainfucking. Nothing really special about
the implementation and it is probably very poor performance-wise.
Author: Felix Oghină
License: (brain)fuck licenses!
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// by brainfuck standards (doesn't that sound funny?), the data pointer has
// 30,000 bytes at its disposal, but I hate hard-coding such stuff.
#define DATA_SIZE 30000
void usage() {
puts(
"Usage: brainfuck FILE\n"
"If FILE is ommited or is '-', standard input is read"
);
}
int main(int argc, char **argv) {
// used by the bf program
unsigned char *dataptr = malloc(sizeof(char) * DATA_SIZE);
// position of the data pointer
unsigned int datapos = 0;
// input file
FILE *input;
// level - deepness of brackets
// i - uh, you need explanation for this one?
unsigned int level, i;
// we will read chars from the input into r
unsigned char r;
// determine input
if (argc == 2) {
if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) {
usage();
return EXIT_SUCCESS;
}
else {
input = fopen(argv[1], "r");
if (input == NULL) {
puts("Error opening input file");
return EXIT_FAILURE;
}
}
}
else {
usage();
return EXIT_FAILURE;
}
// zero the data pointer
for (i=0; i < DATA_SIZE; i++) {
dataptr[i] = 0;
}
// start interpreting
rewind(input);
while (!feof(input)) {
r = (unsigned char) fgetc(input);
switch(r) {
case '>':
if (datapos < DATA_SIZE - 1) datapos++;
else {
puts("brainfuck error: pointer overflow");
return EXIT_FAILURE;
}
break;
case '<':
if (datapos > 0) datapos--;
else {
puts("brainfuck error: pointer underflow");
return EXIT_FAILURE;
}
break;
case '+':
dataptr[datapos]++;
break;
case '-':
dataptr[datapos]--;
break;
case '.':
putchar(dataptr[datapos]);
break;
case ',':
dataptr[datapos] = getchar();
break;
case '[':
if (dataptr[datapos] == 0) {
level = 1;
while (level != 0) {
r = (unsigned char) fgetc(input);
if (r == '[') level ++;
else if (r == ']') level --;
}
}
break;
case ']':
if (dataptr[datapos] != 0) {
level = 1;
while (level != 0) {
fseek(input, -2, SEEK_CUR);
r = (unsigned char) fgetc(input);
if (r == ']') level ++;
else if (r == '[') level --;
}
}
break;
}
}
return EXIT_SUCCESS;
}
Syntax Highlighting by Pygmentool
Download the source codeWell, guess it's time to fill up that swear jar now.
You have a bug. You don't check for EOF while looking for square brackets.
ReplyDelete