2012年5月4日金曜日

bf処理系、インタプリタなC言語バージョン

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

時系列的にはpythonのあと、rubyの前に書いている

include 
#include 
#include 


/*
 *  http://en.wikipedia.org/wiki/Brainfuck
 */

char* helloworld = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.";
char* helloworld_expected = "Hello World!\n";


/* 
 *  http://codegolf.com/competition/run/8/2
 */

char* another = 
  "+++[>+++++<-]>[>+>+++>+>++>+++++>++<[++<]>---]>->-.[>++>+<<--]>--.--.+.>>>++.<<"
  ".<------.+.+++++.>>-.<++++.<--.>>>.<<---.<.-->-.>+.[+++++.---<]>>[.--->]<<.<+.+"
  "+.++>+++[.<][.]<++.";
char* another_expected = "Just another brainfuck hacker.";


char memory[30000];
char *data = memory;
char *tape= 0;

char* bf(char* p, int run){
  char* r;
  char* start;

  //printf("%p, %i\n", p, run);

  while (*p){
    //printf("%i, %i, %i, %i, %i\n", memory[0], memory[1], memory[2], memory[3], memory[4]);
    //printf("%s\n", p);
    switch (*p){
      case '>':
        /* increment the data pointer (to point to the next cell to the right). */
        if(run){
          data++;
        }
        break;

      case '<':
        /* decrement the data pointer (to point to the next cell to the left). */
        if(run){
          data--; }
        break;

      case '+':
        /* increment (increase by one) the byte at the data pointer. */
        if(run){
          (*data)+=1;
        }
        break;

      case '-':
        /* decrement (decrease by one) the byte at the data pointer. */
        if(run){
          (*data)-=1;
        }
        break;
        
      case '.':
        /* output the byte at the data pointer as an ASCII encoded character.*/
        if(run){
          printf("%c", *data);
        }
        break;

      case ',':
        /* accept one byte of input, storing its value in the byte at the data pointer. */
        /* not implemented */
        if(run){
        }
        break;

      case '[':
        /* if the byte at the data pointer is zero, jump it forward to the command after the matching ] command*. */
        if (*data && run){
          start = p;
          assert(*start=='[');
          r = bf(p+1, 1);
          if(!r){
            r = start - 1; /* rewind, ajust against p++ */
          }
        }else{
          r = bf(p+1, 0); /* skip to ] */
          //printf("skipped to '%s'\n", r);
        }
        p = r;
        break;

      case ']':
        /* if the byte at the data pointer is nonzero, jump it back to the command after the matching [ command*.*/
        /* ==> */
        /* if the byte at the data pointer is zero, moving the instruction pointer forward */
        /* ==> */
        /* just rewind */
        if(run){
          return (char*)0;
        }else{
          return p;
        }
      default:
        break;
    };
    p++;
  };
  return (char*)0;
}


int main(arg, argv){
  //bf(helloworld, 1);
  bf(another, 1);
  return 0;
}
    

0 件のコメント: