summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-13 18:30:01 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-13 18:30:01 +0200
commitf30ff2240932d4d03984bd16cc8b9bb2b5427a53 (patch)
tree8dd7817c3e6d4c1a34f410f63be569fd16133081
parentdaf7dfedf0593b562c5fb3e8a023ef6c3924bb86 (diff)
Better error handling, flushing, optimisation
-rw-r--r--bfcomp.c96
-rw-r--r--o.bf1
2 files changed, 79 insertions, 18 deletions
diff --git a/bfcomp.c b/bfcomp.c
index 95a43f3..5c4db60 100644
--- a/bfcomp.c
+++ b/bfcomp.c
@@ -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);
diff --git a/o.bf b/o.bf
new file mode 100644
index 0000000..dd5b852
--- /dev/null
+++ b/o.bf
@@ -0,0 +1 @@
+++++++++++[>+++++++++++<-]>+.