#include #include #include static unsigned char *data_start; static unsigned char *data_ptr; void process_command(char command, FILE *file) { switch(command) { case '>': /* increment the data pointer (to point to the next cell to the right). */ ++data_ptr; /* TODO : Check if over allocated memory */ break; case '<': /* decrement the data pointer (to point to the next cell to the left). */ --data_ptr; /* TODO : Check if under allocated memory */ break; case '+': /* increment (increase by one) the byte at the data pointer. */ ++*data_ptr; break; case '-': /* decrement (decrease by one) the byte at the data pointer. */ --*data_ptr; break; case '.': /* output a character, the ASCII value of which being the byte at the * data pointer. */ putchar(*data_ptr); break; case ',': /* accept one byte of input, storing its value in the byte at the data * pointer. */ *data_ptr = getchar(); break; case '[': /* [ : if the byte at the data pointer is zero, then instead of moving the * instruction pointer forward to the next command, jump it forward to * the command after the matching ] command. * ] : if the byte at the data pointer is nonzero, then instead of moving * the instruction pointer forward to the next command, jump it back to * the command after the matching [ command. */ { fpos_t position; fgetpos(file, &position); while(*data_ptr != 0) { fsetpos(file, &position); char c = getc(file); while( c!= ']' && c != EOF) { process_command(c, file); c = getc(file); } } } break; case ']': /* if we encounter one here, it means there are not balanced */ fprintf(stderr, "Error in the source file, unbalanced ']'\n"); exit(2); break; default: /* Brainfuck ignores all characters except the eight commands +-<>[],. */ break; } } int main(int argc, char **argv) { data_start = calloc(30000, sizeof(char)); data_ptr = data_start; if (argc > 1) { char command; FILE *file = fopen(argv[1], "r"); if (!file) { fprintf(stderr, "Error: No such file %s\n", argv[1]); return 2; } while((command = getc(file)) != EOF) { process_command(command, file); } fclose(file); return 0; } else { fprintf(stderr, "Usage: %s source_file\n", argv[0]); return 1; } return 0; }