# BunnyBell

The World's Most Practical Esolang!

BunnyBell is a programming language created by User:PixelatedStarfish in 2022 and it is designed to be the most practical esolang possible (though some may find this heretical). It was initially created as a second major version of MacroBeep, designed to support subroutines. MacroBeep v2.0 diverged to the point where it was best renamed, as a new language entirely.

Differences include the following:

• Macros are replaced by functions that can take arguments.
• Cells are four bytes in size, instead of one.
• The global tape of cells is removed and replaced by a local tape for each call to a function.
• The global tape pointer is removed. Instead, cells are addressable via the reference operator &.
• Instructions support more than one argument.

Changes were implemented to better meet the design goals of MacroBeep versions 1.x by means of efficient memory management, concise source code, and the elimination of global memory constructs inherited from Turing tarpits

## Interpreter

An interpreter for BunnyBell is in progress. File extension is  .bbe

### Goals

• Test each command for expected and unexpected arguments.
• Test for error cases.
• Prove useability via the implementation of the Game of Life and a simple command-line game to play.
• Prove useability via the implementation of various program forms on the esolangs wiki, especially finite state machines that take input, display output, and demonstrate arithmetic capabilities.

### Considerations

In order of priority:

• Implement const, handle, hend [implemented]
• Test instructions
• Higher order functions.
• Cyclic references; see linker section.
• The shebang line

Examples of concepts:

##
Output:
10
14
##

func main
foo 5 &0
foo 10 4 &1
out &0
cout 10
out &1
return

func foo a &loc
return &&loc &0

func foo a b &loc
return &&loc &0

• Higher Order Functions (which require a type)
 func main
foo :bar &0
return

func foo :inFun &loc
inFun &0 10 5
return &&loc &0
# &&loc is set to 15

func bar &re a b
return &&re &0

• Cyclic references
1. File A.bbe has the statement  include B.bbe
2. File B.bbe has the statement  include A.bbe
• Shebang line
#!/usr/bin/bbe


## Design Goals: Why Use BunnyBell?

This language is best used for the fun of tinkering. It is designed for students; to ease the transition from learning a high level language to a lower level one, and to practice essential programming skills, such as tracing, debugging, and memory management.

• It has a simplified syntax, for programs that are easier to write, organize, trace, and debug.
• It has simple, programmer controlled memory management.
• Significant punctuation is minimized.
• Significant white space is minimized.

## Memory

All memory in this language is bound to functions (or subroutines, if you prefer that term). Function calls implicitly have access to local tapes of addressable cells.

### Cells

BunnyBell programs store information in four byte cells. A cell stores a 32-bit integer value. Cells are allocated to function calls (see Syntax) in contiguous tapes. Each cell on the tape has an address referenced by the refer operation, & and an integer. &0 refers to the first cell on the strip, &1 to the second, etc. (It may seem odd written out, but that is conventional, and it would annoy programmers to no end if &1 referred to cell 1.)

### The Call Stack

This stores function calls, which are explained in the Syntax section.

## Syntax

### Statements

Statements are a single line of code that are interpreted to run a program. Each statement starts with a command, which can take arguments. The arguments for a command can be separated by tabs or spaces.

### Functions and Calls

Functions define subprograms, and can be called to perform a task. A function call executes the sub program defined by a function. Calls cannot run include statements, but they can take input, store information in memory, and output to calling (parent) function calls. After processing include statements, all BunnyBell programs call the main function implicitly. Every function called from the main function is a child of the main function call.

The ‘func’ command starts a function definition. It takes a function name and input arguments for the function. Functions end with a ‘return’ command which takes no arguments. Outputting to the parent call is accomplished by ‘emit’ or ‘set’ commands.

When a function is called execution stops for the parent call, and resumes when the child call completes execution. The program ends when the main call completes or when a halt instruction executes.

### Arguments

A command can take a few different types of arguments:

• An ADDRESS is an argument that refers to a cell with the refer operator (&).
• An INTEGER is any integer (whole number) in the range of 32 bits.
• A VALUE can be an INTEGER or an ADDRESS, in the latter case, the information stored in a cell is interpreted as an integer.
• A CHARACTER SET is any non integer argument.

Command arguments take the following order from left to right:

• Command name
• Addresses in order of seniority
• Values
• Character sets

