I wrote this simple BF compiler in C some time ago, and I decided I'd dump it somewhere if someone is interested. It generates 16-bit x86 assembly language to be assembled with NASM into DOS COM-style executables. It's missing code to clear the memory to 0 as it really should before executing the program, but that's left as an exercise for the reader. :)
bfc.c:#include <stdio.h>
int main(int argc, char **argv)
{
FILE *fin, *fout;
int c, label = 0;
if (argc != 3) {
fprintf(stderr, "usage: %s in.bf out.asm\n", argv[0]);
return 1;
}
fin = fopen(argv[1], "r");
fout = fopen(argv[2], "w");
if (!fin || !fout) {
fprintf(stderr, "couldn't open files\n");
return 1;
}
fprintf(fout, "[BITS 16]\nmov bx, A\n");
while ((c = fgetc(fin)) != EOF) {
switch (c) {
case '>':
fprintf(fout, "inc bx\n");
break;
case '<':
fprintf(fout, "dec bx\n");
break;
case '+':
fprintf(fout, "inc byte [bx]\n");
break;
case '-':
fprintf(fout, "dec byte [bx]\n");
break;
case '.':
fprintf(fout, "call print\n");
break;
case ',':
fprintf(fout, "call input\n");
break;
case '[':
fprintf(fout, "cmp byte [bx],0\njz E%d\nB%d:\n", label, label);
label++;
break;
case ']':
label--;
fprintf(fout, "cmp byte [bx],0\njnz B%d\nE%d:\n", label, label);
break;
default:
break;
}
}
fprintf(fout, "ret\n"
"print:\npush bx\nmov dl,[bx]\nmov ah,2\nint 21h\npop bx\nret\n"
"input:\npush bx\nmov ah,8\nint 21h\npop bx\nmov [bx],al\nret\n"
"A:\n");
fclose(fin);
fclose(fout);
return 0;
}
[category: /languages | permalink ]