From: Mart Lubbers Date: Thu, 25 Aug 2016 13:20:17 +0000 (+0200) Subject: initial commit X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=54568c8a5460925bf9201d0252915288d88ac4bb;p=bf.git initial commit --- 54568c8a5460925bf9201d0252915288d88ac4bb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..292a768 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a8f241a --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +PROGRAM:=bf +CFLAGS:=-Wall -Werror -g + +all: $(PROGRAM) + +clean: + $(RM) -v $(PROGRAM) diff --git a/bf.c b/bf.c new file mode 100644 index 0000000..c095176 --- /dev/null +++ b/bf.c @@ -0,0 +1,87 @@ +#include +#include +#include + +struct nest { + long pos; + struct nest *next; +}; + +int main(int argc, char *argv[]) +{ + size_t offset, stacksize = 1; + char *b = malloc(stacksize); + b[0] = 0; + char *ptr = b; + struct nest *t, *callstack = NULL; + FILE *in; + + if(argc != 2){ + fprintf(stderr, "Usage: %s PROGRAM\n", argv[0]); + return EXIT_FAILURE; + } + + if((in = fopen(argv[1], "r")) == NULL){ + perror("fopen"); + return EXIT_FAILURE; + } + + while(1){ + switch(fgetc(in)){ + case EOF: + return EXIT_SUCCESS; + case '>': + ++ptr; + if(ptr > b+stacksize){ + offset = ptr-b; + b = realloc(b, stacksize *= 2); + ptr = b+offset; + memset(ptr, 0, stacksize/2); + } + break; + case '<': + if(ptr == b){ + fprintf(stderr, "There is no stack position -1...\n"); + return EXIT_FAILURE; + } + --ptr; + break; + case '+': + ++*ptr; + break; + case '-': + --*ptr; + break; + case '.': + putchar(*ptr); + break; + case ',': + *ptr = getchar(); + break; + case '[': + if(*ptr){ + t = callstack; + callstack = malloc(sizeof(struct nest)); + callstack->next = t; + if((callstack->pos = ftell(in)) == -1){ + perror("ftell"); + return EXIT_FAILURE; + } + } else { + while(fgetc(in) != ']'); + } + break; + case ']': + if(fseek(in, callstack->pos-1, SEEK_SET) == -1){ + perror("fseek"); + return EXIT_FAILURE; + } + t = callstack; + callstack = callstack->next; + free(t); + break; + default: + break; + } + } +}