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
|
/*
A brainfuck intepreter written in C, complete with error checking so you
don't hurt yourself while, uh, brainfucking. Nothing really special about
the implementation and it is probably very poor performance-wise.
Author: Felix Oghină
License: (brain)fuck licenses!
*/
// taken from: http://it-ride.blogspot.com/2009/11/brainfuck-interpreter.html
// and adapted for FoolOs by Miguel
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// by brainfuck standards (doesn't that sound funny?), the data pointer has
// 3,000 bytes at its disposal, but I hate hard-coding such stuff.
// FOOLOS: decreased to 3000 (from 30.000)
#define DATA_SIZE 3000
void usage(char *progname)
{
printf("Usage: %s [FILE]\n",progname);
}
int main(int argc, char **argv)
{
puts("\n\nbrainfuck: Welcome to the BRAINFUCK INTERPRETER by Felix Oghina");
puts("brainfuck: Licensed under the (brain)fuck licenses!");
puts("brainfuck: Adapted & Compiled for FoolOS by Miguel");
// used by the bf program
unsigned char *dataptr = malloc(sizeof(char) * DATA_SIZE);
// position of the data pointer
unsigned int datapos = 0;
// input file
FILE *input;
// level - deepness of brackets
// i - uh, you need explanation for this one?
unsigned int level, i;
// we will read chars from the input into r
unsigned char r;
// check argument count
if(argc!=2)
{
usage(argv[0]);
return EXIT_FAILURE;
}
// open brainfuck source
input = fopen(argv[1], "r");
if (input == NULL)
{
puts("Error opening input file");
return EXIT_FAILURE;
}
// zero the data pointer
for (i=0; i < DATA_SIZE; i++) {
dataptr[i] = 0;
}
// start interpreting
while (1) {
r = (unsigned char) fgetc(input);
switch(r) {
case 'X':
puts("END!");
return 0;
case '>':
if (datapos < DATA_SIZE - 1) datapos++;
else {
puts("brainfuck error: pointer overflow");
return EXIT_FAILURE;
}
break;
case '<':
if (datapos > 0) datapos--;
else {
puts("brainfuck error: pointer underflow");
return EXIT_FAILURE;
}
break;
case '+':
dataptr[datapos]++;
break;
case '-':
dataptr[datapos]--;
break;
case '.':
putchar(dataptr[datapos]);
break;
case ',':
dataptr[datapos] = getchar();
break;
case '[':
if (dataptr[datapos] == 0) {
level = 1;
while (level != 0) {
r = (unsigned char) fgetc(input);
if (r == '[') level ++;
else if (r == ']') level --;
}
}
break;
case ']':
if (dataptr[datapos] != 0) {
level = 1;
while (level != 0) {
//fseek(input, -2, SEEK_CUR);
_lseek(3,-2,SEEK_CUR);
r = (unsigned char) fgetc(input);
if (r == ']') level ++;
else if (r == '[') level --;
}
}
break;
}
}
return EXIT_SUCCESS;
}
|