ADJUST

From Esolang
Jump to navigation Jump to search

ADJUST, for A Divergent Jumble of Unrelated Symbolic Terms, is a two-dimensional esoteric programming language invented by Scott Feeney in 2005. All of the ASCII characters from 32 to 126 are valid instructions; each instruction carries out several operations depending on the prime factors of its ASCII value.

General operation

Execution starts in the lower left corner with the instruction pointer moving upwards and rightwards (that is, diagonally). At any point in time, aside from the stacks and accumulator register (see below), the program state includes the location of the instruction pointer, given by its x and y coordinates, and the direction of the instruction pointer, being any one of the following: left, up-left, up, up-right, right, down-right, down, down-left.

Valid characters are the ASCII characters 32 to 126, which are instructions, and ASCII linefeed characters (10), which separate lines of code. The effect of any other character is undefined. All lines are padded with exclamation marks to the length of the longest line in the code, making the code space rectangular. Leaving the rectangle of code space is an error and results in undefined behavior.

Each character, when encountered, is converted to the list of prime factors of its ASCII value. Each such prime factor is then executed as an instruction, starting with the largest. For example, A has the ASCII value 65, whose prime factorization is 5 x 13. So if an A is encountered, first the 13 command is executed, then the 5 command.

After executing each command for a character, the program moves forward one character, unless one of the commands executed made the program terminate.

Data storage

ADJUST provides two stacks of 8-bit bytes and an 8-bit accumulator register. Initially, the stacks are empty and the accumulator register is set to 0. At any point in time, one stack is said to be lighter than the other if either (1) it is empty, while the other stack has one or more bytes; or (2) the topmost byte on it is larger than the topmost byte on the other stack. Note that the lighter stack is undefined when both stacks are empty or when each stack contains the same topmost byte. When the lighter stack is defined, the heavier stack is defined as the stack that is not the lighter stack. The stacks are arbitrarily referred to as "stack 1" and "stack 2."

All arithmetic done on the accumulator treats the accumulator's value as signed and is computed modulo 256. Bits in a byte are considered to be numbered from 0 to 7, with 0 being the least significant.

Commands

2 Rotate the accumulator three bits to the right.
3 Push the accumulator's value onto the lighter stack, preferring stack 1 if both are equal, and turn 45 degrees left if stack 2 was used, 45 degrees right if stack 1 was used by default because each stack was equally heavy, 90 degrees left if stack 1 was lighter and the accumulator is nonzero, or 135 degrees right if stack 1 was lighter and the accumulator is zero; then move forward once.
5 Flip bit 0 of the accumulator.
7 Move forward once for every bit set in the accumulator.
11 Pop the heavier stack onto the accumulator; or if both stacks have the same value on top, pop that onto the accumulator; or if both stacks are empty, set accumulator to zero.
13 Pop a value from stack 2 and print it to stdout, or do nothing if stack 2 is empty.
17 Read a character from stdin and push it onto stack 1; or if EOF is received, turn 90 degrees to the right if bit 2 of the accumulator is set, then move forward once for each one of bits 3, 4, and 7 that is set. Note that the stacks are left undisturbed if EOF is received, and the accumulator is not changed in any case.
19 Do like instruction 17, but read from stack 2 rather than stdin, and treat stack 2 being empty as EOF.
23 Shift the accumulator five bits left unconditionally.
29 If the accumulator is 0, turn 45 degrees left, move forward two steps, move forward a third step if and only if stack 2 is lighter than stack 1, then turn 45 degrees right.
31 Move forward once.
37 If the lighter stack is defined, copy its value and push that value on the heavier stack. The accumulator is not affected by this operation, nor is the stack that was originally lighter.
41 If the lighter stack is defined, pop a value from the heavier stack and discard it.
43 Shift the accumulator one bit right; then, if the accumulator is now zero, move forward once and turn 90 degrees left.
47 If the lighter stack is defined, pop it onto the accumulator.
53 If stack 1 is the lighter stack, reverse bits 0-3 in the accumulator; otherwise, reverse bits 4-7.
59 Count the number of bits set in the accumulator and turn 45 degrees to the right that many times.
61 Swap the two stacks entirely.
67 Exit the program.

All prime numbers greater than 67 set the accumulator to themselves.

External resources