81

From Esolang
Jump to navigation Jump to search
Not to be confused with 8.
Note that 81 is always italicized.
81
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