自家製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