-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbrainfuck.c
145 lines (133 loc) · 3.95 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* Name: Brainfuck Interpreter in C
* Repository: https://github.com/BaseMax/BrainfuckInterpreterC
* Author: Max Base
* Date: 2022/09/17
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* read_file(char* file_path)
{
char* data = NULL;
FILE* file = fopen(file_path, "r");
if (file == NULL) {
return NULL;
}
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
rewind(file);
data = malloc(file_size + 1);
fread(data, file_size, 1, file);
data[file_size] = '\0';
fclose(file);
return data;
}
char* interpret(char* bf)
{
// > Move the pointer to the right
// < Move the pointer to the left
// + Increment the memory cell at the pointer
// - Decrement the memory cell at the pointer
// . Output the character signified by the cell at the pointer
// , Input a character and store it in the cell at the pointer
// [ Jump past the matching ] if the cell at the pointer is 0
// ] Jump back to the matching [ if the cell at the pointer is nonzero
// All characters other than ><+-.,[] should be considered comments and ignored. But, see extensions below.
char* output = malloc(30000);
// initialize memory
int memory[30000];
// initialize pointer
int pointer = 0;
// initialize output
int output_pointer = 0;
// loop through input
int i = 0;
while (i < strlen(bf)) {
// > Move the pointer to the right
if (bf[i] == '>') {
pointer += 1;
}
// < Move the pointer to the left
else if (bf[i] == '<') {
pointer -= 1;
}
// + Increment the memory cell at the pointer
else if (bf[i] == '+') {
memory[pointer] += 1;
}
// - Decrement the memory cell at the pointer
else if (bf[i] == '-') {
memory[pointer] -= 1;
}
// . Output the character signified by the cell at the pointer
else if (bf[i] == '.') {
output[output_pointer] = memory[pointer];
output_pointer += 1;
}
// , Input a character and store it in the cell at the pointer
else if (bf[i] == ',') {
memory[pointer] = getchar();
}
// [ Jump past the matching ] if the cell at the pointer is 0
else if (bf[i] == '[') {
if (memory[pointer] == 0) {
// find matching ]
int count = 1;
while (count > 0) {
i += 1;
if (bf[i] == '[') {
count += 1;
}
else if (bf[i] == ']') {
count -= 1;
}
}
}
}
// ] Jump back to the matching [ if the cell at the pointer is nonzero
else if (bf[i] == ']') {
if (memory[pointer] != 0) {
// find matching [
int count = 1;
while (count > 0) {
i -= 1;
if (bf[i] == ']') {
count += 1;
}
else if (bf[i] == '[') {
count -= 1;
}
}
}
}
else {
// pass
}
i += 1;
}
// add \0 to output
output[output_pointer] = '\0';
return output;
}
int main(int argc, char** argv)
{
if (argc < 2) {
printf("Usage: %s <file>", argv[0]);
return 1;
}
else {
char* code = read_file(argv[1]);
if (code == NULL) {
printf("File not found");
return 1;
}
else {
char* result = interpret(code);
printf("%s", result);
free(code);
free(result);
}
}
return 0;
}