Home

DrV :: Blog

Blog home | RSS 2008/03/27 rss

03-27-2008

A Simple BF Compiler

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 ]


Powered by Blosxom
Last updated: 2008-Nov-24
Contact: daniel@drv.nu