81
- Not to be confused with 8.
- Note that 81 is always italicized.
Paradigm(s) | Imperative |
---|---|
Designed by | User:Waffelz |
Appeared in | 2025 |
Memory system | Cell-based |
Dimensions | one-dimensional |
Computational class | Turing complete |
Reference implementation | Unimplemented |
File extension(s) | *.81 |
About
81 is an esolang created by User:Waffelz during class because he was bored. It is entirely based on base-81 literals, whose digits are listed in the table below:
X0 | X1 | X2 | X3 | X4 | X5 | X6 | X7 | X8 | X9 | |
0X | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
1X | A | B | C | D | E | F | G | H | I | J |
2X | K | L | M | N | O | P | Q | R | S | T |
3X | U | V | W | X | Y | Z | a | b | c | d |
4X | e | f | g | h | i | j | k | l | m | n |
5X | o | p | q | r | s | t | u | v | w | x |
6X | y | z | ! | @ | # | $ | % | ^ | & | * |
7X | + | / | | | \ | < | > | ~ | ` | ? | = |
8X | _ |
In 81 code, number literals are surrounded in brackets ([...]
), and memory addresses are surrounded in braces ({...}
). It has a set of 28 opcodes, which are Turing-complete.
Memory
There are 43,046,721 memory cells, indexed from [0] to [ _ _ _ ], all initialized as 0. They can store integers from 0–15,009,4635,296,999,120, or [0] to [ _ _ _ _ _ _ _ _ ]. It has built-in 5 registers — an accumulator (A
), 3 general-purpose registers (RX
/RY
/RZ
), and an overflow flag (V
).
Commands
(M1
/M2
represent arbitrary memory addresses, C1
/C2
represent arbitrary number literals, and label
represents an arbitrary label.)
CPY C1 M1 | Copies the value of C1 to M1. |
INC M1 | Increment the value of M1. |
DEC M1 | Decrement the value of M1. |
ADD C1 C2 | Add the values of C1 and C2 and store it in the accumulator. |
SUB C1 C2 | Subtract the values of C1 and C2 and store it in the accumulator. |
MUL C1 C2 | Multiply the values of C1 and C2 and store it in the accumulator. |
DIV C1 C2 | Divide the values of C1 and C2 and store it in the accumulator, rounding down if necessary. |
POW C1 C2 | Raise the value of C1 to the value of C2 and store it in the accumulator. |
CLR M1 | Reset the value of M1 to 0. |
SWP M1 M2 | Swap the values of M1 and M2. |
EQL C1 C2 | Store 1 in the accumulator if C1 is equal to C2, else 0. |
NEQ C1 C2 | Store 1 in the accumulator if C1 is not equal to C2, else 0. |
GRT C1 C2 | Store 1 in the accumulator if C1 is greater than C2, else 0. |
LSS C1 C2 | Store 1 in the accumulator if C1 is less than C2, else 0. |
) label | Define a label for use with JMP or related commands. |
JMP label | Move code execution to the specified label. |
JEQ C1 C2 label | Move code execution to the specified label if C1 is equal to C2, else continue normally. |
JNQ C1 C2 label | Move code execution to the specified label if C1 is not equal to C2, else continue normally. |
JGR C1 C2 label | Move code execution to the specified label if C1 is greater than to C2, else continue normally. |
JLS C1 C2 label | Move code execution to the specified label if C1 is less than C2, else continue normally. |
JCD C1 label | Move code execution to the specified label if C1 is 1, else continue normally. |
RET | Move code execution to the instruction after the last executed JMP (or related) command. |
OUT C1 | Output the Unicode character whose codepoint is stored in C1. |
INP | Take one character as input and store its Unicode codepoint in the accumulator. |
†NOU C1 | Output the number in C1 in base 10. |
†NIN | Take one base-10 number as input and store it in the accumulator. |
HLT | Halt the program. |
NOP | No-op (does nothing). |
†This operator exists solely for user-friendliness. The programmer must use base 81 internally.
Note: A HLT
command is not required for a program.
Syntax/Semantics
The syntax of 81 is very simple. Every command is on its own newline, followed by its arguments separated by one space.
81 has two types of comments — a normal (inline) comment, and a header. Inline comments are delimited via @
, and everything after is ignored by the runtime. A header comment must be on its own line, and is surrounded by three equal signs (=== ... ===
).
Example Programs
- Note: These programs contain the original comments from the draft of 81.
“Hello, World!”
OUT [/] @ H (72) OUT [1K] @ e (101) OUT [1R] @ l (108) OUT [1R] @ l (108) OUT [1U] @ o (111) OUT [i] @ , (44) OUT [W] @ (32) OUT [16] @ W (87) OUT [1U] @ o (111 OUT [1X] @ r (114) OUT [1R] @ l (108) OUT [1J] @ d (100) OUT [X] @ ! (33) HLT
Fibonacci Numbers
=== input collection === NIN @ iteration count CPY A RX === edge cases === JEQ RX [0] _ JEQ RX [1] c1 JEQ RX [2] c2 === prepare memory == CPY [0] {0} CPY [1] {1} DEC RX DEC RX === set up output === OUT {0} OUT [D] OUT {1} === main loop === ) loop ADD {0} {1} @ calculate the next number based on @ the current ones in memory JCD V err @ jump to )err on an overflow OUT [D] @ output a space, then the number NOU A @ this stops trailing spaces in the CPY {0} A @ program’s output. SWP {0} {1} @ keep only what’s needed for the next DEC RX @ iteration JGR RX 0 loop === 0 edge case === ) _ HLT === 1 edge case === ) c1 NOU {0} HLT === 2 edge case === ) c2 NOU {0} OUT [D] NOU {1} HLT === overflow error === ) err OUT [*] @ E (69) OUT [1X] @ r (114) OUT [1X] @ r (114)
Primality Check
=== input collection === NIN @ the number to check CPY RX A === handle n = 0 or 1 edge cases === JLS RX [2] N/A === prepare memory === CPY RY [2] @ the current integer being divided === main loop === ) loop @ if RY^2 > RX, and the loop is still going (meaning @ it passed), stop the program MUL RY RY JGR A RX p @ if RX % RY != 0, stop the program DIV RX RY MUL A RY SUB RX A JEQ A [0] _ @ increment RY and loop INC RY JMP loop === primality check indeterminant === ) N/A OUT [?] @ N (78) OUT [l] @ / (47) OUT [$] @ A (65) HLT === primality check passed (prime) === ) p OUT [_4] @ T (84) HLT === primality check failed (not prime) === ) _ OUT [+] @ F (70) HLT