This is a compiler I wrote that compiles a language I created into Brainfuck.
Download the source : compile.c.
The parser is very simple. The source file is parsed into tokens, separated by spaces.
FizzBuzz example :
char three set three 3 char five set five 5 char ten set ten 10 char num1 set num1 '0 char num2 set num2 '0 char count set count 40 while count { dec count inc num2 dec ten ifnot ten { set num2 '0 inc num1 set ten 10 } char fizzbuzz zero fizzbuzz dec three ifnot three { set three 3 print Fizz inc fizzbuzz } dec five ifnot five { set five 5 print Buzz inc fizzbuzz } ifnotz fizzbuzz { char zero equal zero num1 '0 ifnotz zero { put num1 } put num2 } print \n }
Which is compiled into the following Brainfuck code :
[-]+++>[-]+++++>[-]++++++++++>[-]++++++++++++++++++++++++++++++++++++++++++++++++>[-]++++++++++++++++++++++++++++++++++++++++++++++++>[-]++++++++++++++++++++++++++++++++++++++++[-<+<<->>>>>[-]<[-]<<<<[>>>>>+<+<<<<-][-]>>>>>[-<<<<<+>>>>>]>[-]+<<[>>[-]<<[-]][-]>>[-<<+>>]<<[<<[-]++++++++++++++++++++++++++++++++++++++++++++++++<+<[-]++++++++++>>>>[-]]>>>[-]<<<<<<<<<->>>>>>>>>>>[-]<[-]<<<<<<<<<<[>>>>>>>>>>>+<+<<<<<<<<<<-][-]>>>>>>>>>>>[-<<<<<<<<<<<+>>>>>>>>>>>]>[-]+<<[>>[-]<<[-]][-]>>[-<<+>>]<<[<<<<<<<<<<[-]+++>>>>>>>>>>>>>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++++++++.+++++++++++++++++..<<<<+>[-]]<<<<<<<<<->>>>>>>>>>>>>[-]<[-]<<<<<<<<<<<<[>>>>>>>>>>>>>+<+<<<<<<<<<<<<-][-]>>>>>>>>>>>>>[-<<<<<<<<<<<<<+>>>>>>>>>>>>>]>[-]+<<[>>[-]<<[-]][-]>>[-<<+>>]<<[<<<<<<<<<<<<[-]+++++>>>>>>>>>>>>>>>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++++++++++++++++++++++++++++.+++++..<<<<<<<+>>>>[-]]>>>[-]+<<<<<<<[>>>>>>>[-]<<<<<<<[-]][-]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[>>>>>>>>>>[-]<[-]<<<<<<<<<<<<<<<[>>>>>>>>>>>>>>>>+<+<<<<<<<<<<<<<<<-][-]>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>]>[-]++++++++++++++++++++++++++++++++++++++++++++++++[<<->>-]<<<[-]+>[<[-]>[-]]>>>[-]+<<<<[>>>>[-]<<<<[-]][-]>>>>[-<<<<+>>>>]<<<<[<<<<<<<<<<<<<<.>>>>>>>>>>>>>>[-]]<<<<<<<<<<<<<.>>>>>[-]]>>>>>>>>[-]++++++++++.<<<<<<<<<<<<]
Commands may be split into multiple lines or can be written all in the same line. That is, the following are equivalent :
char hello zero hello inc hello
char hello zero hello inc hello
char hello zero hello inc hello
My compiler implements many commands that make it easier to create Brainfuck programs :
char coucou
coucou
.set coucou 123
coucou
variable to 123.set coucou 'A
coucou
variable to 65.copy coucou hello
hello
into coucou
.move coucou hello
hello
into coucou
.zero coucou
coucou
variable to zero.inc coucou
coucou
variable.incby coucou 5
coucou
variable by 5.dec coucou
coucou
variable.decby coucou 5
coucou
variable by 5.equal out coucou hello
coucou
and hello
are equal and stores the result into out
.equal out coucou 5
coucou
equals 5
and stores the result into out
.equal out coucou 'A
coucou
equals 65
and stores the result into out
.greater out coucou hello
coucou
is greater than hello
and stores the result into out
.greater out coucou 5
coucou
is greater than 5
and stores the result into out
.greater out coucou 'A
coucou
is greater than 65
and stores the result into out
.flip coucou
coucou
variable : nonzero becomes zero and zero becomes one.get coucou
coucou
.put coucou
coucou
.print Hello,\ World!\n
Hello, World!
.All loops follow the same syntax :
while coucou { ... }
This loops while coucou
is nonzero.
...
may be any tokens.
This prints A five times :
char count set count 5 while count { dec count print A } print \n
It may also be written into a single line :
char count set count 5 while count { dec count print A } print \n
Ifs are loops that run only once.
There are four kinds of ifs :
if coucou { ... }
ifnot coucou { ... }
ifz coucou { ... }
ifnotz coucou { ... }
The ifs ending with z
clear their condition after they are run.
Use them to save memory.
The two other ifs make a copy of their condition and leave the original untouched.
if
tests if the condition is nonzero and ifnot
tests if the condition is zero.
Loops have their own set of variables.
If you want to create variables not accessible from outside your code, use blocks :
{ char x set x 'X } char y put y print \n
This will print X because the two variables share the same position in memory.
To create an array, use the array
command.
array str 4
This creates variables str
, str+1
, str+2
and str+3
.
To navigate arrays, use the left
and right
commands.
right
and left
shift every variable.
This prints A :
array str 2 set str+1 'A right 1 put str
This also prints A :
char a char b set b 'A right 1 put a
Because a
now points to b
.
To start using normal variables again (and print
), make sure you are back at the start of your array.
To more easily work with strings, use the read
and write
commands.
This reads a string and prints it back when you press Enter :
array str 10 read str '\n write str
The second argument to read
specifies when to stop reading. Here, it stops at a newline. It must be a decimal number or a character preceded by an apostrophe.
Internally, strings start and end with null bytes. So array size 10 means a maximum of 8 bytes.
This code does a ROT13 :
char loop set loop 1 while loop { char input get input equal loop input 10 flip loop if loop { # A-Z to a-z char beforeZ greater beforeZ 91 input if beforeZ { incby input 32 } incby input 13 # after z char afterz greater afterz input 122 if afterz { decby input 26 } # a-z to A-Z if beforeZ { decby input 32 } put input } } print \n
This reads your name and prints it back with "Hello" before it :
print Your\ name\ :\ # array name 10 read name '\n print Hello,\ # ifnot name+1 { print World } write name print !\n
To reuse code, use functions.
Functions are declared with the function
function. They may have zero or more arguments.
This prints "Hello, Philippe!" :
function hello name { print Hello,\ # print name print !\n } hello Philippe
Example : an implementation of an "if-then-else" function.
function ifelsez condition then else { char not set not 1 while condition { zero condition zero not then } while not { zero not else } } char c set c 0 # change to 0 or 1 ifelsez c { print IfThen } { print IfElse }
Note that functions only have access to variables where the funciton is called, not defined.
This prints A :
function test { put a } { char a set a 'A test }
Internally, the curly brackets create anonymous functions that can be used by other functions.