Skip to content

Repository files navigation

Esolang Interpreters

Python License: GPL v3 Coverage

Table of Contents

About

Working interpreters, compilers, and transpilers for esoteric programming languages, each verified against its spec. Most interpreters read the program file from the first command-line argument.

Planned work is tracked in docs/roadmap.md; documented limitations and ruled-out ideas live in docs/limitations.md, with the full wall arguments in docs/walls.md. Annotated example programs — one per state model (tape, stack, OISC, and 2D grid), each traced command by command — are in docs/walkthroughs/.

Usage

Installation

git clone https://github.com/bangyen/esolangs.git
cd esolangs
just install-dev

Running a Program

Interpreters run as modules, with the program file as the first argument (categories: grid_based, stack_based, queue_based, tape_based, register_based, other), or through the esolangs command:

python -m esolangs.interpreters.<category>.<language> program.txt
esolangs run <language> program.txt
esolangs list                          # list the supported languages
esolangs generate <language> "Hello"   # print a program that outputs "Hello"
esolangs transpile BFStack BF program.txt  # rewrite between languages

Most generators emit one long line. --width (optionally --width N, default 80) bounds a program to that many columns for readability — this is how the committed examples are written. Usually that means wrapping the finished program, breaking only between whole commands so it still does the same thing. A generator that builds a shape takes the width itself instead: Clockwise lays its code around a rectangle's perimeter, so it picks the squarest ring that fits rather than being reflowed after the fact (the square is also its default, since that minimises the bounding box). Streetcode and WII2D fold their instruction line into a boustrophedon the pointer walks in the same order, and LaserFuck steers its beam down and back so a long run of tape commands costs rows instead of columns.

Languages whose newlines carry meaning and that cannot re-shape ignore the flag rather than producing a broken program: the remaining 2D grid languages, where a newline starts a new row, and NoComment, which rejects any character that is not a command. A single token longer than the width (a Polynomial coefficient) gets its own line rather than being split, and a shape with an irreducible size — a Clockwise ring, or a LaserFuck decision tree — comes out as wide as it has to be.

Assembly compilers run the same way and write output.asm:

python -m esolangs.compilers.<language> program.txt

Examples

Ready-to-run programs are committed under examples/: examples/hello-world/ holds a "Hello, World!" for each of the 45 languages with a text generator, and examples/boolean/ holds a truth-table program for each of the 54 with a boolean generator (plus one hand-written Minifuck program). Both sets are regenerated by scripts/write_examples.py.

esolangs run Suffolk examples/hello-world/suffolk.txt

Annotated walkthroughs of a few representative programs live in docs/walkthroughs/.

Public API

The package exposes a small typed API:

import esolangs

program = esolangs.generate("Suffolk", "Hello, World!")
output = esolangs.run("Suffolk", program)
esolangs.list_languages()
bf = esolangs.transpile("BFStack", "brainfuck", bfstack_program)

Running the Tests

just test

Implemented Languages

Show all 63 languages

The full capability matrix (generators, cross-check and boolean support, examples) is in docs/languages.md.

Grid-based Languages

Languages that move a pointer or beam across a 2D grid.

Stack-based Languages

Languages that use a stack for data manipulation.

Queue-based Languages

Languages whose primary data structure is a queue or deque.

Tape-based Languages

Languages that operate on a tape (similar to Turing machines).

Register-based Languages

Languages that use registers to store and manipulate data.

Other Languages

Languages that don't fit into the above categories.

Extra Implementations

Show all 5 implementations

Implementations written in languages other than Python, used as cross-check references in CI: most generators are round-trip verified against them. The cross-checks share an exit-code convention mirroring the Python interpreters: 0 = success, 2 = malformed program, 3 = invalid runtime operation.

RISC-V Assembly Implementations

