Gemooy
Gemooy is an esoteric programming language designed by Chris Pressey on December 2, 2010. It combines features from 2-ill and Etcha, and adds self-modification. It came about when the author noticed the tape-related semantics of 2-ill were essentially the same as those of BitChanger. There are also some passing similarities to LNUSP, but Gemooy's design was not (consciously) influenced by it.
Contents |
[edit] Program structure
A Gemooy program consists of an unbounded two-dimensional grid of cells; each cell may contain one of three symbols, @, #, or blank. A program text may contain any other symbols, but they are treated as blank cells upon program load. The symbols $ and % have special meaning; $ indicates the initial position of the instruction pointer, % indicates the initial position of the data pointer. All cells outside of the loaded program are considered to contain blanks.
[edit] Program state
Pointing into the grid is an instruction pointer. The instruction pointer is at any time moving in one of eight directions corresponding to the deltas (dx, dy) where -1 <= dx <= 1 and -1 <= dy <= 1 and not (dx = 0 and dy = 0). The instruction pointer is initially travelling southeast (dx = 1, dy = 1).
Also pointing into the grid is a data pointer. The cell under the data pointer can be "incremented", which means:
- If it is a blank, it becomes a
#. - If it is a
#, it becomes a@. - If it is a
@, it becomes a blank.
Decrementation is the inverse operation.
[edit] Program execution
The cells that the instruction pointer passes over are executed. Executing @ causes the direction of the instruction pointer's travel to turn 45 degrees clockwise if the cell at the data pointer contains a blank, 45 degrees counterclockwise if the cell at the data pointer contains #, or not at all if the cell at the data pointer contains @.
Executing # has an effect that depends on direction that the instruction pointer is travelling:
- North = Move data pointer one cell north, skip instruction pointer over next cell.
- East = Move data pointer one cell east, skip instruction pointer over next cell.
- South = Move data pointer one cell south, skip instruction pointer over next cell.
- West = Move data pointer one cell west, skip instruction pointer over next cell.
- Northeast or Northwest = Increment cell at data pointer.
- Southeast or Southwest = Decrement cell at data pointer.
Executing a blank does nothing.
The program terminates when the instruction pointer travels out of bounds, i.e. away from the populated grid and into empty space from which it cannot possibly return.
[edit] Examples
Draw an infinite line of #'s extending eastward:
@@ %
@ $
@ #
#
@# @
@
@
@ @
Toggle (between # and blank) the cells down the leftmost column until the @ is reached:
% @@ @@
# @ $ @
@
# #
#
@
# # #
# #
@ @
@ @@
# @ @ @
@ @ @
Draw a solid line of #'s eastward until a @, then turn around and draw a dotted line of #'s westward on the line below:
% @
@@ @@
@ @ @
@ @
@ $ @
#
#
@ # @# @
@ @
@ #
@ @
@@ @@
@ @ @
@ @
@ @
#
@ #@# @
# @ @
# @ @
@ @@
@ @
@ @
[edit] Computational Class
Despite the probable Turing-completeness of Etcha and 2-ill, the computational class of Gemooy is not known. The particular arrangement of semantics presents some difficulty in achieving an arbitrary effect at an arbitrary point. Namely, if the symbol under the data pointer is a @, and the instruction pointer is moving non-diagonally, it is not possible to change the symbol under the data pointer. If, on the other hand, the instruction pointer is moving diagonally, it is not possible to move the data pointer without first changing the symbol under the data pointer.
This leads to problems in executing the same logic regardless of the current contents of the data pointer. Two (or three) separate execution paths must be built, and they must merge at the end; but they can only merge in two ways:
- Coming into the same
@from two angles like so:
dp is dp is
over blank over #
\ /
\ /
@
|
v
In this case, even after the paths merge, the problem of executing the same logic regardless of the current contents of the data pointer remains, as the contents of the data pointer are still divergent.
- Using
#executed non-diagonally to skip over an intervening@like so:
/
/
<---@#-----
In this case, the data pointer may be over the same symbol in both paths. But what symbol the data pointer is over may change in the horizontal path when # causes the data pointer to move. Thus it is important to be able to predict what that new symbol could be.
From this it seems reasonable to conclude that, at the very least, it is not possible to write a one-to-one Gemooy simulator in Gemooy.
[edit] Trivial Variations
Being essentially a "visible" language, Gemooy does not include any external input or output interface; the idea would be that input to a program would be "drawn" in the playfield alongside it before execution, and execution would likewise "draw" the output to the playfield.
However, adding input and output streams to communicate externally could be useful in e.g. a setting in a Unix-like operating system with pipes and so forth; the author proposes the following trivial variation called Gemooyio. When a # is executed, the effect is as given above, but with the following changes:
- Northeast = If cell under data pointer is blank, output a 0 bit, otherwise output a 1 bit.
- Northwest = Increment cell at data pointer.
- Southeast = Decrement cell at data pointer.
- Southwest = Wait for a bit to arrive on the input stream; if 0, write a blank under the data pointer; if 1, write a
#; if a signal indicating there is no more input, write a@.
It is recommended that the input and output should be considered unbuffered; i.e. if input is coming from a keyboard, input bits are available as soon as reasonably possible after a keystroke is registered. It is also recommended that, if communication occurs in the domain of ASCII characters, character codes are transmitted in eight-bit sequences with the LSB first.
[edit] External Resources
- Gemooy in Chris Pressey's lingography