A self hosting Extended brainfuck to pure brainfuck compiler
This project is maintained by westerp
EFB Compiler extends brainfuck by using extra symbols. The output will be valid brainfuck code that can run on any interpreter/compiler. If you are interested in the process of making this compiler, please go to the Introduction. To find out more about the the syntax have a look at EBF language introduction
The high level goal was to be able to implement a LISP interpreter which runs on brainfuck and bootstrapped with EBF. I have spawned a new project called Zozotez for creating LISP with EBF.
BrainFuck
. All BF programs are EBF programs :)<>+-[],.
var in these examples can be any string of alphanumeric characters and underscore [\w_]+
.
group | function | description |
---|---|---|
variable | :var | Defines a variable. It allocates variable in the order of appearance, eg. :a:b will give a position and b position 1. If you try to redefine a variable it will report ERROR. For byte-oriented interpreters/cross compilers the maximum number of variable allocated at the same time is 253. |
$var | Applies <'s or >'s in order to move from current position to the position allocated to variable named x. It assumes it is at position 0 at the start of the application and it will follow < and > given that you don't create an asymmetric loop. | |
@var | To give the compiler the position after a asymmetric loop. Take for instance: :a:b:c:d [>-]>[->] @c< It is impossible for the code to actually go into both loops so in reality you will always be in c and not d as the compiler thinks. | |
!var | Deallocates variable x. It is assumed that x was the last variable allocated and will halt with an ERROR if not. | |
structure | (...) | Auto-aligning brackets. $a($b+++) => $a[$b+++$a] . This might be used in rotating data structures like array seeking as well. consider we have an array left of :c:a:z which is open.. $c(@z) will seek until bread crumb is zero. It supports up to 251 nested loops. awib 0.2 has 18 and as of writing ebf has 12 as it's highest nesting level. |
macro | {name...} | Create macro named x. Contents will not be echoed since it might contain brainfuck code that will affect execution. A macro cannot create other macroes. When macroes are expanded ebf will treat the expanded text as ebf code, not just pure brainfuck. This enables a macro expansion to trigge runderlying macro expansins and the posibility to create complex code in layers of abstraction. |
&name | Insert macro x. | |
^<index> |
^0 works like $var. ^0 is the cell from which the macro was called and ^1 is the first cell after making this a kind if parameter passing possible eg we have:a:b:c and we are at a when invoking &a. In there ^ and ^0 is $a, ^1 is $b and ^2 is $c .If we afterwards are at $b and call the macro, then ^0 would be $b. | |
*<+-><offset> | Another way to indicate offset. Like @a, but you tell the relative offset fix. Eg. *-3 will reduce the compilers assumed position with 3. Used in combination with ^<number> where macro does not know of it's real position (eg. it could be called from any position and hench reused) | |
Syntax sugar | <number><+-<>> |
Eg. 10+ reads like "times 10 plus". It replicates any of the commands <>+- the number of times indicated by the digits before the operation (+ in example). It does not have cell boundry limits. 512> is OK for 8 bit interpreter/compilers. |
~ "text" | Stores the string denoted by text from the current cell. Position end up one cell to the right from the last character in the string. Example uses double quotes, but in reality any character will do, eg. ~*"'^* uses asterix as quote character | |
|"text" | Prints the string denoted by test using the current and the next cell, which needs to be empty. Current cell contains last character after operation.Like store string you might use any quote char. |
desc | EBFsource | BFobject | ||||||
HelloWorld |
|
| ||||||
echo |
|
| </tr>
||||||
simple add |
|
| ||||||
reverse echo |
|
|