Introduction to brain-flak


Brain-flak is a stack-based esoteric language designed by Programming Puzzles and Code-Golf user DjMcMayhem. The name is a cross between "brainfuck" , which was a big inspiration for the language, and "flak-overstow" , since the language is confusing and stack-based.

Overview
Brain-flak is an expression-based language written only using brackets, which must be balanced. Any other character will be ignored. Its only data type is a signed integer, which in this implementation has unbounded size.

There are two stacks, one of which is considered the active stack at each point of the execution. Programs start with the active stack initialised with the input data and inactive stack empty, and return the active stack when finished. Popping from an empty stack yields 0.

Each expression in brain-flak executes some side-effects on the stacks and evaluates to a number. Concatenation of expressions performs their side-effects from left to right and evaluates to a sum of their evaluations.

Functions
There are two types of functions in brain-flak: nilads, that are brackets without any contents, and monads, which are non-empty bracketed subexpressions.

Nilads:
() evaluates to 1
[] evaluates to the height of the active stack
{} pops the active stack and evaluates to the popped value
<> swaps active and inactive stack and evaluates to 0

Recall that concatenating expressions sums their values, so ()()() will evaluate to 3, and {}() will pop from the active stack and evaluate to one more than the popped value.

Monads:
(X) evaluates X, pushes the result on the stack and evaluates to the same value
[X] evaluates X and evaluates to its negation
{X} evaluates X in a loop as long as top of the active stack is not 0 and evaluates to the sum of all results
<X> evaluates X, discards the result and evaluates to zero

For example program ([(()()())]) will push numbers 3 and -3 to the stack, and program ({{}}) will replace values on the stack until a zero with their sum.

Examples
Sum the input stack:
USING: brain-flak prettyprint ; { 2 1 3 7 } [ b-f"([]<>){({}[()])<>({}{})<>}<>" ] with-brain-flak .
{ 13 }

Calculate nth fibonacci number:
USING: brain-flak prettyprint ; { 10 } [ b-f"(<>)(())<>{({}[()])(<>({})<({}{}<>)><>)(<>{}<>)<>}<>{}" ] with-brain-flak .
{ 55 }

More examples of brain-flak programs can be seen on its github wiki.

Vocabulary
The brain-flak vocabulary provides a brain-flak to Factor compiler in two words:
compile-brain-flak ( string -- quote: ( state -- state' ) )

b-f"


These offer a way to compile brain-flak strings into quotations and embed them directly in code. Programs compiled this way will take and return a brain-flak state object. State objects can be constructed from a sequence which becomes the initial stack of the state. The vocabulary also includes a wrapper word for using a brain-flak quotation as a function from sequence to sequence:
brain-flak

<brain-flak> ( seq -- state )

with-brain-flak ( ..A seq q: ( ..A s -- ..B s' ) -- ..B seq' )