First finished version
This commit is contained in:
commit
b18854c74f
20
Makefile
Normal file
20
Makefile
Normal file
@ -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
|
18
README.md
Normal file
18
README.md
Normal file
@ -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 <program.bf>
|
||||
```
|
||||
|
||||
## 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)
|
28
hello_world.bf
Normal file
28
hello_world.bf
Normal file
@ -0,0 +1,28 @@
|
||||
+++++ +++
|
||||
[
|
||||
>++++
|
||||
[
|
||||
>++
|
||||
>+++
|
||||
>+++
|
||||
>+
|
||||
<<<<-
|
||||
]
|
||||
>+
|
||||
>+
|
||||
>-
|
||||
>>+
|
||||
[<]
|
||||
|
||||
<-
|
||||
]
|
||||
|
||||
>>.
|
||||
>---.
|
||||
+++++ ++..+++.
|
||||
>>.
|
||||
<-.
|
||||
<.
|
||||
+++.----- -.----- ---.
|
||||
>>+.
|
||||
>++.
|
74
main.c
Normal file
74
main.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user