************************* Embedded Brain Fuck (EBF) ************************* ============== 1 Introduction ============== Embedded Brain Fuck (or EBF) is an extension of the Brain Fuck language to allow easier usage on embedded systems. EBF adds a number of extra commands that make writing and manipulating registers and various places in memory simpler. It also provides mechanisms for literal writes into memory. ========== 2 Overview ========== EBF maps the data array from classic Brain Fuck to the entire system memory (this may be overridden via configuration options). This allows for architecture specific applications to access chip configuration registers. EBF programs are compiled into portable C code instead of interpreted directly. This allows the user to then compile the application using whatever C compiler works for their system. =================== 3 Programming Model =================== EBF follows the same model as original Brain Fuck, with a large, contiguous array of memory which may be accessed a single cell at a time. However, EBF adds several features which enable easier program and data flow on embedded systems. Most instructions allow for these modifiers: * Absolute Addressing - Take an absolute address to work on instead of using the current data cell. * Relative Addressing - Take a relative address, using an offset from the current working cell as an operand. * Literals - Take a literal value as an operand to the instruction. See the Instructions section below for specifics on how each instruction works with these modifiers. ---------------- 3.1 Data Pointer ---------------- EBF uses a variable to keep track of the current working cell: ``DP``. This pointer is incremented and decremented to access different cells and may be used to access or modify the value inside a cell. User defined functions may access this variable by including ``ebf.h``. ----------------- 3.2 Configuration ----------------- A single configuration block may be inserted into each EBF application which modifies the generated code in particular ways. The configuration block must be contained within a ``#%(...)`` expression. It may be multi-lined, and must adhere to YAML formatting. All options are either key/value pairs or sequences. Below is a listing of all options and what they do: * ``cell_width``: The width in bits of each data cell. Valid values are 8, 16, 32, and 64. * ``includes``: Any user supplied header files that should be included in the EBF application. Allows the application to call user supplied functions and hooks. Must be formatted as a sequence. * ``init_hook``: A boolean option that turns on the ``init_hook()`` function before the application code. This function must be defined by the user. * ``cleanup_hook``: A boolean option that turns on the ``cleanup_hook()`` function after the application code. This function must be defined by the user. ============== 4 Instructions ============== This section describes all of the valid instructions available in EBF, including both the classic and extended commands. The extended commands are a superset of the original commands and thus a classic Brain Fuck program will still be compiled correctly. ---------------------- 4.1 Unary Instructions ---------------------- Standard instructions are single character (unary) commands that typically operate using the current cell and/or data pointer. These are equivalent to classic Brain Fuck instructions. * ``>`` - Increment data pointer. * ``<`` - Decrement data pointer. * ``+`` - Increment current cell value. * ``-`` - Decrement current cell value. * ``.`` - Write the current cell value to ``stdout``. * ``,`` - Read a value from ``stdin`` and store it in the current cell. * ``[`` - If the current cell is zero, jump forward to one after the matching ``\]``. * ``]`` - If the current data value is non-zero, jump back to one after the matching ``\[``. Must close a previous ``\[``. * ``|`` - Bitwise OR the current cell and the next cell to the right and store the result in the current cell. * ``&`` - Bitwise AND the current cell and the next cell to the right and store the result in the current cell. * ``^`` - Bitwise XOR the current cell and the next cell to the right and store the result in the current cell. * ``~`` - Bitwise NOT the current cell and store the result in the current cell. * ``\`` - Bitwise left shift the current cell by one and store the result in the current cell. * ``/`` - Bitwise right shift the current cell by one and store the result in the current cell. ------------------------- 4.2 Extended Instructions ------------------------- Extended instructions are multi-character instructions that have a modifier character and take a number ``N`` as an operand. There are three different classes of extended commands: absolute address, relative address, and literal. The general form of an extended instruction is: ``IMN``, where ``I`` is the instruction character, ``M`` is the modifier character, and ``N`` is a number in either decimal (positive or negative), octal, or hexadecimal. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4.2.1 Absolute Address Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Absolute address instructions interpret the ``N`` parameter as an absolute address. That address is dereferenced and the value at that cell is used to perform the given instruction. For example, ``+*0xDEADBEEF`` reads the value at cell ``0xDEADBEEF`` and adds that value to the current cell. Below is a list of all of the absolute address instructions: * ``>*N`` - Increment data pointer by the value at ``N``. * ``<*N`` - Decrement data pointer by the value at ``N``. * ``+*N`` - Increment current cell value by the value at ``N``. * ``-*N`` - Decrement current cell value by the value at ``N``. * ``.*N`` - Write the value at ``N`` to ``stdout``. * ``,*N`` - Read a value from ``stdin`` and store it in cell ``N``. * ``[*N`` - If the value at ``N`` is zero, jump forward to one after the matching ``]``. * ``|*N`` - Bitwise OR the current cell and the value at ``N`` and store the result in the current cell. * ``&*N`` - Bitwise AND the current cell and the value at ``N`` and store the result in the current cell. * ``^*N`` - Bitwise XOR the current cell and the value at ``N`` and store the result in the current cell. * ``~*N`` - Bitwise NOT the value at ``N`` and store the result in the current cell. * ``\*N`` - Bitwise left shift the current cell by the value at ``N`` and store the result in the current cell. * ``/*N`` - Bitwise right shift the current cell by the value at ``N`` and store the result in the current cell. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4.2.2 Relative Address Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Relative address instructions interpret the ``N`` parameter as an offset from the current ``DP``. That address is dereferenced and the value at that cell is used to perform the given instruction. For example, ``+:0x100`` reads the value at cell ``DP + 256`` and adds that value to the current cell. Below is a list of all of the relative address instructions: * ``>:N`` - Increment data pointer by the value at ``DP+N``. * ``<:N`` - Decrement data pointer by the value at ``DP+N``. * ``+:N`` - Increment current cell value by the value at ``DP+N``. * ``-:N`` - Decrement current cell value by the value at ``DP+N``. * ``.:N`` - Write the value at ``DP+N`` to ``stdout``. * ``,:N`` - Read a value from ``stdin`` and store it in cell ``DP+N``. * ``[:N`` - If the value at ``(DP+N)`` is zero, jump forward to one after the matching ``]``. * ``|:N`` - Bitwise OR the current cell and the value at ``(DP+N)`` and store the result in the current cell. * ``&:N`` - Bitwise AND the current cell and the value at ``(DP+N)`` and store the result in the current cell. * ``^:N`` - Bitwise XOR the current cell and the value at ``(DP+N)`` and store the result in the current cell. * ``~:N`` - Bitwise NOT the value at ``(DP+N)`` and store the result in the current cell. * ``\:N`` - Bitwise left shift the current cell by the value at ``(DP+N)`` and store the result in the current cell. * ``/:N`` - Bitwise right shift the current cell by the value at ``(DP+N)`` and store the result in the current cell. ^^^^^^^^^^^^^^^^^^^^^^^^^^ 4.2.3 Literal Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^ Literal instructions interpret ``N`` parameter as a literal value. Similarly to absolute and relative, that value is used to perform the given instruction. For example, ``+#0x1234`` adds ``0x1234`` to the current cell. Below is a list of all of the literal instructions: * ``>#N`` - Increment data pointer by the value ``N``. * ``<#N`` - Decrement data pointer by the value ``N``. * ``+#N`` - Increment current cell value by the value ``N``. * ``-#N`` - Decrement current cell value by the value ``N``. * ``.#N`` - Write the value ``N`` to ``stdout``. * ``,#N`` - Store the value ``N`` to the current cell. * ``[#N`` - If the value ``N`` is zero, jump forward to one after the matching ``]``. * ``|#N`` - Bitwise OR the current cell and the value at ``N`` and store the result in the current cell. * ``&#N`` - Bitwise AND the current cell and the value at ``N`` and store the result in the current cell. * ``^#N`` - Bitwise XOR the current cell and the value at ``N`` and store the result in the current cell. * ``~#N`` - Bitwise NOT the value at ``N`` and store the result in the current cell. * ``\#N`` - Bitwise left shift the current cell by the value `N` and store the result in the current cell. * ``/#N`` - Bitwise right shift the current cell by the value `N` and store the result in the current cell. --------------------- 4.3 Jump Instructions --------------------- Jump instructions allow the programmer to jump the instruction pointer to another location in the program. These instructions work the same as C labels and ``goto``. Note, once a jump occurs there is no built-in concept of a return location, unless user defined functions are used. * ``@label`` - Mark a label named "label". This location may later be jumped to. Labels must begin with an alphabetical character, but may contain alphanumeric characters and the underscore (``_``) character. * ``!label`` - Jump to label "label". If the label is not defined in the application it is considered a syntax error. A jump may precede a label definition in the application. * ``!(func)`` - This is a special form of a jump that translates to a C function call. This allows the programmer to call external functions. The function signature must be ``void func(void)``, where ``func`` is any valid C function name. ------------ 4.4 Comments ------------ Comments in the code may be made using two methods, a line comment or non-instruction characters. Non-instruction characters are ignored, therefore, any characters that are not interpreted as an instruction are considered a comment. A line comment is used to mark the rest of a line as a comment, thus allowing instruction characters and syntax to be used in a comment. All characters on a line after a ``#`` (which isn't part of an instruction) are considered part of a line comment and are ignored by the parser (unless it is a configuration block, which is treated specially). ========== 5 Appendix ========== --------------- 5.1 Cheat Sheet --------------- These tables show the C equivalents of each instruction. ``DP`` is a pointer type to the current data cell. ^^^^^^^^^^^^^^^^^^^^^^^^^^ 5.1.1 Default Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^ These instructions are equivalent to classic Brain Fuck. +-------------+------------+---------------------+------------------------------------------------+ | Instruction | Syntax | C Equivalent | Notes | +=============+============+=====================+================================================+ | ``>`` | ``>`` | ``DP++`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``<`` | ``<`` | ``DP--`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``+`` | ``+`` | ``(*DP)++`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``-`` | ``-`` | ``(*DP)--`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``[`` | ``[`` | ``while(*DP!=0) {`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``]`` | ``]`` | ``} // end while`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``.`` | ``.`` | ``putc(*DP)`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``,`` | ``,`` | ``*DP=getchar()`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``&`` | ``&`` | ``*DP=*DP&*(DP+1)`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``|`` | ``|`` | ``*DP=*DP|*(DP+1)`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``^`` | ``^`` | ``*DP=*DP^*(DP+1)`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``~`` | ``~`` | ``*DP=~*DP`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``\`` | ``\`` | ``*DP=*DP<<1`` | | +-------------+------------+---------------------+------------------------------------------------+ | ``/`` | ``/`` | ``*DP=*DP>>1`` | | +-------------+------------+---------------------+------------------------------------------------+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 5.1.2 Absolute Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``N`` represents any valid address (in decimal, octal, or hexadecimal notation). +-------------+------------+------------------------+---------------------------------------------+ | Instruction | Syntax | C Equivalent | Notes | +=============+============+========================+=============================================+ | ``>`` | ``>*N`` | ``DP+=*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``<`` | ``<*N`` | ``DP-=*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``+`` | ``+*N`` | ``*DP+=*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``-`` | ``-*N`` | ``*DP-=*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``[`` | ``[*N`` | ``while(*N!=0) {`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``]`` | ``]*N`` | ``if(*N==0) break; }`` | Allows extra conditional break. | +-------------+------------+------------------------+---------------------------------------------+ | ``.`` | ``.*N`` | ``putchar(*N)`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``,`` | ``,*N`` | ``*N=getchar()`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``&`` | ``&*N`` | ``*DP=*DP&*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``|`` | ``|*N`` | ``*DP=*DP|*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``^`` | ``^*N`` | ``*DP=*DP^*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``~`` | ``~*N`` | ``*DP=~*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``\`` | ``\*N`` | ``*DP=*DP<<*N`` | | +-------------+------------+------------------------+---------------------------------------------+ | ``/`` | ``/*N`` | ``*DP=*DP>>*N`` | | +-------------+------------+------------------------+---------------------------------------------+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 5.1.3 Relative Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ``N`` represents any valid positive or negative number (in decimal, octal, or hexadecimal notation). This number is added to the current ``DP`` using C-style pointer arithmetic to determine which cell to operate on. +-------------+------------+-----------------------------+----------------------------------------+ | Instruction | Syntax | C Equivalent | Notes | +=============+============+=============================+========================================+ | ``>`` | ``>:N`` | ``DP+=*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``<`` | ``<:N`` | ``DP-=*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``+`` | ``+:N`` | ``*DP+=*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``-`` | ``-:N`` | ``*DP-=*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``[`` | ``[:N`` | ``while(*(DP+N)!=0) {`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``]`` | ``]:N`` | ``if(*(DP+N)==0) break; }`` | Allows extra conditional break. | +-------------+------------+-----------------------------+----------------------------------------+ | ``.`` | ``.:N`` | ``putchar(*(DP+N))`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``,`` | ``,:N`` | ``*(DP+N)=getchar()`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``&`` | ``&:N`` | ``*DP=*DP&*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``|`` | ``|:N`` | ``*DP=*DP|*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``^`` | ``^:N`` | ``*DP=*DP^*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``~`` | ``~:N`` | ``*DP=~*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``\`` | ``\:N`` | ``*DP=*DP<<*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ | ``/`` | ``/:N`` | ``*DP=*DP>>*(DP+N)`` | | +-------------+------------+-----------------------------+----------------------------------------+ ^^^^^^^^^^^^^^^^^^^^^^^^^^ 5.1.4 Literal Instructions ^^^^^^^^^^^^^^^^^^^^^^^^^^ ``N`` represents any valid positive or negative number (in decimal, octal, or hexadecimal notation). This literal number is used in the operation. +-------------+------------+-----------------------+----------------------------------------------+ | Instruction | Syntax | C Equivalent | Notes | +=============+============+=======================+==============================================+ | ``>`` | ``>#N`` | ``DP+=N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``<`` | ``<#N`` | ``DP-=N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``+`` | ``+#N`` | ``*DP+=N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``-`` | ``-#N`` | ``*DP-=N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``[`` | ``[#N`` | ``while(N!=0) {`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``]`` | ``]#N`` | ``if(N==0) break; }`` | Allows forced break (e.g. ``if()`` pattern). | +-------------+------------+-----------------------+----------------------------------------------+ | ``.`` | ``.#N`` | ``putchar(N)`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``,`` | ``,#N`` | ``*DP=N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``&`` | ``&#N`` | ``*DP=*DP&N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``|`` | ``|#N`` | ``*DP=*DP|N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``^`` | ``^#N`` | ``*DP=*DP^N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``~`` | ``~#N`` | ``*DP=~N`` | | +-------------+------------+-----------------------+----------------------------------------------+ | ``\`` | ``\#N`` | ``*DP=*DP<>N`` | | +-------------+------------+-----------------------+----------------------------------------------+ ^^^^^^^^^^^^^^^^^^^^^^^^ 5.1.5 Misc. Instructions ^^^^^^^^^^^^^^^^^^^^^^^^ +-------------+----------------+-------------------+----------------------------------------------+ | Instruction | Syntax | C Equivalent | Notes | +=============+================+===================+==============================================+ | ``@`` | ``@label`` | ``label:`` | Label must conform to C standard. | +-------------+----------------+-------------------+----------------------------------------------+ | ``!`` | ``!label`` | ``goto label;`` | Label must conform to C standard. | +-------------+----------------+-------------------+----------------------------------------------+ | ``!()`` | ``!(func)`` | ``func();`` | External function call. Function must be | | | | | defined by the user with signature: | | | | | ``void func(void)``. | +-------------+----------------+-------------------+----------------------------------------------+ | ``#`` | ``# comment`` | ``/* comment */`` | Everything until the next newline is | | | | | considered a comment. | +-------------+----------------+-------------------+----------------------------------------------+ | ``#%()`` | ``#%(config)`` | N/A | Multi-line YAML configuration block (one per | | | | | application). See Configuration section for | | | | | more info. | +-------------+----------------+-------------------+----------------------------------------------+