Execute Brain****/C: Difference between revisions
Oops, this is incorrect too. |
No edit summary |
||
Line 216: | Line 216: | ||
//We are done. Give an awesome goodness signal back! |
//We are done. Give an awesome goodness signal back! |
||
return FINISHED; |
return FINISHED; |
||
} |
|||
</lang> |
|||
==Version 3== |
|||
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> |
|||
void bf_run(char *s) { |
|||
int len = strlen(s), d = 0; |
|||
char *tape = calloc(len, sizeof(char)); |
|||
for (; d >= 0 && *s; s++) { |
|||
if (*s == '[') { //if there is a loop |
|||
char *p = ++s; |
|||
while(*p != ']') { //take care of the loop part |
|||
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; |
|||
default: break; |
|||
} |
|||
p++; |
|||
if(*p == ']' && tape[d] != 0) p = s; //the loop stops when the cell has value equal to 0 |
|||
} |
|||
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> |
</lang> |
Revision as of 15:02, 28 April 2015
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
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>
void bf_run(char *s) { int len = strlen(s), d = 0; char *tape = calloc(len, sizeof(char));
for (; d >= 0 && *s; s++) { if (*s == '[') { //if there is a loop char *p = ++s;
while(*p != ']') { //take care of the loop part 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; default: break; } p++;
if(*p == ']' && tape[d] != 0) p = s; //the loop stops when the cell has value equal to 0 }
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>