#include #include #include static unsigned char *data_start; static unsigned char *data_ptr; #define MEM_SIZE 30000 #define GOTO_NEXT goto *labels[op_char] void engine_run(FILE* file) { void** labels[127]; /* We will address each char */ unsigned char op_char = 0; fpos_t* loop_start_position = calloc(3000,sizeof(fpos_t)); for (int i = 0; i <= 127; i++) labels[i] = &&unknown_char; labels['>'] = &&ptr_increment; labels['<'] = &&ptr_decrement; labels['+'] = &&value_increment; labels['-'] = &&value_decrement; labels['.'] = &&value_output; labels[','] = &&value_input; labels['['] = &&loop_start; labels[']'] = &&loop_end; op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; ptr_increment: { if (data_ptr + 1 > data_start + MEM_SIZE) data_ptr = data_start; ++data_ptr; op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } ptr_decrement: { if (data_ptr - 1 < data_start) data_ptr = data_start + MEM_SIZE; --data_ptr; op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } value_increment: { ++*data_ptr; op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } value_decrement: { --*data_ptr; op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } value_output: { putchar(*data_ptr); op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } value_input: { *data_ptr = getchar(); op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } loop_start: { fgetpos(file, loop_start_position); loop_start_position++; op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } loop_end: { if (*data_ptr != 0) { fsetpos(file, loop_start_position-1); } else { loop_start_position--; } op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } unknown_char: { op_char = getc(file); if (op_char > 127) return; GOTO_NEXT; } } int main(int argc, char **argv) { data_start = calloc(MEM_SIZE, sizeof(char)); data_ptr = data_start; if (argc <= 1) { fprintf(stderr, "Usage: %s source_file\n", argv[0]); return 1; } FILE *file = fopen(argv[1], "r"); if (!file) { fprintf(stderr, "Error: No such file %s\n", argv[1]); return 2; } engine_run(file); fclose(file); return 0; }