We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
ABCLang
ABCLang is a minimalistic, Turing-complete esoteric programming language created by User:Jan Ala. It uses only three characters: a, b, and c.
Overview
ABCLang is a stack-based virtual machine language with:
- 3 characters (a, b, c)
- 26 instructions (encoded as 3-character sequences)
- Two stacks (A and B) for data
- One register for temporary storage
- Turing-complete via dual-stack simulation of a Turing machine
Encoding System
Base-26 Digit Encoding
Each base-26 digit (0-25) is encoded as a 3-character abc sequence:
| Value | Code | Value | Code | Value | Code |
|---|---|---|---|---|---|
| 0 | aaa | 9 | baa | 18 | caa |
| 1 | aab | 10 | bab | 19 | cab |
| 2 | aac | 11 | bac | 20 | cac |
| 3 | aba | 12 | bba | 21 | cba |
| 4 | abb | 13 | bbb | 22 | cbb |
| 5 | abc | 14 | bbc | 23 | cbc |
| 6 | aca | 15 | bca | 24 | cca |
| 7 | acb | 16 | bcb | 25 | ccb |
| 8 | acc | 17 | bcc |
Note: ccc is the terminator marker, not a valid instruction or digit.
Numbers
Numbers are encoded in base-26, little-endian format:
42 = 1×26 + 16 = [16, 1] = bcb aab + ccc (terminator marker) = bcbaabccc
Examples:
| Number | Base-26 | Little-Endian | ABC Code |
|---|---|---|---|
| 0 | [0] | [0] | aaaccc |
| 1 | [1] | [1] | aabccc |
| 25 | [25] | [25] | ccbccc |
| 26 | [1,0] | [0,1] | aaaaabccc |
| 42 | [1,16] | [16,1] | bcbaabccc |
| 114 | [4,10] | [10,4] | bababbccc |
Labels
Labels are arbitrary abc strings (length must be a multiple of 3) followed by the ccc terminator.
Instruction Set
All instructions are 3-character abc sequences.
| Code | Instruction | Params | Description |
|---|---|---|---|
| aaa | push | number | Push number onto current stack |
| aab | drop | - | Pop and discard top of stack |
| aac | swap | - | Swap top two elements |
| aba | dup | - | Duplicate top of stack |
| abb | rot | - | Rotate top three: [a,b,c] → [b,c,a] |
| abc | over | - | Copy top of other stack to current stack |
| aca | switch | - | Switch active stack (A ↔ B) |
| acb | pick | - | Copy nth element to top |
| acc | add | - | b + a (pop a, pop b, push b+a) |
| baa | sub | - | b - a |
| bab | mul | - | b * a |
| bac | div | - | b // a (integer division, truncate toward zero) |
| bba | mod | - | b % a (modulo) |
| bbb | not | - | Logical NOT: 0 → 1, non-zero → 0 |
| bbc | load | - | Push register value onto stack |
| bca | store | - | Pop stack into register |
| bcb | readnum | - | Read integer from stdin, push onto stack |
| bcc | readchar | - | Read character (ASCII), push onto stack |
| caa | writenum | - | Pop and output integer |
| cab | writechar | - | Pop and output character (must be >= 0) |
| cac | jmp | label | Unconditional jump |
| cba | jz | label | Pop; if value == 0, jump |
| cbb | jn | label | Pop; if value < 0, jump |
| cbc | call | label | Call subroutine |
| cca | ret | - | Return from subroutine |
| ccb | label | name | Define label |
IMPORTANT: Because the argument is popped first, 'pick' effectively behaves like a 1-based index from the original stack. The element is selected from the remaining stack.
Example:
[0, 1] -> push 2 -> [0, 1, 2] pick 1. pop 2 -> [0, 1] 2. copy index 2 -> [0, 1, 0]
Result: [0, 1, 0] (copied the bottom element)
Data Types
Integers: Arbitrary precision (Python int)
Characters: Unicode codes stored as integers
Labels: Strings of abc characters
Memory Model
Two Stacks
- Stack A and Stack B coexist
- One is active at any time
- switch toggles the active stack
- over copies the other stack's top to the current stack
Register
- Single register R stores one integer value
- load: push R onto current stack
- store: pop from current stack into R
Program Structure
Comments
Any character not a, b, or c is ignored (including spaces, newlines, and punctuation).
Program Termination
The program stops when it reaches the end of the source code (EOF). No explicit halt instruction is needed.
Labels
ccb aaa ccc (define label "aaa") cac aaa ccc (jump to "aaa")
Parameters
- push: followed by a number (base-26 little-endian) then ccc
- jmp/jz/jn/call: followed by a label name then ccc
- label: followed by a label name then ccc
Examples
Hello, World!
aaacacaacccccabaaacbcabaccccabaaaabbabbccccabaaaabbabbccccabaaaacbabbccccabaaacaaaabccccabaaaacaaabccccabaaabaaabaccccabaaaacbabbccccabaaabababbccccabaaaabbabbccccabaaacbbabaccccabaaaacbaabccccab
Factorial
cacbbbcccccbaaacccabaaaaaaccccbaacbbccbcccababbcbabbcaaaaaabcccbaacacaaacccccbbbbcccbcbaaaaabcccbcacbcaaacccbbccaacacccacccccbccbcccccaccbccaccc
Fibonacci
cacbbbcccccbaaacccbbcaaaaabcccbaacbbccbcccaacaaaaaccccacbaccbbcaaaaabcccbaabcacacaaacccccbbbbcccbcbbcaaaaaaacccaaaaabccccbcaaacccaaccaacacccacccccbccbcccccaccbccacccccc