Two further bodies of work live under extra/ without being cross-check interpreters, so they are not listed above:

  • Lean 4 proofs (extra/lean/esolangs) verify generators rather than run programs: that the MAMMALIAN text generator is total over the byte range, that the Factor encoder round-trips (decode (encode code) = code), and that the brainfuck minterm boolean generator computes its truth table. lake build checks them, and CI runs them on Linux.
  • Line (extra/line) implements Line, whose spec is a set of hand-drawn curve images with no text format. Its programs are PNGs rather than text, so it cannot go through the registry's pipeline; it keeps its own renderer, pixel extractor, and interpreter, plus brainfuck and boolean generators that target it. just test-line runs its suites.

Compilers

Show all 16 compilers

Compilers that translate esoteric languages to other target languages.

RISC-V Assembly Compilers

Transpilers

Transpilers rewrite a program in one esolang into an equivalent program in another, and are verified end-to-end: the source runs on its interpreter, the translation runs on the target interpreter, and the outputs must agree.

Every transpiler here is total over its source language: it accepts every program that language's own interpreter accepts. Partial ones are not carried — the admission criteria, and why six earlier transpilers were removed rather than documented as subsets, are in esolangs/tools/transpilers.py.

Source Direction Target
BF 3D Brainfuck
BF Painfuck
BFStack BF
Decleq S*bleq
esolangs transpile BFStack BF program.txt       # rewrite a program into another esolang
esolangs transpile Decleq "S*bleq" program.txt  # emits a Decleq emulator; any program
bf = esolangs.transpile("BFStack", "brainfuck", source)  # or via the API

Tools

Utility programs that work with the esoteric languages.

Boolean Function Generator

The boolean package builds a program that computes a truth table (most-significant input first) in each language with suitable control flow:

from esolangs.tools.boolean import (
    between,
    circlefuck_byte,
    dig,
    polynomial,
    sophie,
    suffolk,
    taglate,
)

dig("0110")  # 2-input XOR in Dig
between("0110")  # the same truth table in Between
suffolk("0110")  # and in Suffolk
sophie("0110")  # and in Sophie
polynomial("0110")  # in Polynomial (up to n = 4)
taglate("0110")  # 2-input XOR in Taglate (up to n = 2)
circlefuck_byte(table)  # arbitrary byte-valued functions

The truth table is a binary string of length 2**n, indexed by the inputs with the most significant first; its length implies the input count, so n is not passed separately. 54 of the languages in the suite have such a generator, some covering only a documented subset of tables.

Program Generator

The text package builds a program that prints a given string in each language with a text generator:

python -m esolangs.tools.text "Hello, World!"

Every generator is also available through esolangs list and esolangs generate (see above); run esolangs list for the full set.

Single-Interpreter Install

Want one interpreter without cloning the repo or installing the package? scripts/install_one.sh fetches that language's interpreter and inlines the shared io and exceptions modules (plus any interpreter it imports, e.g. Factor's brainfuck) into one self-contained file:

curl -fsSL https://raw.githubusercontent.com/bangyen/esolangs/main/scripts/install_one.sh | sh -s Suffolk
python esolangs_suffolk.py program.txt

The language name matches esolangs list (e.g. Suffolk, Nevermind, Forþ). Factor and Polynomial need pip install sympy; the bundled file notes this. scripts/bundle_one.py does the same from a local checkout:

python scripts/bundle_one.py Nevermind

Contributing

Contributions are welcome! If you find a bug or want to add a language, check the roadmap and limitations first, and read CONTRIBUTING.md — including whether the language is worth adding — before proposing one. New languages are registered in src/esolangs/registry.py. Run just test (the full local check: lint, pytest, bandit, and the Python verify scripts) to verify a change.

To run that check automatically on every push:

python scripts/verify.py       # run it once
git config core.hooksPath .githooks   # or run it automatically on every push

License

This project is licensed under the GPL v3 License - see the LICENSE file for details.

About

Interpreters and compilers for esoteric programming languages, from stack-based to modern register-based systems

Topics

Resources

Contributing

Security policy

Stars

12 stars

Watchers

1 watching

Forks

Contributors

Languages