Earlier this year I was playing around with making simple programming languages and came across “BrainFuck”. I, being bored decided to write my own BrainFuck Interpreter and of course made a few changes along the way (only in I/O functions, added integer support since BrainFuck only deals with characters). If interested, I recommend reading more information about BrainFuck on Wikipedia.
The Full download including Source and examples can be found HERE.
Here are the basic rules of BrainFuck with some added I/O Functions.
| brainfuck command | C equivalent |
|---|---|
| > | ++CP; |
| < | –CP; |
| + | ++*CP; |
| - | –*CP; |
| [ | while (*CP) { |
| ] | } |
| c | printf(“%c”,(char)*CP) |
| d | printf(“%u”,*CP); |
| C | while (scanf(“%c”, CP) != 1); |
| D | while (scanf(“%u”, CP) != 1); |
| M | Print out Cell and Pointers |
| I | Print out Instruction Pointer |
CP is the Cell Pointer
Below are various scripts written in BrainFuck
Hello World
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | +++++ +++++ [ > +++++ ++ > +++++ +++++ > +++ > + <<<< - ] > ++ c > + c +++++ ++ c c +++ c > ++ c << +++++ +++++ +++++ c > c +++ c ----- - c ----- --- c > + c > c M |
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 | +++++ [ > +++++ +++++ +++ < - ] +++++ +++++ [ >> +++++ ++++ << - ] >> +++++ ++ < +++++ ++ c ----- -- > ++++ c +++++ ++ cc +++ c ----- ----- ---- << +++ [ >>> +++++ +++++ <<< - ] >>> ++ c << +++++ +++++ +++++ +++++ ++ c ----- ----- ----- ----- -- > +++++ +++++ ++++ c +++ c ------ c -------- c --- > + c M |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | +++ M [ > +++ [ > +++ [ - M ] < - ] < - ] M |
Below is the source for the BrainFuck Interpreter
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | #include <stdio.h> #include <stdlib.h> #define DEFAULT_IN_FILE "in.bf" #define DEFAULT_MEMORY_SIZE 8 char inFile[256] = DEFAULT_IN_FILE; /* function definitions */ void runInstructions(); int loadFile(char inFile[256]); void printInstructions(); void clearDataBuffer(); void printDataBuffer(); unsigned int* cell; /* cell buffer, all program cell is stored in here */ unsigned int cellSize = 0; unsigned int IP; // instruction pointer unsigned char* instructions; /* the Instructions loaded from input file */ unsigned int instructionsSize = 0; unsigned int* CP = NULL; /* cell Pointer */ int main(int argc, char *argv[]) { int i; for(i = 1; i < argc; i++) { /* handle parameters */ if(strcmp(argv[i], "-i") == 0) { /* input file */ if( i + 1 < argc) { sprintf(inFile, "%s", argv[i + 1]); } else { /* improper format */ return -1; } } else if(strcmp(argv[i], "-size") == 0) { /* size of cell buffer */ if( i + 1 < argc) { cell = (unsigned int*) malloc( atoi(argv[i + 1]) * sizeof(unsigned int) ); cellSize = atoi(argv[i + 1]); } else { /* improper format */ return -1; } } } if(cellSize == 0) { cell = (unsigned int*) malloc( DEFAULT_MEMORY_SIZE * sizeof(unsigned int) ); cellSize = DEFAULT_MEMORY_SIZE; } CP = cell; loadFile(inFile); clearDataBuffer(); runInstructions(); return 0; } void runInstructions() { int i; // used in for loops int numCloseBrackets = 0; int numOpenBrackets = 0; for(IP = 0; IP < instructionsSize; IP++) { switch(instructions[IP]) { case '>': /* INC/DEC */ ++CP; break; case '<': --CP; break; case '+': /* INC/DEC POINTER */ ++(*CP); break; case '-': --(*CP); break; case '[': /* WHILE LOOP */ if(*CP == 0) { // if CP == 0, then skip to the next matching ']' numOpenBrackets = 0; for(i = IP + 1; i < instructionsSize; i++) { if(instructions[i] == '[') { numOpenBrackets++; } else if(instructions[i] == ']') { if(numOpenBrackets == 0) { IP = i; break; } else { numOpenBrackets--; } } } } break; case ']': /* END WHILE*/ if(*CP != 0) { // if CP != 0, loopback to the previous matching'[' numCloseBrackets = 0; for(i = IP - 1; i >= 0; i--) { if(instructions[i] == ']') { numCloseBrackets++; }else if(instructions[i] == '[') { if(numCloseBrackets == 0) { IP = i; break; } else { numCloseBrackets--; } } } } break; case 'c': /* OUTPUT */ printf("%c",(char)*CP); break; case 'd': printf("%u",*CP); break; case 'C': /* INPUT */ while (scanf("%c", CP) != 1); break; case 'D': while (scanf("%u", CP) != 1); break; case 'M': /* print Data Buffer */ printDataBuffer(); break; case 'I': /* print Instructions as is*/ printInstructions(); break; default: /* unknown command, ignore it */ break; } } } /* * */ int loadFile(char inFile[256]) { FILE *fp; fp=fopen(inFile, "r"); if(fp == NULL) { return -1; } fseek(fp, 0, SEEK_END); // seek to end of file instructionsSize = ftell(fp); // get current file pointer rewind (fp); instructions = (char*) malloc( instructionsSize ); int i; for(i = 0; i < instructionsSize; i++) { instructions[i] = ' '; } if(instructions == NULL) { return -1; } fread (instructions,1,instructionsSize,fp); fclose(fp); return 0; } void printInstructions() { int i; for(i = 0; i < instructionsSize; i++) { printf("%c", instructions[i]); } printf("\n"); } void clearDataBuffer() { int i; for(i = 0; i < cellSize; i++) { cell[i] = 0; } } void printDataBuffer() { int i; printf("\n"); for(i = 0; i < cellSize; i++) { printf("[%d]=%d", i, cell[i]); if(CP == &cell[i]) { printf(" <-- (CP)"); } printf("\n"); } printf("\nIP = %d\n", IP); } |

Posted in
Tags: 
