Skip to content
A self hosting Extended brainfuck to pure brainfuck compiler
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
docs
examples
object-design
tools
CNAME
COPYING
Makefile
_config.yml
ebf.ebf
readme.md

readme.md

A self hosting Extended brainfuck to pure brainfuck compiler

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

Serious use: Zozotez - a LISP interpreter implemented in EBF

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.

Current features

  • Variables with variable length names
  • Alternative bracket () for automatic bracket aligning
  • A macro replace mechanism that is nestable with parameter passing
  • multiplication of bf commands by using number in front of them. eg. 256>
  • print string and store string for easy string manipulation
  • All the power of BrainFuck. All BF programs are EBF programs :)
  • Compatible with most cross compilers/interpreters. Supports all EOF convensions

http://sylwester.no/gcodeimg/lamp_50.png

Current Commands in addition to BFs <>+-[],.

var in these examples can be any string of alphanumeric characters and underscore [\w_]+.

groupfunctiondescription
variable:varDefines a variable. It allocates variable in the order of appearance, eg. 🅰️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.
$varApplies <'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.
@varTo 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.
!varDeallocates 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.
&nameInsert 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
🅰️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.

Examples,. The advantage of EBF comes apparent when dealing with larger projects than these examples

descEBFsourceBFobject
HelloWorld
|"Hello World

"
>++++++++[-<+++++++++>]<.

>+++++[-<++++++>]<-.+++++
++..+++.>+++++++++[-<----
----->]<++.>+++++++[-<+++
+++++>]<-.>+++++[-<+++++>
]<-.+++.------.--------.>
++++++++[-<-------->]<---
.>++++[-<----->]<---.
echo
;;macro definitions

{read $eof_flag+$input(-),[+[->-]]>[@eof_flag->]}
{print .}
var :input
var :eof_flag
;;main program
&read
$input(
&print
&read
)
>+<[-],[+[->-]]>[->]<<[.

>+<[-],[+[->-]]>[->]<<]
simple
add
{read ^1eof_flag+^0input(-),[+[->-]]>[->] *-1}

:num1
:num2
$num1 &read
$num2 &read
$num1 48-
$num1(-$num2+)
$num2 .
>+<[-],[+[->-]]>[->]<>

+<[-],[+[->-]]>[->]<<<
----------------------
----------------------
----[->+<]>.
reverse
echo
:input

:end_flag

{read
$end_flag+
$input,
+[11-[$end_flag-]]>[@end_flag->]
}

; read until linefeed/eof
+(->@input &read )
; print in reverse order
<@input[11+.(-)<]
; print newline
10+.
+[->>+<,+[-----------[

>-]]>[->]<<]<[++++++++
+++.[-]<]++++++++++.

See more examples in source repository

This site is a member of a Web Ring.

To browse visit The Esoteric Programming Languages Ring

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.