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_interpreter.c

96 lines
2.8 KiB
C

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