Brainfuck Interpreter in C
A dead simple brainfuck interpreter in C, it was posted here first.
bfi.c
:
1 #include <stdio.h> 2 #ifndef codesize 3 #define codesize 30000 4 #endif 5 6 #define cellsize 30000 7 8 const char *s_name = 9 " bfi" 10 #if codesize != 30000 11 "%d" 12 #endif 13 " - brainf*ck language interpreter 1.0 build - "__DATE__"\n" 14 #if codesize != 30000 15 " **** Special version with %d code array in size ****\n" 16 #endif 17 " ----- copyright (c) 2005 by 8pm@baidu.cbar\n"; 18 const char *s_license = 19 " This program is free software; you can redistribute it and/or modify\n" 20 " it under the terms of the GNU General Public License as published by\n" 21 " the Free Software Foundation; either version 2 of the License, or\n" 22 " (at your option) any later version.\n" 23 "\n" 24 " This program is distributed in the hope that it will be useful,\n" 25 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 26 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 27 " GNU General Public License for more details.\n" 28 "\n" 29 " You should have received a copy of the GNU General Public License\n" 30 " along with this program; if not, write to the\n" 31 " Free Software Foundation, Inc.,\n" 32 " 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n" 33 "\n" 34 " usage: $ %s [source code]\n" 35 "\n"; 36 37 const char *s_err_open = 38 "[] error: unable to open file %s\n"; 39 const char *s_err_ovfl = 40 "[] error: unable to run, program too large.\n"; 41 const char *s_err_unmt = 42 "[] error: unmatch %c in source file.\n"; 43 44 char cell[cellsize], code[codesize]; 45 int n = 0, ip = 0, dp = 0; 46 47 int load_program(FILE *fp, const int size) 48 { 49 int br = 0, p = 0; 50 while (!feof(fp)) 51 switch (n = fgetc(fp)) { 52 case '[': br += 2; 53 case ']': --br; 54 case '>': 55 case '<': 56 case '+': 57 case '-': 58 case '.': 59 case ',': 60 code[p++] = n; 61 if (p == size-1) 62 return -1; /* program too large */ 63 } 64 code[p] = '\0'; 65 return br ? (br > 0) ? -2 /* unmatch [ */ : -3 /* unmatch ] */ : 0; 66 } 67 68 int main(int argc, char **argv) 69 { 70 FILE *fp = NULL; 71 if (1 == argc) { 72 #if codesize != 30000 73 fprintf(stderr, s_name, codesize/1000, codesize); 74 #else 75 fprintf(stderr, s_name); 76 #endif 77 fprintf(stderr, s_license, argv[0]); 78 return 0; 79 } 80 if (NULL == (fp=fopen(argv[1],"r"))) { 81 fprintf(stderr, s_err_open, argv[1]); 82 return -1; 83 } 84 n = load_program(fp, codesize); 85 if (fp != stdin) fclose(fp); 86 switch (n) { 87 case -1: /* program too large */ 88 fprintf(stderr, s_err_ovfl); 89 return -1; 90 case -2: /* unmatch [ */ 91 fprintf(stderr, s_err_unmt, '['); 92 return -2; 93 case -3: /* unmatch ] */ 94 fprintf(stderr, s_err_unmt, ']'); 95 return -3; 96 } 97 n = ip = dp = 0; 98 do { 99 n = 1; 100 switch (code[ip]) { 101 case '>': ++dp == cellsize ? dp = 0: 0; break; 102 case '<': --dp == -1 ? dp += cellsize: 0; break; 103 case '+': cell[dp]++; break; 104 case '-': cell[dp]--; break; 105 case '.': putchar(cell[dp]); fflush(stdout); break; 106 case ',': cell[dp] = getchar(); break; 107 case '[': 108 if (!cell[dp]) 109 while (n) 110 switch (code[++ip]) { 111 case '[': n++; break; 112 case ']': n--; break; 113 } 114 break; 115 case ']': 116 if (cell[dp]) 117 while (n) 118 switch (code[--ip]) { 119 case ']': n++; break; 120 case '[': n--; break; 121 } 122 break; 123 } 124 } while (code[++ip]); 125 return 0; 126 }