-
Notifications
You must be signed in to change notification settings - Fork 0
/
brainfuck.cpp
118 lines (118 loc) · 2.32 KB
/
brainfuck.cpp
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
114
115
116
117
118
#include <cstdio>
struct Node {
unsigned char data;
Node *pre, *next;
Node(unsigned char d = 0, Node *p = nullptr, Node *n = nullptr) {
data = d;
pre = p;
next = n;
}
} * memory, *source;
Node *left(Node **nd) {
if ((*nd)->pre != nullptr) (*nd) = (*nd)->pre;
return *nd;
}
Node *right(Node **nd) {
if ((*nd)->next == nullptr) {
Node *t = new Node;
(*nd)->next = t;
t->pre = *nd;
}
(*nd) = (*nd)->next;
return *nd;
}
int init_code(FILE *code) {
char c;
source = new Node;
while (true) {
bool flag = 1;
do {
const char *cmd = "+-<>,.[]";
c = fgetc(code);
if (c == EOF) break;
for (int idx = 0; idx < 8; idx++)
if (c == cmd[idx]) {
flag = 0;
break;
}
} while (flag);
if (c == EOF) break;
right(&source);
source->data = c;
}
while (source->data)
left(&source);
return 0;
}
int run() {
bool err = 0;
memory = new Node;
while (1) {
if (source->next == nullptr) break;
right(&source);
char c = source->data;
switch (c) {
case '+':
memory->data++;
break;
case '-':
memory->data--;
break;
case '<':
if (memory->pre == nullptr) {
err = 1;
break;
}
left(&memory);
break;
case '>':
right(&memory);
break;
case ',':
memory->data = getchar();
break;
case '.':
putchar(memory->data);
break;
case '[':
if (memory->data == 0) {
int le = 1;
while (source->next != nullptr) {
right(&source);
if (source->data == '[') le++;
if (source->data == ']') le--;
if (!le) break;
}
if (le) err = 1;
}
break;
case ']':
if (memory->data) {
int ri = 1;
while (source->pre != nullptr) {
left(&source);
if (source->data == '[') ri--;
if (source->data == ']') ri++;
if (!ri) break;
}
if (ri) err = 1;
}
break;
default:
break;
}
if (err) break;
}
if (err) {
puts("Runtime Error!");
return -1;
}
return 0;
}
int main(const int argc, const char **argv) {
FILE *code;
if (argc != 2) return -1;
code = fopen(argv[1], "r");
if (code == nullptr) return -1;
return init_code(code) + run();
}