In this example we use libgccjit to construct an ahead-of-time compiler for an esoteric programming language that we shall refer to as “brainf”.
brainf scripts operate on an array of bytes, with a notional data pointer within the array.
brainf is hard for humans to read, but it’s trivial to write a parser for it, as there is no lexing; just a stream of bytes. The operations are:
Character | Meaning |
---|---|
> | idx += 1 |
< | idx -= 1 |
+ | data[idx] += 1 |
- | data[idx] -= 1 |
. | output (data[idx]) |
, | data[idx] = input () |
[ | loop until data[idx] == 0 |
] | end of loop |
Anything else | ignored |
Unlike the previous example, we’ll implement an ahead-of-time compiler,
which reads .bf
scripts and outputs executables (though it would
be trivial to have it run them JIT-compiled in-process).
Here’s what a simple .bf
script looks like:
[ Emit the uppercase alphabet ] cell 0 = 26 ++++++++++++++++++++++++++ cell 1 = 65 >+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++< while cell#0 != 0 [ > . emit cell#1 + increment cell@1 <- decrement cell@0 ]
|