Execute Brain****/C: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
Line 225: Line 225:
#include <stdlib.h>
#include <stdlib.h>
#include <string.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) {
void bf_run(char *s) {
int len = strlen(s), d = 0;
int len = strlen(s), d = 0;
char *tape = calloc(len, sizeof(char));
char *tape = calloc(len, sizeof(char));
int brack = 0;
for (; d >= 0 && *s; s++) {
for (; d >= 0 && *s; s++) {
if (*s == '[') { //if there is a loop
if (*s == '[') {
char *p = ++s;
char *p = ++s;
while(*p != ']') { //take care of the loop part
while(*p != ']') {
int c = *p;
int c = *p;
switch(c) {
switch(c) {
Line 243: Line 266:
case '.': putchar(tape[d]); break;
case '.': putchar(tape[d]); break;
case ',': tape[d] = getchar(); break;
case ',': tape[d] = getchar(); break;
case '[': p = nested_loop(p, tape, d); break;
default: break;
default: break;
}
}

p++;
p++;
if(*p == ']' && tape[d] != 0) p = s; //the loop stops when the cell has value equal to 0
if(*p == ']' && tape[d] != 0) p = s;
}
}
s = p + 1;
s = p + 1;
}
}

Revision as of 16:01, 29 April 2015

Execute Brain****/C is an implementation of Brainf***. Other implementations of Brainf***.
Execute Brain****/C is part of RCBF. You may find other members of RCBF at Category:RCBF.

Version 1

This example is incorrect. Please fix the code and remove this message.

Details: This version is not standard C; C does not allow nested functions

Simple BF engine with infinite tape support. <lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. 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;

  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()); } 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

This example is incorrect. It does not accomplish the given task. Please fix the code and remove this message.

The below Hello World fails.

    >++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.>
    >+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++.

<lang c>#include <stdio.h>

  1. include <string.h>
  2. 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>

  1. include <stdlib.h>
  2. 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>