diff options
Diffstat (limited to 'userspace/brainfuck.c')
| -rw-r--r-- | userspace/brainfuck.c | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/userspace/brainfuck.c b/userspace/brainfuck.c new file mode 100644 index 0000000..03ce4f5 --- /dev/null +++ b/userspace/brainfuck.c @@ -0,0 +1,133 @@ +// taken from: http://it-ride.blogspot.com/2009/11/brainfuck-interpreter.html + +/* comment + * TODO + * You have a bug. You don't check for EOF while looking for square brackets. + */ + +/* + + 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! + +*/ + +// ADDED BY FOOLOS : foolos syscalls! +#include "syscalls.c" + +#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) { + + // ADDED BY FOOLOS: we will show usage anyway + usage(); + + // 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; +} |