The only exception is when their is an argument grouping of indeterminate length. That always has the rightmost position, regardless of typing.

Higher order functions may be added to this list, which would be prioritized after the command name, but before the addresses. These would be used in user-defined functions.

### A Detailed Explanation of the Refer Operator (&)

The basics of how the refer operator works are explained in Cells. The ampersand refers to a cell via its address, such as &0.

To refer to cells of parent calls use a sequence of refer operators. &&0 refers to the first cell of the parent call, and &&&0 refers to the first cell of the grandparent call.

Combining the refer operator with parentheses allows cells to refer to other cells. As shown in the cat program, &(&0) Any address in parentheses is interpreted as a value, so this operation gets the value stored in cell 0 and then gets an address. Effectively, it gets an address stored in cell 0. So cell 0 refers to another cell.

Finally, note that terms do not distribute. &(&12)(&17) is not a valid expression, and it throws an error.

### Grammar

Program := {(Statement | Func)}
Func := Fi, {Statement}, Re
Fi := 'func', Word, Lt
Re := 'return', Lt
Statement := Command, {Arg}, Lt
Command := Word, Sp
Arg := {(Int | Cell | Word), Sp}
Cell := ({And}, And, Int) | ({And} ‘(‘, Cell, ‘)’)
Int := any integer
Word := visible char strings
And := '&'
Sp := ' '
Lt := a newline char


## Commands

There are 26 commands in BunnyBell. Note that arguments in [brackets] are optional

func
defines a function with or without arguments
Args: FUNCTION NAME, [FUNCTION ARGUMENTS]
return
Ends a function and returns cell values to the
specified location in a parent function, such that
parent cells are overwritten. Note that in
the three argument case, the third argument must
refer to an address of the same call as the second.
The third argument must also refer to an address
that is greater than that of the second argument.
 &1 &3  not  &3 &1 
ONE OR MORE CELLS AS SPECIFED BY ARUGMENTS 2 AND 3]
set
This sets a cell.
sub
This takes value from cell.
out
This prints the value given.
Args: VALUE
cout
The prints the value given as an ASCII character.
Args: VALUE
input
Takes input at a cell.
Integer (0), char (1),  or string (2)
print
Prints a string, supports escape sequences.
Args: STRING TO PRINT
bell
Don’t you know? A bell goes ding!
It makes sound!
Args: [HERTZ, [DURATION IN MILLIS]]
wait
Wait for a number of milliseconds
(1000 if not specified).
Args: [TIME TO WAIT IN MILLIS]
random
Set cell to a number between MIN and MAX
with min inclusive.
halt
End program.
label
A label to go to. These are not global,
instead they are defined locally in a function.
Args: LABEL NAME
beq
Branch to LABEL if args are equal.
Args: VALUE, VALUE, LABEL
bneq
Branch to LABEL if args are not equal.
Args: VALUE, VALUE, LABEL
bgr
Branch to LABEL
if A is greater than B.
Args: A, B, LABEL
bleq
Branch to LABEL
if A is less than or equal to B.
Args: A, B, LABEL
goto
Go to label specified
Args: LABEL
istore
Store an array of integers,
separated by white space, starting at the
cstore
Store an array of characters,
bound
Set a bound on function memory, such that cells
beyond the set bound are freed.
Cells cannot be allocated beyond the bound.
Exceeding the bound throws a Not A Cell Error.
Args: BOUND (A VALUE)
const
The specified cell is now a constant.
handle
Go to the label in any of the listed errors occurs in a handle block.
Args: LABEL, ERRCODE OR SET OF ERRCODES
hend
Ends the handle block above.
include
Include contents of specified file.
or directory
Args: PATH TO FILE
#
Inline comment.
##
Frames multiline comment.


## Program Examples

### Hello World

func main
print Hello World
return


### Truth Machine

func main
inp &0 0
beq &0 0 Terminate
label Forever
out 1
goto Forever
label Terminate
out 0
return


### Cat (Echo)

##
Note that inp is storing text as a region of continuous cells from cell one.
&(&0) means "get the value stored at cell 0 and refer to that cell."
&&0 would refer to cell zero of the calling macro (which does not exist) so it is not used here.
##
func main
print Feed the cat\n
input &1 2
label loopStart
cout &(&0)
bneq &(&0) 0 loopStart
return


