summaryrefslogtreecommitdiff
path: root/userspace/brainfuck.c
blob: c608064b559390b1346cd2b9029158e958465651 (plain)
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
/*
    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
#define BUF_SIZE 3000

int main(int argc, char **argv) 
{
    // if any arg than show info message
    if(argc>1)
    {
	puts("BRAINFUCK INTERPRETER by Felix Oghina");
	puts("Licensed under the (brain)fuck licenses!"); 
	puts("Adapted & Compiled for FoolOS by Miguel");
	puts("Reads stdin and write to stdout");
	return EXIT_SUCCESS;
    }

    // buffer input so we can seek
    unsigned char *prog= malloc(BUF_SIZE);
    unsigned char *progread= prog;
    unsigned int  progpos=0;


    // used by the bf program
    unsigned char *dataptr = calloc(1,sizeof(char) * DATA_SIZE);

    // position of the data pointer
    unsigned int datapos = 0;

    // input/output files
    FILE *input=stdin;
    FILE *output=stdout;

    while(1)
    {
	int l=fread(progread,1,255,input);
	if(l==0)break;
	progread+=l;
    }

    // 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;

    // start interpreting
    while (1) {

	r=prog[progpos++];
	if(r==0)break;

        switch(r) {
        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=prog[progpos++];
                    if (r == '[') level ++;
                    else if (r == ']') level --;
                }
            }
            break;
        case ']':
            if (dataptr[datapos] != 0) {
                level = 1;
                while (level != 0) {
		    progpos-=2;
		    r=prog[progpos++];
                    if (r == ']') level ++;
                    else if (r == '[') level --;
                }
            }
            break;
        }
    }

    return EXIT_SUCCESS;
}