patterncMinor
A BrainF*ck-ish compiler in C
Viewed 0 times
ishbrainfcompiler
Problem
-ish because I removed the input functionality from the compiler. And, the compiler does not support nested loops
I've been recently reading up on compilers and how they work. Although this doesn't use most of the things I've learned about (the lexical and parser things), I thought it would be fun to try create a brainf*ck compiler, rather than an interpreter.
bfc.c
```
#include
static int i;
static char *code; // these two as static so get_amt_to_change can easily interact
int get_amt_to_change(char c); // so the compiler doesn't write (ie) add di, 1 ten times
int main(int argc, char **argv) {
code = argv[1];
puts("xor di, di\n"
"setup_loop:\n"
"mov byte [tape + di], 0\n"
"add di, 1\n"
"cmp di, 101\n"
"jne setup_loop\n"
"xor di, di"); // sets up the tape with all 0's
int loop_count = 0; // to keep track of asm subroutines for [ and ]
for(i = 0; code[i] != '\0'; i++) {
switch(code[i]) {
case '+':
printf("add byte [tape + di], %d\n", get_amt_to_change('+'));
break;
case '-':
printf("sub byte [tape + di], %d\n", get_amt_to_change('-'));
break;
case '>':
printf("add di, %d\n", get_amt_to_change('>'));
break;
case '<':
printf("sub di, %d\n", get_amt_to_change('<'));
break;
case '.':
puts("mov ah, 0Eh\n"
"mov al, byte [tape +di]\n"
"int 10h");
break;
case '[':
printf("cmp byte [tape + di], 0\n"
"je end_loop%d\n"
"start_loop%d:\n", loop_count, loop_count);
break;
case ']':
printf("cmp byte [tape + di], 0\n"
"jne start_loop%d\n"
"end_loop%d:\n", loop_count, loop_count);
I've been recently reading up on compilers and how they work. Although this doesn't use most of the things I've learned about (the lexical and parser things), I thought it would be fun to try create a brainf*ck compiler, rather than an interpreter.
bfc.c
```
#include
static int i;
static char *code; // these two as static so get_amt_to_change can easily interact
int get_amt_to_change(char c); // so the compiler doesn't write (ie) add di, 1 ten times
int main(int argc, char **argv) {
code = argv[1];
puts("xor di, di\n"
"setup_loop:\n"
"mov byte [tape + di], 0\n"
"add di, 1\n"
"cmp di, 101\n"
"jne setup_loop\n"
"xor di, di"); // sets up the tape with all 0's
int loop_count = 0; // to keep track of asm subroutines for [ and ]
for(i = 0; code[i] != '\0'; i++) {
switch(code[i]) {
case '+':
printf("add byte [tape + di], %d\n", get_amt_to_change('+'));
break;
case '-':
printf("sub byte [tape + di], %d\n", get_amt_to_change('-'));
break;
case '>':
printf("add di, %d\n", get_amt_to_change('>'));
break;
case '<':
printf("sub di, %d\n", get_amt_to_change('<'));
break;
case '.':
puts("mov ah, 0Eh\n"
"mov al, byte [tape +di]\n"
"int 10h");
break;
case '[':
printf("cmp byte [tape + di], 0\n"
"je end_loop%d\n"
"start_loop%d:\n", loop_count, loop_count);
break;
case ']':
printf("cmp byte [tape + di], 0\n"
"jne start_loop%d\n"
"end_loop%d:\n", loop_count, loop_count);
Solution
You need to enlarge tape because your initialization zeroes 101 bytes.
When in graphics mode, the teletype function uses the BL and BH registers as arguments.
When in text mode, the teletype function uses the BH register as an argument.
You can optimize the setup code by iterating backwards. It shaves off 2 instructions! It too will leave DI=0.
I don't know if you would care but the code for [ ] by itself produces an infinite loop if the byte at [tape + di] is anything but zero.
section .bss
tape resb 101When in graphics mode, the teletype function uses the BL and BH registers as arguments.
mov bx,0007h ;Display page 0 and Color 7
mov ah, 0Eh
mov al, byte [tape +di]
int 10hWhen in text mode, the teletype function uses the BH register as an argument.
mov bh,0 ;Display page 0
mov ah, 0Eh
mov al, byte [tape +di]
int 10hYou can optimize the setup code by iterating backwards. It shaves off 2 instructions! It too will leave DI=0.
mov di, 101
setup_loop:
sub di,1
mov byte [tape + di], 0
jnz setup_loopI don't know if you would care but the code for [ ] by itself produces an infinite loop if the byte at [tape + di] is anything but zero.
Code Snippets
section .bss
tape resb 101mov bx,0007h ;Display page 0 and Color 7
mov ah, 0Eh
mov al, byte [tape +di]
int 10hmov bh,0 ;Display page 0
mov ah, 0Eh
mov al, byte [tape +di]
int 10hmov di, 101
setup_loop:
sub di,1
mov byte [tape + di], 0
jnz setup_loopContext
StackExchange Code Review Q#83600, answer score: 3
Revisions (0)
No revisions yet.