Execute Brain****/C
Version 1
Simple BF engine with infinite tape support. <lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
void bf_run(char *s) { int len = 1, d = 0; char *tape = calloc(len, 1);
int run(int skip) { for (; d >= 0 && *s; s++) { if (d >= len) { tape = realloc(tape, len * 2); memset(tape + len, 0, len); len = len * 2; }
if (*s == ']') return tape[d]; if (*s == '[') { char *p = ++s; while (run(!tape[d])) s = p; continue; }
if (skip) continue;
- define CASE(a, b) if (*s == a) { b; continue; }
CASE('+', tape[d]++); CASE('-', tape[d]--); CASE('>', d++); CASE('<', d--); CASE('.', putchar(tape[d])); CASE(',', tape[d] = getchar()); } return 0; }
run(0); free(tape); }
int main(void) { bf_run( "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++.." "+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.");
return 0; }</lang>
This is a simple function that will run Brain**** code. The code can be fed from a file or anything else. Here it's entered directly (it reverses a string you type).
Version 2
The below Hello World fails.
>++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.> >+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++.
<lang c>#include <stdio.h>
- include <string.h>
- include <stdlib.h>
//Making it easier to understand. All for you guys <3 enum retval_enum{INIT_ERROR_VALUES, INIT_ERROR_MEMORY, RUN_ERROR_BOUNDARIES, ENDLOOP_MISSING, STARTLOOP_MISSING, FINISHED};
//The function to execute the Brainf*** code enum retval_enum runCode(char *code, int cellnum);
int main(int argc, char **argv)
{
printf("Running code\n\n");
//Run some code to test. I think this is a Hello World program. The code can be read from a file or whatever else is wanted
unsigned int stat = runCode(",----------[++++++++++>,----------]<[.<]+++++++++++++.---.", 1000); printf("\n\nDone running code\n"); switch(stat) { case INIT_ERROR_VALUES: printf("Error initializing values.\n"); //Some jerk set the number of cells to 0 break;
case INIT_ERROR_MEMORY: printf("Not enough memory.\n"); //Not enough memory to allocate an array of chars with length cellnum break;
case RUN_ERROR_BOUNDARIES: printf("Boundary error in BF prog\n"); //Whilst running, the cell iterator got below 0 or over cellnum. ie. not enough cells break;
case STARTLOOP_MISSING: printf("Error in code. Start loop missing\n"); //An endloop was found without a startloop break;
case ENDLOOP_MISSING: printf("Error in code. End loop missing\n"); //A Startloop was found without an endloop break;
case FINISHED: printf("Finished with no problems\n"); //Code finished without any probs break; };
return 0; }
enum retval_enum runCode(char *code, int cellnum) { //Returns with enum on failure if(cellnum==0) return INIT_ERROR_VALUES;
//Allocate memory for cells unsigned char *p_cells = 0; p_cells = (unsigned char*) malloc(cellnum); if(p_cells == 0) return INIT_ERROR_MEMORY;
int cell_iter = 0; int code_len = strlen(code); int code_iter = 0;
//iter is changed according to code while(code_iter < code_len) { switch(code[code_iter]) { case '+': //Just increase. If it overflows, it'll become 0 p_cells[cell_iter]++; break;
case '-': //"Underflowing" will cause it to be max(int) p_cells[cell_iter]--; break;
case '>': //Move pointer and check boundaries cell_iter++; if(cell_iter == cellnum) { free(p_cells); return RUN_ERROR_BOUNDARIES; } break;
case '<': //Move pointer and check boundaries cell_iter--; if(cell_iter<0) { free(p_cells); return RUN_ERROR_BOUNDARIES; } break;
case '.': //Output current cell putchar(p_cells[cell_iter]); break;
case ',': //Grab 1 char input p_cells[cell_iter]=getchar(); break;
case '[': //If current cell is 0, run to the next ']' if(p_cells[cell_iter]==0) while(code[code_iter]!=']') { code_iter++; if(code_iter>=code_len) { free(p_cells); return ENDLOOP_MISSING; } } break;
case ']': //Run all the way back before the last '[' while(code[code_iter]!='[') { code_iter--; if(code_iter<0) { free(p_cells); return STARTLOOP_MISSING; } } code_iter--; break;
default: //It's not a relevant char, ignore it. break; }; code_iter++; };
//Just clean up free(p_cells);
//We are done. Give an awesome goodness signal back! return FINISHED; } </lang>
Version 3
The below Hello World fails.
>++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.> >+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++.
This is a modified code of Version 1. It happens to be Standard C.
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <string.h>
char *nested_loop (char *s, char *tape, int d) { char *p = ++s; while(*p != ']') { int c = *p; switch(c) { case '+': tape[d]++; break; case '-': tape[d]--; break; case '>': d++; break; case '<': d--; break; case '.': putchar(tape[d]); break; case ',': tape[d] = getchar(); break; case '[': p = nested_loop(p, tape, d); break; default: break; } p++;
if(*p == ']' && tape[d] != 0) p = s; }
return p; }
void bf_run(char *s) { int len = strlen(s), d = 0; char *tape = calloc(len, sizeof(char)); int brack = 0;
for (; d >= 0 && *s; s++) { if (*s == '[') { char *p = ++s;
while(*p != ']') { int c = *p; switch(c) { case '+': tape[d]++; break; case '-': tape[d]--; break; case '>': d++; break; case '<': d--; break; case '.': putchar(tape[d]); break; case ',': tape[d] = getchar(); break; case '[': p = nested_loop(p, tape, d); break; default: break; }
p++;
if(*p == ']' && tape[d] != 0) p = s; } s = p + 1; }
#define CASE(a, b) if (*s == a) { b; continue; } CASE('+', tape[d]++); CASE('-', tape[d]--); CASE('>', d++); CASE('<', d--); CASE('.', putchar(tape[d])); CASE(',', tape[d] = getchar()); }
free(tape); }
int main(void) { bf_run("--------[-->+++<]>.------------.---.--[--->+<]>-.----[->++++<]>+.++++." "------------.------.++++++++.-[++>---<]>+.[->+++<]>++.[--->+<]>----.---." "++++++++.---------.-[->+++++<]>-.++[->+++<]>.+++++++++.+++++++++.[---->+<]" ">++.-[--->++<]>.+++++++++++.--------.+++.+++.+[---->+<]>+++.+++++[->+++<]>" ".+++++++.+[->+++<]>.+++++++++++++.[-->+++++<]>+++.---[->++++<]>.----------" "--.---.--[--->+<]>-.++[--->++<]>.-----------.+[----->+<]>.-.-[---->+<]>++." "+[->+++<]>+.+++++++++++.--------.--[->+++<]>-.,"); //the quick brown fox jumps over the lazy dog.
return 0; } </lang>