HiveBrain v1.2.0
Get Started
← Back to all entries
debugcppMinor

Brainfuck-to-C compiler written in C++

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
brainfuckwrittencompiler

Problem

This compiler, implemented in C++, takes brainfuck code and produces a valid (but still obfuscated) C program, which in turn can be compiled to a native binary.

Expected usage is as follows:

-
Build the compiler

$ c++ -o bfc bfc.cpp


-
Compile a brainfuck program (example) to C

$ ./bfc ascii.bf


-
Compile the resulting C program to an executable.

$ cc -g -O0 -o ascii ascii.bf.c


-
Run the executable natively.

$ ./ascii


Or, you can also run it in a debugger. As long as you compiled with debugging symbols included and without optimizations, you should be able to step through the brainfuck source code line by line.

$ gdb ascii
[...]
(gdb) break ascii.bf:1
Breakpoint 1 at 0x1000010fc: file ascii.bf, line 1.
(gdb) run
[...]
Breakpoint 1, main (argc=1, argv=0x7fff5fbffbd0) at ascii2.bf:1
1   [-][
(gdb) break ascii.bf:66
Breakpoint 2 at 0x1000031c3: file ascii.bf, line 66.
(gdb) cont
Continuing.

Breakpoint 2, main (argc=1, argv=0x7fff5fbffbd0) at ascii.bf:66
66      >>>>> >>>>> >>> .                   (c_ascii)
(gdb) display m.ptr
1: m.ptr = 4
Current language:  auto; currently minimal
(gdb) display /d m.mem[0] @ 32
2: /d m.mem[0] @ 32 = {0, 58, 32, 10, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 58, 48, 1, 0, 0, 0, 58, 48, 1, 0, 0, 0, 58, 48, 0, 0}
(gdb) display /d m.mem[m.ptr]
3: /d m.mem[m.ptr] = 0


I'd like to know:

  • How well does this technique work for debuggers other than GDB?



  • Is there anything I should do to make either the compiler source code or the generated output more readable?



  • How should I improve the error handling?



  • Are there any other improvements you might suggest?



```
#include
#include
#include
#include

static const char BOILERPLATE_HEAD[] = "\
#include \n\
#include \n\
#include \n\
\n\
typedef unsigned char bf_mem_t;\n\
\n\
struct machine_state {\n\
int ptr;\n\
int size;\n\
bf_mem_t *mem;\n\
};\n\
\n\
void error(int line, struct machine_state *m) __attribute__((noreturn));\n\
void

Solution

As far as I can understand

default:    comment.replace(i, 0, "\\");


makes

case '\\':  comment.replace(i, 0, "\\"); break;


useless.

Edit to add another comment :

Please activate all warnings on your code on one hand and on the generated code on the other hand. I think that :

void comment(int line, struct machine_state *m, const char *comment) {\n\
    return;\n\
    fprintf(stderr, \"%d %s\", line, comment);\n\
}\n\


shoud eventually warn you about unreachable code.

Code Snippets

default:    comment.replace(i, 0, "\\");
case '\\':  comment.replace(i, 0, "\\"); break;
void comment(int line, struct machine_state *m, const char *comment) {\n\
    return;\n\
    fprintf(stderr, \"%d %s\", line, comment);\n\
}\n\

Context

StackExchange Code Review Q#39330, answer score: 3

Revisions (0)

No revisions yet.