initial commit
[bf.git] / bf.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4
5 struct nest {
6 long pos;
7 struct nest *next;
8 };
9
10 int main(int argc, char *argv[])
11 {
12 size_t offset, stacksize = 1;
13 char *b = malloc(stacksize);
14 b[0] = 0;
15 char *ptr = b;
16 struct nest *t, *callstack = NULL;
17 FILE *in;
18
19 if(argc != 2){
20 fprintf(stderr, "Usage: %s PROGRAM\n", argv[0]);
21 return EXIT_FAILURE;
22 }
23
24 if((in = fopen(argv[1], "r")) == NULL){
25 perror("fopen");
26 return EXIT_FAILURE;
27 }
28
29 while(1){
30 switch(fgetc(in)){
31 case EOF:
32 return EXIT_SUCCESS;
33 case '>':
34 ++ptr;
35 if(ptr > b+stacksize){
36 offset = ptr-b;
37 b = realloc(b, stacksize *= 2);
38 ptr = b+offset;
39 memset(ptr, 0, stacksize/2);
40 }
41 break;
42 case '<':
43 if(ptr == b){
44 fprintf(stderr, "There is no stack position -1...\n");
45 return EXIT_FAILURE;
46 }
47 --ptr;
48 break;
49 case '+':
50 ++*ptr;
51 break;
52 case '-':
53 --*ptr;
54 break;
55 case '.':
56 putchar(*ptr);
57 break;
58 case ',':
59 *ptr = getchar();
60 break;
61 case '[':
62 if(*ptr){
63 t = callstack;
64 callstack = malloc(sizeof(struct nest));
65 callstack->next = t;
66 if((callstack->pos = ftell(in)) == -1){
67 perror("ftell");
68 return EXIT_FAILURE;
69 }
70 } else {
71 while(fgetc(in) != ']');
72 }
73 break;
74 case ']':
75 if(fseek(in, callstack->pos-1, SEEK_SET) == -1){
76 perror("fseek");
77 return EXIT_FAILURE;
78 }
79 t = callstack;
80 callstack = callstack->next;
81 free(t);
82 break;
83 default:
84 break;
85 }
86 }
87 }