Hexagony is (to the best of the author’s knowledge) the first two-dimensional esoteric programming language on a hexagonal grid. Furthermore, the memory layout also resembles a (separate) hexagonal grid. The name is a portmanteau of “hexagon” and “agony”, because… well, give programming in it a go.
Hexagony is Turing-complete.
Using Hexagony
There are a number of Hexagony implementations and a few ways to run them:
- The easiest way to your feet wet is SirBogman’s fantastic online IDE hexagony.net (running its own JavaScript-based interpreter).
- If you prefer an offline experience, Timwi’s Esoteric IDE also supports Hexagony (running its own C#-based interpreter).
- If you’re looking for a command-line interpreter, SirBogman has written a fast C#-based interpreter. This interpreter also runs on code.golf.
- And finally, there’s the original reference implementation in Ruby, which you can find in this very repo. Usage notes are at the bottom of this README. You can also use this interpreter online at Try it online!
An honourable mention goes to Timwi’s HexagonyColorer. While this doesn’t let you run Hexagony code, it’s a nifty tool for annotating code paths in Hexagony programs:
Overview
Hexagony has a number of important (and partially unique) concepts which need introduction.
Source code
The source code consists of printable ASCII characters and line feeds and is interpreted as a pointy-topped hexagonal grid, where each cell holds a single-character command (similar to how “normal” 2D languages like Befunge or ><> interpret their source as a rectangular grid). The source code must always be a regular hexagon. A convenient way to represent hexagonal layouts in ASCII is to insert a space after each cell and offset every other row. A hexagon of side-length 3 could be represented as
. . .
. . . .
. . . . .
. . . .
. . .
where each .
could be a command (incidentally, .
is a no-op in Hexagony). The next larger possible source code would be
. . . .
. . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . .
. . . .
Because of this restriction, the number of commands in the source code will always be a centred hexagonal number. For reference, the first 10 centred hexagonal numbers are:
1, 7, 19, 37, 61, 91, 127, 169, 217, 271
When reading a source file, Hexagony first strips all whitespace characters. Then each `
(backtick) are removed as well, but the characters after those backticks are marked with a “debug flag”. Then the remaining source code is padded to the next centred hexagonal number with no-ops and rearranged it into a regular hexagon. This means that the spaces in the examples above were only inserted for cosmetic reasons but don’t have to be included in the source code. The following three programs are identical:
a b c
d e f g
h . . . .
. . . .
. . .
But note that
would instead be the short form of
As an example for the debug flag, in the following code, the interpreter would print detailed debug information whenever the ?
is executed:
. . .
. .`? .
. . . . .
. . . .
. . .
The exact presentation of the debug information is up to the interpreter, but it should be possible to read off the following information:
- The positions and directions of the instruction pointers.
- Which instruction pointer is active.
- The values and positions of all non-zero memory edges.
- The position and orientation of the memory pointer.
These concepts are explained below.
Interpreters are allowed to omit this feature (and just strip backticks along with whitespace) provided they allow step-by-step debugging with access to the above information.
Control flow
Hexagony has 6 instruction pointers (IPs). They start out in the corners of the source code, pointing along the edge in the clockwise direction. Only one IP is active at any given time, initially the one in the top left corner (moving to the right). There are commands which let you switch to another IP, in which case the current IP will make another move (but not execute the next command), and then the new IP will start by executing its current command before making its first move. Each IP has an index from 0
to 5
:
0 . 1
. . . .
5 . . . 2
. . . .
4 . 3
The direction of an IP can be changed via several commands which resemble mirrors and branches.
The edges of the hexagon wrap around to the opposite edge. In all of the following grids, if an IP starts out on the a
moving towards the b
, the letters will be executed in alphabetical order before returning to a
:
. . . . . a . . . . k . . g . .
a b c d e . . b . . . . j . . . h . . a
. . . . . . g . . c . . . . i . . e . i . . b .
. . . . . . . . h . . d . . . . h . . d . . j . . c . .
f g h i j k . i . . e . . g . . c . k . . d . .
. . . . . . j . . f f . . b . . . e . .
. . . . . k . . . . a . . f . .
If the IP leaves the grid through a corner in the direction of the corner there are two possibilities:
Picture an infinite hexagonal grid (which is separate from the source code). Each edge of the grid has a value (a signed arbitrary-precision integer), which is initially zero. That is, the memory layout is essentially a line graph of a hexagonal grid.
The memory pointer (MP) points at one of the edges and has an orientation along that edge. At any time, there are three relevant edges: the one pointed at (the current memory edge), and its left and right neighbours (i.e. the edges connected to the vertex the MP’s orientation points to).
It is possible to manipulate the current edge in several ways. The unary operators operate on the current edge only. The binary operators take the left and right neighbours as operands and store their result in the current edge. It is