diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | bf.c | 19 | ||||
-rw-r--r-- | hello.bf | 43 |
5 files changed, 82 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..28151d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +bf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4e10a2a --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +bf: bf.c + $(CC) -O3 -Wall -Wextra -std=c89 -Wpedantic -o $@ $< + +clean: + rm -f bf @@ -1,2 +1,15 @@ # bf A very small Brainfuck interpreter + +To build, simply run make. + +Running the interpreter is simple: + + $ ./bf input.bf + +The interpreter purposely does no error checking. If you don't specify an +input file, it will crash. If there is an error reading the input file, it +will crash. + +Program size is fixed at the same size as data space, which is controlled by +`#define S`. @@ -0,0 +1,19 @@ +#include <stdio.h> +#define S (1<<16) +#define I a[1] +#define D a[0] +#define C case +#define B break +static char d[S], p[S]; +int main(int i, char *a[]) { + fread(p, 1, S, fopen(I, "r")); + for (D = d, I = p; I < p + S; I++) { + switch (i = *I) { + C '[': C ']': for (i = '\\' - *I; i < 0 ? *D : !*D; i += *(I += i > 0 ? 1 : -1) == '[' ? 1 : *I == ']' ? -1 : 0); B; + C '+': C '-': *D -= i - ','; B; + C '<': C '>': D += i - '='; B; + C ',': *D = getchar(); B; + C '.': putchar(*D); B; + } + } +} diff --git a/hello.bf b/hello.bf new file mode 100644 index 0000000..df6f0a2 --- /dev/null +++ b/hello.bf @@ -0,0 +1,43 @@ +[ This program prints "Hello World!" and a newline to the screen, its + length is 106 active command characters. [It is not the shortest.] + + This loop is an "initial comment loop", a simple way of adding a comment + to a BF program such that you don't have to worry about any command + characters. Any ".", ",", "+", "-", "<" and ">" characters are simply + ignored, the "[" and "]" characters just have to be balanced. This + loop and the commands it contains are ignored because the current cell + defaults to a value of 0; the 0 value causes this loop to be skipped. +] +++++++++ Set Cell #0 to 8 +[ + >++++ Add 4 to Cell #1; this will always set Cell #1 to 4 + [ as the cell will be cleared by the loop + >++ Add 2 to Cell #2 + >+++ Add 3 to Cell #3 + >+++ Add 3 to Cell #4 + >+ Add 1 to Cell #5 + <<<<- Decrement the loop counter in Cell #1 + ] Loop till Cell #1 is zero; number of iterations is 4 + >+ Add 1 to Cell #2 + >+ Add 1 to Cell #3 + >- Subtract 1 from Cell #4 + >>+ Add 1 to Cell #6 + [<] Move back to the first zero cell you find; this will + be Cell #1 which was cleared by the previous loop + <- Decrement the loop Counter in Cell #0 +] Loop till Cell #0 is zero; number of iterations is 8 + +The result of this is: +Cell No : 0 1 2 3 4 5 6 +Contents: 0 0 72 104 88 32 8 +Pointer : ^ + +>>. Cell #2 has value 72 which is 'H' +>---. Subtract 3 from Cell #3 to get 101 which is 'e' ++++++++..+++. Likewise for 'llo' from Cell #3 +>>. Cell #5 is 32 for the space +<-. Subtract 1 from Cell #4 for 87 to give a 'W' +<. Cell #3 was set to 'o' from the end of 'Hello' ++++.------.--------. Cell #3 for 'rl' and 'd' +>>+. Add 1 to Cell #5 gives us an exclamation point +>++. And finally a newline from Cell #6 |