Interpreter now accepts bf-code as a file
This commit is contained in:
7
Makefile
7
Makefile
@@ -1,5 +1,5 @@
|
|||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS=-std=c99 -Wall -O2 -static
|
CFLAGS=-std=c99 -Wall -O2 -static -g
|
||||||
CLIBS=-lm
|
CLIBS=-lm
|
||||||
PRGNAME=bfckr
|
PRGNAME=bfckr
|
||||||
CFILES=$(shell find . -name '*.c')
|
CFILES=$(shell find . -name '*.c')
|
||||||
@@ -7,8 +7,7 @@ HFILES=$(shell find . -name '*.h')
|
|||||||
STYLE=astyle --style=1tbs
|
STYLE=astyle --style=1tbs
|
||||||
RUN=valgrind --leak-check=full
|
RUN=valgrind --leak-check=full
|
||||||
DEBUG=gdb --args
|
DEBUG=gdb --args
|
||||||
ARGS="++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
|
ARGS="examples/hello.bf"
|
||||||
|
|
||||||
|
|
||||||
all: build run
|
all: build run
|
||||||
|
|
||||||
@@ -23,4 +22,4 @@ run:
|
|||||||
memtest:
|
memtest:
|
||||||
$(RUN) ./$(PRGNAME) $(ARGS)
|
$(RUN) ./$(PRGNAME) $(ARGS)
|
||||||
debug:
|
debug:
|
||||||
$(DEBUG) ./$(PRGNAME)
|
$(DEBUG) ./$(PRGNAME) $(ARGS)
|
||||||
|
|||||||
81
bfckr.c
81
bfckr.c
@@ -15,10 +15,11 @@
|
|||||||
|
|
||||||
// Amount of memory on the band tape
|
// Amount of memory on the band tape
|
||||||
#define MEMORY_SIZE 10000
|
#define MEMORY_SIZE 10000
|
||||||
|
#define MAX_INPUT_SIZE 1000
|
||||||
|
|
||||||
// Memory initialized with zeros and its pointer
|
// Memory initialized with zeros and its pointer
|
||||||
uint8_t memory[MEMORY_SIZE] = {0};
|
char memory[MEMORY_SIZE] = {0};
|
||||||
uint8_t *p = memory;
|
char *p = memory;
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
void bfuck_parser(char *input);
|
void bfuck_parser(char *input);
|
||||||
@@ -38,65 +39,56 @@ void die(const char *message)
|
|||||||
// Parses and executes a brainfuck expression
|
// Parses and executes a brainfuck expression
|
||||||
void bfuck_parser(char *input)
|
void bfuck_parser(char *input)
|
||||||
{
|
{
|
||||||
char curr;
|
for(size_t i = 0; input[i] != 0; i++) { // where i is the instruction pointer
|
||||||
uint16_t loop;
|
switch(input[i]) {
|
||||||
|
|
||||||
for(uint16_t i = 0; input[i] != 0; i++) {
|
|
||||||
curr = input[i];
|
|
||||||
|
|
||||||
switch(curr) {
|
|
||||||
case '>':
|
case '>':
|
||||||
++p;
|
++p; // increment data pointer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
--p;
|
--p; // decrement data pointer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '+':
|
case '+':
|
||||||
++*p;
|
++(*p); // increment byte at data pointer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
--*p;
|
--(*p); // decrement byte at data pointer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
putchar(*p);
|
putchar(*p); // output the byte at data pointer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
*p = getchar();
|
*p = getchar(); // accept one byte of input and store it at data pointer
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[':
|
case '[':
|
||||||
continue;
|
if(*p == 0) { // if the byte at the data pointer is zero
|
||||||
|
// jump forward to the command after the next ]
|
||||||
|
while(input[i] != ']') {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continue; // increment instruction pointer
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ']':
|
case ']':
|
||||||
if(*p) {
|
if(*p != 0) { // if the byte at the data pointer is nonzero
|
||||||
loop = 1;
|
// jump back to the command after the previous [
|
||||||
while(loop) {
|
while(input[i] != '[') {
|
||||||
curr = input[--i];
|
i--;
|
||||||
if(curr == '[') {
|
|
||||||
loop--;
|
|
||||||
}
|
}
|
||||||
if(curr == ']') {
|
} else {
|
||||||
loop++;
|
continue; // increment instruction pointer
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ' ':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\n':
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("%c", *p);
|
// Do nothing
|
||||||
die("Invalid operant!");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,11 +96,30 @@ void bfuck_parser(char *input)
|
|||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int i = 0;
|
||||||
|
int c;
|
||||||
|
char input[MAX_INPUT_SIZE];
|
||||||
|
|
||||||
|
// check arguments
|
||||||
if(argc < 2) {
|
if(argc < 2) {
|
||||||
die("Need more arguments.");
|
die("Need more arguments.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bfuck_parser(argv[1]);
|
// try to open file
|
||||||
|
if((fp = fopen(argv[1], "rt")) == NULL) {
|
||||||
|
die("Couldn't open file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the whole file and store it in the input buffer
|
||||||
|
while((c = getc(fp)) != EOF) {
|
||||||
|
input[i++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to interpret it
|
||||||
|
bfuck_parser(input);
|
||||||
|
|
||||||
|
// close and exit
|
||||||
|
fclose(fp);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|||||||
1
examples/fibonacci.bf
Normal file
1
examples/fibonacci.bf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
+++++++++++>+>>>>++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++ ++++++++++++++<<<<<<[>[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<[>++++++++++[ -<-[>>+>+<<<-]>>>[<<<+>>>-]+<[>[-]<[-]]>[<<[>>>+<<<-]>>[-]]<<]>>>[>>+>+<<<-]>>>[ <<<+>>>-]+<[>[-]<[-]]>[<<+>>[-]]<<<<<<<]>>>>>[++++++++++++++++++++++++++++++++++ ++++++++++++++.[-]]++++++++++<[->-<]>+++++++++++++++++++++++++++++++++++++++++++ +++++.[-]<<<<<<<<<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<-[>>.>.<<<[-]]<<[>>+>+<<<-]>> >[<<<+>>>-]<<[<+>-]>[<+>-]<<<-]
|
||||||
1
examples/hello.bf
Normal file
1
examples/hello.bf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
|
||||||
8
examples/rot13.bf
Normal file
8
examples/rot13.bf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
+[,+[-[>+>+<<-]>[<+>-]+>>++++++++[<-------->-]<-[<[-]>>>+[<+<+>>-]<[>+<-]<[<++>
|
||||||
|
>>+[<+<->>-]<[>+<-]]>[<]<]>>[-]<<<[[-]<[>>+>+<<<-]>>[<<+>>-]>>++++++++[<-------
|
||||||
|
->-]<->>++++[<++++++++>-]<-<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<<<<+>>>>++++[<++++++++
|
||||||
|
>-]>-]<<-<-]>[<<<<[-]>>>>[<<<<->>>>-]]<<++++[<<++++++++>>-]<<-[>>+>+<<<-]>>[<<+
|
||||||
|
>>-]+>>+++++[<----->-]<-[<[-]>>>+[<+<->>-]<[>+<-]<[<++>>>+[<+<+>>-]<[>+<-]]>[<]
|
||||||
|
<]>>[-]<<<[[-]<<[>>+>+<<<-]>>[<<+>>-]+>------------[<[-]>>>+[<+<->>-]<[>+<-]<[<
|
||||||
|
++>>>+[<+<+>>-]<[>+<-]]>[<]<]>>[-]<<<<<------------->>[[-]+++++[<<+++++>>-]<<+>
|
||||||
|
>]<[>++++[<<++++++++>>-]<-]>]<[-]++++++++[<++++++++>-]<+>]<.[-]+>>+<]>[[-]<]<]
|
||||||
10
examples/test.bf
Normal file
10
examples/test.bf
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
> +++++ +++++ +++++ (15 digits)
|
||||||
|
|
||||||
|
[<+>>>>>>>>++++++++++<<<<<<<-]>+++++[<+++++++++>-]+>>>>>>+[<<+++[>>[-<]<[>]<-]>>
|
||||||
|
[>+>]<[<]>]>[[->>>>+<<<<]>>>+++>-]<[<<<<]<<<<<<<<+[->>>>>>>>>>>>[<+[->>>>+<<<<]>
|
||||||
|
>>>>]<<<<[>>>>>[<<<<+>>>>-]<<<<<-[<<++++++++++>>-]>>>[<<[<+<<+>>>-]<[>+<-]<++<<+
|
||||||
|
>>>>>>-]<<[-]<<-<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+<<<-[>>+<<-]<]<<<<+>>>>>>>
|
||||||
|
>[-]>[<<<+>>>-]<<++++++++++<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+>[<<+<+>>>-]<<<
|
||||||
|
<+<+>>[-[-[-[-[-[-[-[-[-<->[-<+<->>]]]]]]]]]]<[+++++[<<<++++++++<++++++++>>>>-]<
|
||||||
|
<<<+<->>>>[>+<<<+++++++++<->>>-]<<<<<[>>+<<-]+<[->-<]>[>>.<<<<[+.[-]]>>-]>[>>.<<
|
||||||
|
-]>[-]>[-]>>>[>>[<<<<<<<<+>>>>>>>>-]<<-]]>>[-]<<<[-]<<<<<<<<]++++++++++.
|
||||||
Reference in New Issue
Block a user