ACRONYM
ACRONYM was created by Tslil Clingman in early 2008, originating from an idea the author had in late 2007. ACRONYM was created to serve the author's wishes for a highly obfuscated language in which no given programme would have major visual differences from any other given programme (with the exceptions of length and format)
Language overview
There are three "Layers" in the language: the 1st and 2nd Memory Layers consist of a two dimensional grid of dimensions 128x128. Each grid cell of a Memory Layer can store an arbitrary integer. The Command Layer consists of a grid of 3x2 commands (with values from 0..5 going left to right, top to bottom).
All grids have a Targeter and a Mover. The Targeter on the current Memory Layer is the Data Origin. The Targeter on the other Memory Layer is the Data destination. The Targeter on the Command Layer is the Data Manipulator. The Mover for any given Layer is always bound to the current row and column of the Targeter of that Layer. The Mover shifts rows and columns up/down//left/right and the Layers are wrap-around.
When a command is executed, the data from the data origin is modified in accordance with the command and then added to the data in the data destination.
The order of the Layers is as follows: the 1st Memory Layer is above the Command Layer which is above the 2nd Memory Layer.
Syntax
The following 19 symbols may be combined to form a valid ACRONYM programme, anything that is not one the following, is considered a comment.
> and < | Move Targeter of current Layer right/left |
^ and v | Move Targeter of current Layer up/down |
|^ and |v | Push the column that the Targeter is in, in the current Layer up/down |
-> and -< | Push the row that the Targeter is in, in the current Layer right/left |
{ and } | Opening curly brackets advances through the Layers, setting the current Layer to one further than the previous, closing them sets it one back |
~ | Takes the Data Origin, applies the Data Manipulator to it and adds it to the Data Destination |
/ and \ | Signifies a loop starting/ending point |
( and ) | Represent the first value in the loop condition, it takes the value of Targeter from the current Memory Layer by default, may contain any other valid commands |
[ and ] | Represent the second value in the loop condition, it takes the value of Targeter from the other Memory Layer by default, may contain any other valid commands |
: and : | Contains the condition for evaluation of the loop values, can be: =, /=, or > (equal to, not equal to, greater than) |
Command Specifics
No-Op (0) | NOT (1) | ONE (2) |
INP (3) | OUT (4) | ERS (5) |
Command effects are as follows:
No-Op | Allows the Origin Data to pass through unhindered and be added to the Destination Data. (No Operation) |
NOT | Multiplies the Origin Data by -1 and adds it to the Destination Data. |
ONE | Transforms the Origin Data into one and adds it to the Destination Data. |
INP | Transforms the Origin Data into the ASCII code of the input and adds it to the Destination Data. |
OUT | Outputs the Origin Data and adds it to the Destination Data. |
ERS | Sets both the Origin Data and the Destination Data to 0. (Only destructive command) |
Language and Syntax Explanations
The Targeter of the Memory Layers is located by default in the top right corner, whereas the Targeter for the Command Layer is located by default in the top left corner.
In order to select the first Memory Layer, we open {. Any commands now issued will be sent to the First Memory Layer. If we open { again, any commands issued will be sent to the Command Layer. Finally, opening { a third time will send all commands to the Second Memory Layer. Closing } will result in the current layer being set one back. Layers are wrap-around so we can do the following: {{{{ which will select the 1st Memory Layer.
A ~ (tilde) may only be executed on a Memory Layer, causing the Data Origin (value under the Targeter) to be modified in accordance with the command and added to the Data Destination (value under the Targeter on the other Memory Layer). This is a non-destructive process, i.e. executing No-Op will result in the Data Origin remaining intact but the Data Destination being modified.
Using | or - will merely shift the current column/row within which the Targeter of the currently active Layer resides. The Targeter will not move and consequently will not reside over the same value prior to the shift as it will after. However, seeing as the girds are of infinite size, the Targeter will wrap around the furthest cell reached of that row/column.
A loop is started at a point in the code using the / (forward slash). The end is marked using a \ back slash). Loops may be nested. The loop condition may be at the beginning or at the end of a loop segment, or both. The basic syntax for a loop is a / or \ followed by ( )'s followed by [ ]'s followed by : :'s. The loop condition functions as follows: The round brackets are the first comparator value in the condition and the Layer within them is defaulted to the Current Layer. The square brackets are the second comparator value in the condition and the Layer within is defaulted to the other Memory Layer.
If a loop is initiated in the Command Layer, the round brackets represent the 1st Memory Layer and the square brackets represent the 2nd Memory Layer.
Both brackets may contain any valid code. The Layer destinations of the brackets are also modifiable, achieved by surrounding the brackets in question by { }'s.
When the closing bracket is reached for a loop comparator value clause, the value under the then currently active Layer's Targeter is taken as that value, thus { }'s inside a loop comparator value clause will not directly affect the value taken.
Finally, any Commands issued within round or square brackets are simulated and do not actually modify any Memory Layers. After having assigned the desired comparator values, we place a colon followed by an =,/= or > sign and another colon. This is the evaluation condition.
Example loops : {/{{(>>)}}[>]:/=: ...code... \} {/(<<)[^<]:>:>^>>>v<|v->{<^^<v|^-<{<<<~}|v}\(>>){{[^<]}}:=:}
Note on Grid Size
This language will, by no account, need an infinitely large grid to be Turing complete. It is possible, due to the fact that a given cell may store an arbitrary integer, to simulate an arbitrary amount of cells within one cell. This is achieved through Prime Factorisation as follows.
A value in a cell (N) is stored by means of the product of Primes, whose exponents are the values of other simulated cells, as such: (2^a) (3^b) (5^c) (7^d) Where a, b, c and d are the values of the simulated cells. In order to increase the value 'stored in cell a', we multiply the value of N by 2, and therefore multiplying by the valueof the associated Prime base increases the value of the simulated cell. Thus, dividing by the value of the associated Prime base will decrease the value of the associated, simulated cell.
The above pattern can be extended to any given amount of Prime bases and therefore cells, illustrating that for a language to be Turing Complete in terms of memory capacity, it need only have one cell for storage which can hold an arbitrary integer, and possibly others to serve as temporary storage to aid in factorisation.
Example Code
Output "T" (84):
{{>>}~~~~~~~~~~~{{-<~}<<} /{{(<){[<<]}}}:>:~{>>{<<}}~{<<{>>~<<}>>}~{<<{>>}}\{>>v}~{^}~~~~~{<}~{<{~}v>}~} (using Fibonacci) or {{>>}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{v<<{~}}}
Hello World:
{{>>{~~~~{-<}~~~~~~~~~{-<-<}}<<} </(<<<){[<]}:>:{>>{~~~~~~~~{<}~{>}}<<}\ ~>{{~{v}}>>>v{~}^<<<}/(<<<){[<<]}:>:{>>{~~~~~~~~{<<}~{>>}}<<}\ ~{>>{vvvvvvvv~~~~~~~~~~~~~~~}<<}~{>>{vvvv~~~~~~~~~~~~~}<<}~ {>>{^^^^^^^^^^~}<<}~{>>{v~~~~~~~{{<<}~}v{~}vvvvvvv{~{>>}}^^^^^^~~~ {{<<}~}vvvv{~{>>}}v~~~}<<}~<{{^^^}}~ {>>{vvvvvv~{{<<}~{>>}}^^^^^^^~~~~~~~~~~~{{<<}~{v>}}^^^^^^}} /{{()}}{[<<<<]}:>:{{~v}}\}