From fd8ef0fd42490779a7f082bc778afdfac77a7a9c Mon Sep 17 00:00:00 2001 From: xanxys Date: Mon, 12 May 2014 00:14:14 +0900 Subject: [PATCH] Rewrite bfi in C++ for future optimization. --- bfi/conv | 2 +- bfi/main.c | 105 --------------------------------------------------- bfi/main.cpp | 79 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 106 deletions(-) delete mode 100644 bfi/main.c create mode 100644 bfi/main.cpp diff --git a/bfi/conv b/bfi/conv index c504796..5b7c4b6 100755 --- a/bfi/conv +++ b/bfi/conv @@ -1,3 +1,3 @@ #!/bin/env sh -gcc -O3 main.c -o bfi +g++ -std=c++11 -O3 main.cpp -o bfi diff --git a/bfi/main.c b/bfi/main.c deleted file mode 100644 index def1b09..0000000 --- a/bfi/main.c +++ /dev/null @@ -1,105 +0,0 @@ -#include -#include - -#define MEM_SIZE (20*1000*1000) // 20MB - - -void run(FILE *log,char *code){ - char *code_base=code; - - unsigned char *ptr_base=malloc(MEM_SIZE); - memset(ptr_base,0,MEM_SIZE); - - unsigned char *ptr=ptr_base; - - long long stp=0; - while(*code){ - /* - if(log) - fprintf(log,"%c %d %d\n",*code,code-code_base,ptr-ptr_base); - */ - stp++; - switch(*code){ - case '>': ++ptr; break; - case '<': --ptr; break; - case '+': ++*ptr; break; - case '-': --*ptr; break; - case '.': fwrite(ptr,1,1,stdout); break; - case ',': fread(ptr,1,1,stdin); break; - case '[': - if(*ptr==0){ - int c=1; - while(c>0){ - code++; - if(*code=='[') c++; - if(*code==']') c--; - } - } - break; - case ']': - if(*ptr!=0){ - int c=1; - while(c>0){ - code--; - if(*code==']') c++; - if(*code=='[') c--; - } - } - default: - stp--; - } - - code++; - } - fprintf(stderr,"%lld steps\n",stp); - - free(ptr_base); -} - -int main(int argc,char **argv){ - if(argc!=2 && argc!=3){ - printf("usage: bfi (compiled with MEM_SIZE=%d)\n",MEM_SIZE); - printf("usage: bfi (compiled with MEM_SIZE=%d)\n",MEM_SIZE); - return -1; - } - - // open - FILE *fp=fopen(argv[1],"r"); - if(fp==NULL){ - printf("could not open %s\n",argv[1]); - return -2; - } - - fseek(fp,0,SEEK_END); - int size=ftell(fp); - fseek(fp,0,SEEK_SET); - - char *code=malloc(size+1); - fread(code,size,1,fp); - code[size]=0; - - // close - fclose(fp); - - setbuf(stdin,NULL); - setbuf(stdout,NULL); - fflush(stdin); - fflush(stdout); - - // open optional log file - FILE *log=NULL; - if(argc==3){ - log=fopen(argv[2],"w"); - if(log==NULL){ - printf("could not open %s\n",argv[2]); - return -2; - } - } - - run(log,code); - free(code); - if(log) fclose(log); - - return 0; -} - diff --git a/bfi/main.cpp b/bfi/main.cpp new file mode 100644 index 0000000..6f1b73b --- /dev/null +++ b/bfi/main.cpp @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include + +// 20MB +const int MEM_SIZE = 20*1000*1000; + + +void run(const std::string& code_memory) { + std::vector data_memory(MEM_SIZE, 0); + + unsigned char* ptr = data_memory.data(); + const char* ptr_program = code_memory.data(); + const char* const ptr_program_end = code_memory.data() + code_memory.size(); + + uint64_t steps = 0; + while(ptr_program < ptr_program_end) { + steps++; + switch(*ptr_program){ + case '>': ++ptr; break; + case '<': --ptr; break; + case '+': ++*ptr; break; + case '-': --*ptr; break; + case '.': std::cout << std::unitbuf << *ptr; break; + // TODO: do disable stdin buffering. + case ',': *ptr = std::cin.get(); break; + case '[': + if(*ptr==0){ + int c=1; + while(c>0){ + ptr_program++; + if(*ptr_program=='[') c++; + if(*ptr_program==']') c--; + } + } + break; + case ']': + if(*ptr!=0){ + int c=1; + while(c>0){ + ptr_program--; + if(*ptr_program==']') c++; + if(*ptr_program=='[') c--; + } + } + default: + steps--; + } + + ptr_program++; + } + std::cerr << steps << " steps" << std::endl; +} + +int main(int argc, char** argv) { + // Parse argument + if(argc != 2) { + std::cout << "bfi (compiled with MEM_SIZE=" << MEM_SIZE << ")" << std::endl; + std::cout << "usage: bfi " << std::endl; + return -1; + } + const std::string bf_code_path(argv[1]); + + // Read bf code. + std::ifstream bf_code_file(bf_code_path); + if(!bf_code_file.is_open()) { + std::cout << "could not open " << bf_code_path << std::endl; + return -2; + } + + const std::string bf_code( + (std::istreambuf_iterator(bf_code_file)), + std::istreambuf_iterator()); + + run(bf_code); + return 0; +}