## Errors

Error                                   (0)
Runtime Error                           (1)
Missing Return; Unexpected End Of File  (3)
Undefined Function                      (4)
Undefined Label                         (5)
Not a Cell; Undefined Address           (6)
Unexpected Argument Type                (7)
More Arguments Expected                 (9)
Missing Main Function                  (10)
Duplicate Function Definition          (11)
Duplicate Label Definition             (12)
Include in Function                    (13)
Stack Overflow                         (15)
Out of Memory                          (16)
Unmatched Parenthesis                  (17)
Numeric Error; Maximum Value is [Int]  (18)
Cannot Modify Constant                 (19)


Whenever possible, an error should describe the function and instruction at which it occurred.

## Proof of Turing Completeness

### An Indirect Proof

A Turing machine is defined as a finite state machine that can operate on an arbitrarily large set of contiguous cells that store information and function as a memory tape. The finite state machine controls a pointer that points to a cell on the tape. The operations a Turing machine can perform are listed as:

• Increment the pointer.
• Decrement the pointer.
• Write to a cell.
• Perform a logical branch.

Any program that can simulate a Turing machine is also Turing complete. The most direct proof is to simulate one, but the cat program requires some of the capabilities of a Turing machine to write an input to memory and output each character.

The cat program uses:

• Memory cells accessed via a pointer (which is also a cell)
• An operation to increment the pointer (add 1) which can be substituted for a decrement by inverting the argument (add -1)
• Operations to read and write to cells.
• A branching operation.

According to the definition above, BunnyBell can simulate all the operations of a Turing machine. Ergo BunnyBell can simulate a Turing machine, proving Turing completeness.

### Proof by Translation to bf

bf is a Turing complete language with 8 commands. It can be proven that BunnyBell is also Turing complete by translating BunnyBell to bf. Assume that cells do not wrap at 0 or 255.

Given a function t, with an an arbitrarily large number of cells and a pointer to any cell stored at cell 0. The following translation can be done.

Translation Table
bf BunnyBell
. cout &(&0)
, inp &(&0) 0
[ beq &(&0) 0 closeBracket :: label openBracket
] bneq &(&0) 0 openBracket :: label closeBracket

(Please note that the double colon should be substituted for a newline.)

## The Debugger

Every BunnyBell interpreter should have a debugger that prints the following at each step:

• The current function call, with arguments.
• The current instruction in full.
• Value stored at the last cell accessed.
• Any program output at that step.

First, note that source files are run from a run directory, and its sub directories.

The linker formats source code so that it can run appropriately. All leading whitespace before an instruction is removed. Additionally, all include statements are processed. The contents of each included files are concatenated into a single set of source.

The include statement includes all the functions in a file so a program can use them. As stated above, include statements include files at the path identified. So...

include run\foo\hw.bbe


... includes the hw.bbe file in a subdirectory foo, in run. Note that the run directory (or folder) is included in the file path. This ensures that the interpreter will look for files in the run directory.

The entire contents of a directory can be included using an asterisk ( * ) like so...

include run\foo\*



The closing angle bracket ( > ) gets replaced with the path from run to hw.bbe . So...

include run\foo\bar\tm.bbe


is equivalent to

include >\bar\tm.bbe


### Handling Cyclic References

A cyclic reference is when a file includes itself, or when files are linked together in a Hamiltonian Cycle. Currently, these are handled by generic case errors. In Macrobeep there is no test case for a cyclic reference (and there should have been!). The challenge lies in handling this case without slowing the linker too much. Ideally, a specific linker error would be thrown for this situation.

## A Practical Esolang?

Esoteric programming languages tend to be programming languages that are highly impractical. How could there be a language that is both practical and esoteric? Indeed there may be objections to the notion of a practical esolang. That said, do not confuse BunnyBell with some ordinary programming language. It pushes the boundaries of what an esoteric programming language can be! BunnyBell innovates into practicality! Is that not great? Is this paragraph not wonderful? Is this good search engine optimization? Programming Language! BunnyBell! May the crawlers notice this humble article as it announces itself! BunnyBell, BunnyBell, Bunny Bell, bunny bell, the programming language calls out into the great wilds of infinity! May it be heard, seen, appreciated! Enjoy this programming language; the world’s most practical esolang!