-
Notifications
You must be signed in to change notification settings - Fork 35
/
brainfuck.c
113 lines (95 loc) · 2.47 KB
/
brainfuck.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
enum direction {
FWD,
BWD
};
char* find_match(char *src, char match, enum direction dir) {
char *aux = src;
int count = 1;
while (count) {
dir == FWD ? ++aux : --aux;
if (*aux == *src) ++count;
if (*aux == match) --count;
}
return aux;
}
void prepare_jumps(char *program, ssize_t prg_size, char *jump_map[]) {
char *aux = program;
while (aux < (program + prg_size)) {
switch(*aux) {
case '[':
jump_map[aux-program] = find_match(aux, ']', FWD);
break;
case ']':
jump_map[aux-program] = find_match(aux, '[', BWD);
break;
}
++aux;
}
}
ssize_t read_prg(char *buf, ssize_t buf_size, int fd) {
char *aux_ptr = buf;
ssize_t prg_size = 0,
aux_size = buf_size;
ssize_t ret = read(fd, aux_ptr, aux_size);
while (ret && (prg_size < buf_size)) {
aux_size -= ret;
prg_size += ret;
aux_ptr += ret;
ret = read(fd, aux_ptr, aux_size);
}
return prg_size;
}
int main(int argc, char *argv[])
{
char program[50000],
memory[30000];
char *jump_map[50000];
char *ip = program,
*ptr = memory;
int fd = 0;
ssize_t prg_size = 0;
if (argc < 2) {
fd = STDIN_FILENO;
} else {
fd = open(argv[1], O_RDONLY);
if(fd < 0){
fprintf(stderr, "Error opening %s!\n", argv[1]);
perror("open");
exit(1);
}
}
prg_size = read_prg(program, sizeof(program), fd);
prepare_jumps(program, prg_size, jump_map);
while (ip < (program + prg_size)) {
switch(*ip) {
case '>': ++ptr; break;
case '<': --ptr; break;
case '+': ++(*ptr); break;
case '-': --(*ptr); break;
case '.': putchar(*ptr);
fflush(stdout);
break;
case ',': *ptr = getchar();
if (*ptr == EOF) exit(0);
break;
case '[':
if (!*ptr) {
ip = jump_map[ip-program];
}
break;
case ']':
if (*ptr) {
ip = jump_map[ip-program];
}
break;
}
++ip;
}
return 0;
}