diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-08-13 18:30:01 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-08-13 18:30:01 +0200 |
commit | f30ff2240932d4d03984bd16cc8b9bb2b5427a53 (patch) | |
tree | 8dd7817c3e6d4c1a34f410f63be569fd16133081 | |
parent | daf7dfedf0593b562c5fb3e8a023ef6c3924bb86 (diff) |
Better error handling, flushing, optimisation
-rw-r--r-- | bfcomp.c | 96 | ||||
-rw-r--r-- | o.bf | 1 |
2 files changed, 79 insertions, 18 deletions
@@ -8,9 +8,13 @@ #define DBGTIME(tag,block) \ do { \ - clock_t start; \ + clock_t start=clock(); \ + DBGTIMESTART(start,tag,block); \ + } while(0) + +#define DBGTIMESTART(start,tag,block) \ + do { \ if(params.verbose){ \ - start=clock(); \ fprintf(stderr,"%s",(tag)); \ } \ {block} \ @@ -20,6 +24,11 @@ } while(0) +__attribute__((noreturn)) void outofmem(void){ + fprintf(stderr,"Memory allocation error!\n"); + exit(1); +} + int uniqid(void){ static int i=0; return i++; @@ -85,8 +94,12 @@ void parseargs(int argc,char **argv){ } int runcmd(const char *cmd/*,int in,int out*/){ + clock_t start=clock(); pid_t pid=fork(); - assert(pid>=0); + if(pid<0){ + fprintf(stderr,"Cannot fork!\n"); + exit(1); + } if(pid==0){ /*dup2(in,0); dup2(out,1);*/ @@ -94,7 +107,7 @@ int runcmd(const char *cmd/*,int in,int out*/){ __builtin_unreachable(); } else { int statloc; - DBGTIME(cmd,{ + DBGTIMESTART(start,cmd,{ while(true){ waitpid(pid,&statloc,0); if(WIFEXITED(statloc))break; @@ -107,16 +120,18 @@ int runcmd(const char *cmd/*,int in,int out*/){ FILE* gettempfilew(char name[20]){ memcpy(name,"/tmp/tmp.XXXXXXXXXX",20); int fd=mkstemp(name); - assert(fd>=0); + if(fd<0){ + fprintf(stderr,"Cannot create temp file!\n"); + exit(1); + } FILE *f=fdopen(fd,"w"); - assert(f); + if(!f)outofmem(); return f; } int compilechain(const char *asmfname,const char *dstfname){ char ofname[20]; FILE *f=gettempfilew(ofname); - if(params.verbose)fprintf(stderr,"o -> %s\n",ofname); assert(strlen(ofname)==19); fclose(f); char buf[25+19+1+strlen(asmfname)+1]; @@ -138,8 +153,11 @@ void writeprologue(FILE *asmf){ "extern _malloc\n" "extern _free\n" "extern _printf\n" + "extern _getchar\n" "extern _putchar\n" "extern _write\n" + "extern ___stdoutp\n" + "extern _fflush\n" "\n" "default rel\n" "\n" @@ -167,7 +185,6 @@ void writeprogram(char *source,FILE *asmf){ int i=0; do { char c=source[i]; - if(c&&strchr("+-><[].,",c)==NULL)continue; if(addc&&c!='+'&&c!='-'){ addc=(addc%256)+256%256; if(addc==1)fprintf(asmf,"\tinc byte [rbx] ; 1 +\n"); @@ -200,7 +217,7 @@ void writeprogram(char *source,FILE *asmf){ case '[':{ struct stackitem *ls=malloc(sizeof(struct stackitem)); - assert(ls); + if(!ls)outofmem(); ls->id=uniqid(); ls->next=loopstack; loopstack=ls; @@ -214,7 +231,10 @@ void writeprogram(char *source,FILE *asmf){ } case ']':{ - assert(loopstack); + if(!loopstack){ + fprintf(stderr,"Excess ']' in source\n"); + exit(1); + } fprintf(asmf, "\tcmp byte [rbx], 0 ; ]\n" "\tjnz loop%d_body\n" @@ -230,7 +250,9 @@ void writeprogram(char *source,FILE *asmf){ fprintf(asmf, "\tmov edi, 0 ; .\n" "\tmov dil, byte [rbx]\n" - "\tcall _putchar\n"); + "\tcall _putchar\n" + "\txor edi, edi\n" + "\tcall _fflush\n"); break; case ',': @@ -239,11 +261,18 @@ void writeprogram(char *source,FILE *asmf){ "\tmov byte [rbx], al\n"); break; + case '0': + fprintf(asmf,"\tmov byte [rbx], 0\n"); + break; + default: - if(c)assert(false); + if(c)assert(false); //should've been stripped } } while(source[i++]); - assert(!loopstack); + if(loopstack){ + fprintf(stderr,"Excess '[' in source\n"); + exit(1); + } } void writeepilogue(FILE *asmf){ @@ -280,11 +309,11 @@ void writeepilogue(FILE *asmf){ "\n" "nomemstr: db \"Out of memory!\"\n" ".len: equ $-nomemstr\n" - "\n" + /*"\n" "formatstr: db \"Last cell reached: %%d\", 10, 0\n" "\n" "align 8, db 0\n" - "maxp: dq 0\n" + "maxp: dq 0\n"*/ "\n" "\n" "section .bss\n" @@ -296,13 +325,13 @@ void writeepilogue(FILE *asmf){ void readsource(FILE *f,char **sourcep){ int sz=1024; char *source=malloc(sz); - assert(source); + if(!source)outofmem(); int i=0; while(true){ if(i==sz-1){ sz*=2; source=realloc(source,sz); - assert(source); + if(!source)outofmem(); } char c=fgetc(f); if(feof(f))break; @@ -313,11 +342,36 @@ void readsource(FILE *f,char **sourcep){ *sourcep=source; } +void optimise(char *source){ + int j=0; +#define COPY do {if(j<i)source[j]=source[i]; j++;} while(0) + for(int i=0;source[i];i++){ + switch(source[i]){ + case '[': + if(source[i+1]=='-'&&source[i+2]==']'){ + source[j++]='0'; + i+=2; + } else COPY; + break; + + default: + COPY; + break; + } + } + source[j]='\0'; +#undef COPY +} + int main(int argc,char **argv){ + fflush(stdout); parseargs(argc,argv); FILE *srcf=fopen(params.srcfname,"r"); - assert(srcf); + if(!srcf){ + fprintf(stderr,"Cannot open file '%s'\n",params.srcfname); + return 1; + } char *source; readsource(srcf,&source); @@ -325,6 +379,8 @@ int main(int argc,char **argv){ fclose(srcf); + optimise(source); + char asmfname[20]; FILE *asmf=gettempfilew(asmfname); if(params.verbose)fprintf(stderr,"asm -> %s\n",asmfname); @@ -335,6 +391,10 @@ int main(int argc,char **argv){ fclose(asmf); + /*char *b; + asprintf(&b,"cat -n %s",asmfname); + runcmd(b); + free(b);*/ int ret=compilechain(asmfname,params.dstfname); unlink(asmfname); if(params.verbose)fprintf(stderr,"unlink(%s) (asmfname)\n",asmfname); @@ -0,0 +1 @@ +++++++++++[>+++++++++++<-]>+. |