commit b18854c74f2d46daa165d68338f70aa72050c6e0 Author: Anthony Debucquoy Date: Thu Oct 26 14:15:26 2023 +0200 First finished version diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a57f52c --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +.PHONY: clean, mrproper +CC = gcc +CFLAGS = -g -Wall + +all: main + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +main: main.o + $(CC) $(CFLAGS) -o $@ $+ + +clean: + rm -f *.o core.* + +mrproper: clean + rm -f main + +run: main + ./$< ./hello_world.bf diff --git a/README.md b/README.md new file mode 100644 index 0000000..4e5c877 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# BFF + +BFF (BrainFuck Fucker) is a really simple [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck#Language_design) interpreter in c + +## Usage + +``` +$ make +$ ./bff +``` + +## TODO + +- [ ] Faster loops by keeping the position of the previous '[' or ']' + +## Resources + +- The wikipedia's BrainFuck Design Language: [https://en.wikipedia.org/wiki/Brainfuck#Language_design](https://en.wikipedia.org/wiki/Brainfuck#Language_design) diff --git a/hello_world.bf b/hello_world.bf new file mode 100644 index 0000000..a5b4314 --- /dev/null +++ b/hello_world.bf @@ -0,0 +1,28 @@ ++++++ +++ +[ + >++++ + [ + >++ + >+++ + >+++ + >+ + <<<<- + ] + >+ + >+ + >- + >>+ + [<] + + <- +] + +>>. +>---. ++++++ ++..+++. +>>. +<-. +<. ++++.----- -.----- ---. +>>+. +>++. diff --git a/main.c b/main.c new file mode 100644 index 0000000..e8275d8 --- /dev/null +++ b/main.c @@ -0,0 +1,74 @@ +#include +#include +#include + +#define MEMORY_SIZE 30000 + +int main(int argc, char *argv[]) +{ + int c = 0; + argv++; // Program name + + while(--argc){ + const char *filename = *argv++; + char *memory = calloc(1, MEMORY_SIZE), *pointer = memory; + + FILE *fd = fopen(filename, "r"); + assert(fd); + + fseek(fd, 0, SEEK_END); + int file_size = ftell(fd); + rewind(fd); + + char* file_pointer = malloc(file_size+1), *file_cnt = file_pointer; + fread(file_pointer, 1, file_size, fd); + file_cnt[file_size] = 0; + fclose(fd); + + for(;*file_cnt != '\0'; file_cnt++){ + switch (*file_cnt) { + case '>': // Increment the data pointer by one (to point to the next cell to the right). + pointer++; + break; + case '<': // Decrement the data pointer by one (to point to the next cell to the left). + pointer--; + break; + case '+': // Increment the byte at the data pointer by one. + (*pointer)++; + break; + case '-': // Decrement the byte at the data pointer by one. + (*pointer)--; + break; + case '.': // Output the byte at the data pointer. + printf("%c", *pointer); + break; + case ',': // Accept one byte of input, storing its value in the byte at the data pointer. + scanf("%c", pointer); + 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(*pointer == 0) + while(*++file_cnt != ']' || c != 0){ + if(*file_cnt == '[') + c++; + else if(*file_cnt == ']') + c--; + } + break; + case ']': // 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. + if(*pointer != 0) + while(*--file_cnt != '[' || c != 0){ + if(*file_cnt == ']') + c++; + else if(*file_cnt == '[') + c--; + } + break; + default: + break; + } + } + free(memory); + free(file_pointer); + } + return 0; +}