Springboard

From Esolang
Jump to navigation Jump to search

Springboard is a brainfuck pre-processor that adds the ability to define and re-use symbols.

It was inspired by Forth and it was written to make it easier to write stack based brainfuck code that can target any plain brainfuck machine implementation. This ability to define and re-use symbols, in a stack based model of computation, also enables capturing and re-using known brainfuck patterns more efficiently. An extensive list of those patterns is outlined on this page.

Quickstart

  1. Plain brainfuck code is valid springboard code
    • For example, the following is valid springboard code:

         [-]+>[-]+[-<+>]
  2. Springboard programs can define and re-use “symbols”.
    • For example:

          : 0 [-];
          : 1 0 +;
          : add [-<+>];
      
          1>1 add
      This will compile to the addition snippet given at point #1.
    • Notice here, “0” and “1” are NOT numbers.

  3. Symbols can be defined locally (within a given file) or get imported.
    • For example:
      • File: mysymbols.sb

            : 0 [-];
            : 1 0 +;
            : add [-<+>];
        
            1>1 add
      • File: mycode.sb

            import "mysymbols.sb"
        
            1>1>1>1>1
  4. Comments start with # and extend to the end of the line.
    • For example:

          : 0 [-];      # Ensures that the value of a cell is set to zero
          : 1 0 +;      # Re-uses the symbol 0 to define 1.
          : add [-<+>]; # Defines addition
      
          1>1 add       # Symbols get resolved recursively to produce the final code.

Program structure

A typical springboard program is divided into three optional sections:

  1. Imports
    • One import per line
  2. Symbol definitions
    • A symbol definition starts with :, followed by the symbol identifier, the Springboard code it resolves to and terminates with ;.
    • Symbol definitions in a given program can be imported to another program via the use of import.
  3. Code
    • Springboard code appears here as Brainfuck code symbols intermixed with any defined symbols.

“Libraries”

Springboard comes with a set of predefined symbols (“libraries”) that enable writing stack based brainfuck much easier than writing plain brainfuck.

The following table summarises the existing libraries and their content. The effect of each symbol to the stack is given in “Stack-Effect comment” style. That is, the effect of each symbol to the stack is outlined as (stack before evaluating the symbol -- stack after evaluating the symbol). For example, add (x y -- x+y) consumes the top two values from the stack (x, y) and pushes back the sum x+y on the top of the stack.

Library Symbols defined
std/num_base_N.sb, where N Integer symbols from 0 to 255
is 2,4,8,16..256 in sets of powers of two size.
std/math.sb add (x y -- x+y), sub (x y -- x-y)
mul (x y -- x*y), negate (x -- 1-x)
std/bool.sb and (x y -- x && y), or (x y -- x y)
not (x -- !x), isnonzero (x -- x!=0)
std/str.sb Lowercase letters a-z. SP (asci 32)
ds, sd begin/end the definition of a
string literal
lower (x -- x-32), upper (x -- x+32)
print Sends a string preloaded on the
stack, to output.
std/stack.sb drop (x y z -- x y), swap (x y -- y x)
| |rot (x y z – y z x),if,else,then`

Code examples

Hello World

import "../std/str.sb"

ds d l r o w SP o l l e h sd upper print

Try it here

Exclusive OR

Defines xor (x y -- x ^ y) as x * ¬y + ¬x * y.

import "../std/num_base_256.sb"
import "../std/stack.sb"
import "../std/bool.sb"

: xor over not over and rot rot not and or;

1 0 xor

Try it here

Bounded iteration

Prints a message (here “Step”) N times (here N=10)

import "../std/num_base_256.sb"
import "../std/stack.sb"
import "../std/bool.sb"
import "../std/math.sb"
import "../std/str.sb"

0 0 10 < [ > dup if 1 negate else 0 then add ds 10 p e t s upper sd print < ]

Try it here

Fibonacci Sequence

Given two successive terms of the Fibonacci sequence and a number N, produces the next N terms of the sequence (here N=11).

Notice here, the production of the next term in the series is quite simple: over over add creates copies of the last two terms in the series on the stack and adds them. The remaining brainfuck code preserves the “state” of the algorithm which is number N, the remaining terms to be produced. This makes fib a function that is applied to the top of the stack repeatedly, until N is reduced to zero.

import "../std/num_base_256.sb"
import "../std/stack.sb"
import "../std/math.sb"

1 1 11 <[[->>>>+<<<<] over over add >>> [-<<<+>>>]<<<-] 

Try it here

The springboard compiler

The most up to date reference implementation for the Springboard compiler along with its “libraries” and example programs can be obtained from this repository.