This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
brainfuck-toys/bf_threaded.c

127 lines
2.5 KiB
C

#include <stdio.h>
#include <error.h>
#include <stdlib.h>
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;
}