๐ฅ Welcome to the Dragon's Lair
CMRA is a tiny esoteric programming language (esolang) that explores reversible execution through a dragon-themed syntax. Programs can change their traversal direction at runtime: ascend with soar or descend with dive.
Two interpreters stand guard: the Fire Dragon (cmra.py) with expressive aliases, and the Shadow Dragon (cmrash.py) with minimal commands.
Origin
CMRA began as a workshop project I attended by
Tushar Sadhwani
during a college multifest. The prototype we built lives in
prototype.py, and a nonโaliased baseline can be found in Tusharโs
esolangs
repository. You can also read his blog at
tush.ar.
This is a tiny side project made for fun and learning. If you build something cool
or want to improve the interpreter, reach out on
GitHub (@Chimera418)
or Discord gamingchimera.
๐งช Why an esolang?
- Experimental control flow: A single global
DIRECTION walks the program forwards or backwards.
- Concept-first design: Meant for learning, puzzling, and play โ not for production.
- Minimal surface area: Just variables, expressions, prints, and directional checks/blocks.
- Readable flair: Dragon-flavored aliases make intent obvious and fun.
โก Quick start
Option 1 โ pip install (recommended)
Install from PyPI to get the cmra command inside your virtual environment:
# From the project root, with your venv activated:
pip install cmra
# Development install from source (optional):
pip install -e .
# Then run any .cmra or .cmrash file:
cmra "test cases\test.cmra"
cmra projects\fizzbuzz.cmra
cmrash "test cases cmrash\test.cmrash"
Option 2 โ PowerShell wrapper (no install needed)
.\cmra.ps1 "test cases\test.cmra"
Option 3 โ Python directly
# Fire Dragon
python -m cmra.cli "test cases\test.cmra"
python .\cmra.py "test cases\test.cmra"
# Shadow Dragon
python .\cmrash.py "test cases cmrash\test.cmrash"
# Also works with `py` instead of `python`
py cmra.py "test cases\test_strings.cmra"
Option 4 โ CMRA Esoteric Language Extension
For the best developer experience, install the official extension:
Run command: Extension execution defaults to python -m cmra "<file>", with optional override via cmra.executablePath.
Diagnostics: `.cmra` shows themed randomized messages; `.cmrash` shows concise technical messages focused on = syntax.
Diagnostic message examples
- Fire Dragon:
Line 4: 'x' is but a myth in this realm. (Hint: bind before use)
- Fire Dragon:
Line 5: Fire Dragon rejects '=' in this chant. (Hint: use bind)
- Shadow Dragon:
Line 4: Undefined variable 'x'. (Hint: initialize with =)
- Shadow Dragon:
Line 5: Unexpected 'bind' in .cmrash. (Hint: use =)
Full diagnostics catalog: cmra-vscode-extension/ERROR_MESSAGES.md.
Option 5 โ Standalone Executable (Windows)
Don't have Python? Download the standalone cmra.exe from the GitHub Releases to run programs natively!
๐ See GUIDE.md for the full user guide including loop patterns and tips.
๐ฒ Languages
Shadow Dragon (cmrash.py)
The minimalist path โ direct and powerful:
- Variables:
x = 3
- Print:
print x + 5 (numbers or quoted strings)
- Conditionals:
- Inline:
check x < 5 : print x
- Block:
check x < 5 : { ... }
- Direction:
reverse toggles global direction
- Nested inline checks:
check a < 10 : check flag == 1 : reverse
Fire Dragon (cmra.py)
The expressive path โ commands that speak of power:
bind โ assignment (e.g., x bind 3)
roar โ print (e.g., roar x + 1 or roar "hello")
sniff โ conditional (inline or block)
dive โ set direction downwards (forward)
soar โ set direction upwards (reverse)
murmur โ comment/no-op for the rest of the line
Equivalence: soar โ simplified reverse (set reverse). dive sets forward.
๐งญ Execution model
- Programs step line-by-line with a global
DIRECTION: 1 = forwards, -1 = reverse.
- CMRA:
dive sets forwards; soar sets reverse. Simplified: reverse toggles.
- Block
sniff/check returns into the block (first/last line) so a reverse inside takes effect immediately.
- Numbers are floats; strings use single/double quotes.
+ concatenates if either side is a string.
- Precedence:
*, / > +, - > comparisons.
Block entry ritual
- True + forward โ jump to the first line inside the block
- True + reverse โ jump to the last line inside the block
- False โ skip past the entire block
๐ Reusable loop patterns
Flagged loop (inline)
flag bind 1
sniff cond : sniff flag == 0 : dive
flag bind 0
sniff flag == 0 : ;;; body
sniff flag == 0 : ;;; step
flag bind 1
sniff cond : sniff flag == 1 : soar
Block loop (brace style)
flag bind 0
sniff cond :
{
sniff flag == 1 : dive
sniff cond : flag bind 1
sniff flag == 1 : ;;; body
sniff flag == 1 : ;;; step
sniff cond : flag bind 0
sniff flag == 0 : soar
}
Tip: Guard body/step with flag so reverse traversal doesnโt repeat the body. Apply the same pattern to nested loops.
๐บ๏ธ Keyword mapping
| Fire Dragon (CMRA) |
Shadow Dragon (Simplified) |
Description |
bind | = | Assignment |
roar | print | Print expression |
sniff | check | Conditional |
dive | โ | Set forward direction |
soar | reverse | Set reverse direction |
murmur | โ | Comment/no-op |
Note: The simplified language has only reverse. CMRA splits direction control into dive (forward) and soar (reverse).
๐งฉ Examples
Inline check (CMRA)
sniff x <= 10 : roar x
Block check (CMRA)
sniff x < 5 : {
roar "inside"
}
Simplified reverse with nested checks
check x < 5 : {
print x + 5
check flag == 1 : reverse
}
๐ฎ Tests & projects
All tests live in test cases/:
test.cmra โ Hello + loop using sniff/dive/soar
test_strings.cmra โ String literals and concatenation
test_arith.cmra โ Arithmetic precedence (expected: 7, 9)
test_cond.cmra โ Inline conditions (expected: ok, then 3)
test_block.cmra โ Block-style sniff (expected: inside, then after)
Cool projects
projects/story_adventure.cmra โ Interactive text adventure
projects/calculator.cmra โ Factorial, series sum, power (both loop styles)
projects/countdown.cmra โ Countdown and reversible counters
projects/fizzbuzz.cmra โ FizzBuzz with counter-based modulo
projects/bouncing_ball.cmra โ Frame-by-frame bouncing ball effect (no terminal control required)
Run them
# Test cases
cmra "test cases\test_block.cmra"
cmra "test cases\test_strings.cmra"
# Projects
cmra projects\calculator.cmra
cmra projects\countdown.cmra
cmra projects\fizzbuzz.cmra
cmra projects\story_adventure.cmra
# Legacy single-file interpreter (optional)
python .\cmra.py "test cases\test_block.cmra"
โ ๏ธ Dragon's wisdom (pitfalls & tips)
๐ฅ Beware the reverse flame
Direction reversals re-traverse lines. Without a guarding flag, assignments and prints will repeat. Use the loop patterns above.
๐ฅ String growth inferno
Concatenating inside unguarded loops = exponential string growth. Build strings once per forward pass, guard with flags.
๐ฅ Numbers are floats
All numbers parse as floats (2 โ 2.0). Want integers? Adapt tokenization to parse ints before floats.
๐ฅ Nested dragons
Nested loops work, but every inner body needs flag guards. Without guards, inner loops re-execute on reverse passes.
๐ฌ Reach Out
If you build something cool with CMRA or want to collaborate, feel free to connect:
๐ฆ File inventory
cmra.py โ Fire Dragon interpreter (alias keywords, inline + block sniff)
cmrash.py โ Shadow Dragon interpreter (check, print, reverse, braces)
prototype.py โ Compact baseline with inline sniff
keybind.txt โ Keyword mapping cheatsheet
index.html + styles.css โ This site
projects/ โ Showcase programs
test cases/ โ Examples and regression tests
๐ ๏ธ Extending the language
Want to add new commands? Follow this pattern:
- Top-level dispatch โ Add your command alongside
roar/print.
- Inline action executor โ Enable it in nested
sniff/check statements.
Study how roar, bind, dive, and soar are implemented in both interpreters.