Wiki内検索
最近更新したページ
最新コメント
メニューバー
ここは自由に編集できるエリアです。
タグ
カテゴリー

自家製Brainf*ckインタプリタ

/* bfi.c - Dec 2, 2007 by naoya_t - you can use this source under GPLv2 */

#include <stdio.h>
#include <stdlib.h>

#include <termios.h>

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
  if (argc == 1) {
    printf("usage: %s <program-file>\n", argv[0]);
    exit(0);
  }

  struct termios oldt, newt;
  tcgetattr( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr( STDIN_FILENO, TCSANOW, &newt );

  int i, j;

  int fd = open(argv[1], O_RDONLY);
  struct stat fs;
  fstat(fd, &fs);
  int size = fs.st_size;
  char *src = (char *)calloc(1, size);
  if (src == NULL) {
    printf("cannot allocate source memory (%d bytes).\n", size);
    exit(0);
  }
  read(fd, src, size);
  close(fd);

  unsigned short ix = 0;
  unsigned char st[30000];
  for (i=0; i<30000; i++) st[i] = 0;
 
  int loop_st[1024], loop_skip[30000];
  int l, level = 0;

  for (i=0; i<size; i++) {
    switch (src[i]) {
    case '>':
      ix++;
      break;
    case '<':
      ix--;
      break;
    case '+':
      st[ix]++;
      break;
    case '-':
      st[ix]--;
      break;
    case '.':
      putchar(st[ix]);
      break;
    case ',':
      st[ix] = getchar();
      break;
    case '[':
      if (st[ix] == 0) {
        if (loop_skip[i])
          i = loop_skip[i];
        else {
          l = 1;
          for (j=i+1; j<size; j++) {
            if (src[j] == '[') l++;
            else if (src[j] == ']') l--;
            if (l == 0) break;
          }
          loop_skip[i] = j;
          i = j;
        }
      } else {
        loop_st[level++] = i;
      }
      break;
    case ']':
      i = loop_st[--level] - 1;
      break;
    default:
      break;
    }
  }

  free((void *)src);
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
}
2007年12月02日(日) 03:32:35 Modified by naoya_t




スマートフォン版で見る