Execute Brain**** is an implementation of Brainf***.
Other implementations of Brainf***.
RCBF is a set of Brainf*** compilers and interpreters written for Rosetta Code in a variety of languages.

Below are links to each of the versions of RCBF.

An implementation need only properly implement the following instructions:



Command

Description


 > 
 Move the pointer to the right


 < 
 Move the pointer to the left


 + 
 Increment the memory cell under the pointer


 - 
 Decrement the memory cell under the pointer


 . 
 Output the character signified by the cell at the pointer


 , 
 Input a character and store it in the cell at the pointer


 [ 
 Jump past the matching ] if the cell under the pointer is 0


 ] 
 Jump back to the matching [ if the cell under the pointer is nonzero

Any cell size is allowed,   EOF   (End-O-File)   support is optional, as is whether you have bounded or unbounded memory.




 
/*
  BFC.COM
  BrainF**k's Pseudo-compiler!
  Mr_Dalien. NOV 26, 2021
*/
#include <hopper.h>
 
#proto checkMove(_S_,_OPE_,_CODE_,_BF_)
#proto check(_S_,_OPE_,_CODE_,_BF_)
#proto tabulation(_S_)
 
main:
 
  total arg,minus(1) zero?
  do {
      {"\LR","Bad filename!\OFF\n"}print
      {0}return
  }
  filename = [&2]    // get filename parameter 2 (parameter 1 is "bfc.com")
 
  sf="",{filename}exist?,not,
  do{
      {"File: \LR",filename,"\OFF"," don't exist!\n"}print
      {0}return
  }
  {filename}load string(sf)   // load file as string
  --sf                        // "load string" load adding a newline at the EOS. "--sf" delete it!
 
  // determine tape size:
  rightMove=0,{">",sf}count at, mov(rightMove)
  leftMove=0,{"<",sf}count at, mov(leftMove)
  totalCells = 0
  prec(0)   // precision 0 decimals: all number are integers!
  {0}{rightMove}minus(leftMove), cpy(totalCells),lt?
  do{
      {"In file \LR",filename,"\OFF",": program bad formed!\n"}print
      {0}return
  }
 
  // start process!
  nLen=0, {sf}len,mov(nLen)
 
  i=1,       // index
  res={},    // new file "C"
  space=5    // tab space
  // header:
  {"#include <stdio.h>","int main(){","     int ptr=0, i=0, cell["},{totalCells},xtostr,cat,{"];"}cat,push all(res)
  {"     for( i=0; i<",totalCells},xtostr,cat,{"; ++i) cell[i]=0;"}cat,push(res)
 
  iwhile={},swOk=0,true(swOk)
  cntMove=0
  v=""
  __PRINCIPAL__:
     [i:i]get(sf),mov(v),
     switch(v)
        case(">")::do{ 
           _checkMove(">","+","ptr",sf), 
           _tabulation(space),{"if(ptr>="}cat,{totalCells},xtostr,cat
                              {") perror(\"Program pointer overflow\");"}cat,push(res),
           exit
        }
        case("<")::do{
           _checkMove("<","-","ptr",sf), 
           _tabulation(space),{"if(ptr<0) perror(\"Program pointer underflow\");"}cat,push(res),
           exit
        }
        case("+")::do{
           _check("+","+","cell[ptr]",sf), exit
        }
        case("-")::do{
           _check("-","-","cell[ptr]",sf), exit
        }
        case("[")::do{
           {"]"}push(iwhile)
           _tabulation(space),{"while(cell[ptr])"}cat,push(res),
           _tabulation(space),{"{"}cat,push(res)
           space += 5
           exit
        }
        case("]")::do{
           try
               pop(iwhile),kill
               space -= 5, _tabulation(space),{"}"}cat,push(res)
           catch(e)
              {"SIMBOL: ",v,", POS: ",i,": \LR","Symbol out of context \OFF"}println
              false(swOk)
           finish
           exit
        }
        case(".")::do{
            _tabulation(space),{"putchar(cell[ptr]);"}cat,push(res)
            exit
        }
        case(",")::do{
            _tabulation(space),{"cell[ptr] = getc(stdin);"}cat,push(res)
            exit
        }
       // otherwise?
        {"WARNING! SIMBOL(ASCII): ",v}asc,{", POS: ",i,": \LY","Invalid code, is ommited!\OFF\n"}print
 
     end switch
     {cntMove}neg?    // exist more "<" than ">" ??
     do { 
        {"SIMBOL: ",v,", POS: ",i,": \LR","Underflow detected!\OFF\n"}print
        false(swOk)
     }
     ++i,{nLen,i}le?,{swOk},and,jt(__PRINCIPAL__)
 
  {swOk} do{
     _tabulation(space),{"return 0;"}cat,push(res)
     space -=5
     {"}"}push(res)
 
     name="",   {"",".bf",filename},transform,mov(name),  // bye bye ".bf"!
     cname="",  {name,".c"}cat,mov(cname),                // hello <filename>.c!
     {"\n"}tok sep                     // save array with newlines
     {res,cname},save                  // save the array into the <filename>.c" 
     {" "}tok sep                      // "join" need this!
     executable="",  {"gcc ",cname," -o ",name} join(executable)  // line to compile new filename
     {executable}execv                 // do compile c program generated!
 
     /* OPTIONAL: remove <filename>.c */
     // {"rm ",cname}cat,execv
  }
  {"\LG","Compilation terminated "}
  if({swOk}not)
     {"\LR","with errors!\OFF\n"}
  else
     {"successfully!\OFF\n"}
  end if
  print
exit(0)
 
.locals
checkMove(simb,operator,code,bfprg)
   c=1,
   {cntMove},iif({operator}eqto("+"),1,-1),add,mov(cntMove)
   __SUB_MOVE__:
      ++i,[i:i]get(sf),{simb}eq? 
      do{ ++c,
          {cntMove},iif({operator}eqto("+"),1,-1),add,mov(cntMove)
          jmp(__SUB_MOVE__)
      }
   _tabulation(space),{code}cat,{operator}cat,{"= "}cat,{c}xtostr,cat,{";"}cat
   push(res)
   --i
back
check(simb,operator,code,bfprg)
   c=1,
   __SUB__:
      ++i,[i:i]get(sf),{simb}eq? do{ ++c, jmp(__SUB__) }
   _tabulation(space),{code}cat,{operator}cat,{"= "}cat,{c}xtostr,cat,{";"}cat
   push(res)
   --i
back
tabulation(space)
   {" "}replyby(space)
back
 