#include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd; struct stat sb; char *code; unsigned int pc = 0; unsigned int idx = 0, size = 1; int *data = calloc(size, sizeof(int)); if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(EXIT_FAILURE); } if ((fd = open(argv[1], O_RDONLY)) == -1 || fstat(fd, &sb) == -1) { perror("Error opening file"); exit(EXIT_FAILURE); } if (!S_ISREG(sb.st_mode)) { fprintf(stderr, "%s is not a file\n", argv[1]); exit(EXIT_FAILURE); } if ((code = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { perror("Error mapping file into memory"); exit(EXIT_FAILURE); } close(fd); for (pc = 0; pc < sb.st_size; pc++) { switch (code[pc]) { case '>': idx++; if (idx == size) { unsigned int old = size; int *ptr = data; size += old; if ((data = realloc(ptr, size * sizeof(int))) == NULL) { perror("Out of memory"); exit(EXIT_FAILURE); } else memset(data + old, 0, (size - old) * sizeof(int)); } break; case '<': idx--; break; case '+': data[idx]++; break; case '-': data[idx]--; break; case '.': putchar(data[idx]); break; case ',': data[idx] = getchar(); break; case '[': if (data[idx] == 0) { int b = 0; for (unsigned int i = pc + 1; i < sb.st_size; i++) { if (code[i] == ']') { if (b == 0) { pc = i; break; } b--; } else if (code[i] == '[') b++; } } break; case ']': if (data[idx] != 0) { int b = 0; for (unsigned int i = pc - 1; i > 0; i--) { if (code[i] == '[') { if (b == 0) { pc = i; break; } b--; } else if (code[i] == ']') b++; } } break; default: break; } } free(data); munmap(code, sb.st_size); return EXIT_SUCCESS; }