Rust-native compiler for legacy languages, starting with BASIC.
Multi-frontend by design. Cranelift-backed. Built for standalone release binaries.
elderheim is a universal compiler project for legacy languages. The intended
release model is one downloadable compiler binary per supported operating
system. A user downloads elderheim, chooses the source dialect explicitly, and
compiles old source files without installing Rust, rustc, or Cargo.
The final supported release path is meant to be self-contained:
- A user downloads one
elderheimbinary for their OS and architecture. - A user runs
elderheim program.bas. - No Rust install is required.
- No
rustcis required. - No Cargo is required.
- No C compiler is required.
- No external linker is required for the supported release path, where platform constraints allow it.
- Old source code compiles through
elderheimitself.
The first stable goal is 1.0.0: complete the local-manual-backed Dartmouth
BASIC profiles selected for the first release, implemented in Rust and using
Cranelift for native code generation. Users choose a concrete profile such as
dartmouth-basic-1, dartmouth-basic-2, cardbasic, or
dartmouth-basic-4. Missing Dartmouth editions stay reserved for later
compatibility releases if primary manuals are found; they are not part of the
1.0.0 scope. ANSI and ECMA standards are planned as separate future dialects
such as ansi-basic, ecma-basic-1, and ecma-basic-2.
The 0.30.0 Linux/macOS host C compiler linker path is a temporary bridge for
proving the text runtime ABI and executable flow. It is not the intended
long-term user requirement.
elderheim is licensed under MIT OR Apache-2.0.
v0.60.0 is the Dartmouth BASIC Second Edition and CARDBASIC checkpoint. The
0.50.0 stop completed the manual-backed First Edition work scheduled for
that checkpoint against the local May 1964 manual scan and Dartmouth command
summary. The current tree includes the October 1964 profile differences
implemented from the local Dartmouth manual.
| Capability | Status | Notes |
|---|---|---|
| Cargo workspace | Working | Split into AST, parsers, codegen, and CLI crates. |
| Shared AST | Working | Frontends lower into common language-neutral structures. |
| Dialect routing | Working | CLI accepts explicit dialect selection. |
| Dartmouth BASIC parser core | Working for 0.60 scope | dartmouth-basic-1, dartmouth-basic-2, and cardbasic parse the early Dartmouth numeric statement set, including PRINT, LET, implicit assignment, GOTO / GO TO, IF ... THEN, FOR / NEXT, READ / DATA, DEF FN, STOP, END, comparisons, unary minus, exponentiation, and numeric function calls. |
| Dartmouth BASIC semantic validation | Working for 0.60 scope | Rejects duplicate labels, missing GOTO / IF ... THEN targets, string-vs-numeric type mismatches, unmatched FOR / NEXT, undefined functions, and later-profile features in the active early Dartmouth profiles. |
| Cranelift backend | Working for 0.60 scope | Emits native objects for the active early Dartmouth numeric execution subset, including variables, assignments, control flow, loops, data reads, numeric functions, profile-specific print separators, profile-specific array bounds, and the CARDBASIC matrix commands implemented for this stop. |
| Text runtime/linking | Early | Temporarily uses the host C compiler on Linux/macOS to link supported Dartmouth BASIC text-mode programs; this dependency must be removed from the final supported release path. |
| Unsupported codegen rejection | Working | Unsupported statements fail closed instead of producing wrong binaries. |
| Release/security gates | Working | Formatting, clippy, tests, dependency policy, audit, SBOM, and reproducible-build scripts are present. |
Compatibility is tracked per concrete language or dialect, not by loose family names. A dialect is marked complete only after manual-backed fixtures and the release gate for that stop pass. Reserved entries keep their CLI names and roadmap space, but they are not implementation claims.
| Language or dialect | Status | Comment |
|---|---|---|
Dartmouth BASIC First Edition (dartmouth-basic-1) |
Complete for 0.50 scope | Uses the local May 1964 manual scan plus Dartmouth's command summary. The v0.50.0 pentest/tag stop is clean; remaining Dartmouth work moves to later profiles and the 1.0 compatibility matrix. |
Dartmouth BASIC Second Edition (dartmouth-basic-2) |
Complete for 0.60 scope | Uses the local October 1964 Dartmouth manual as the current planning source; semicolon PRINT packing has executable coverage. Full profile-complete status still depends on the remaining manual compatibility audit. |
CARDBASIC (cardbasic) |
Complete for 0.60 scope | Covered by the local October 1964 Dartmouth manual; one-based array bounds, card-deck strings/comparison mnemonics, post-END data decks without DATA, manual size limits, PAGE, MAT READ, MAT PRINT, MAT ZER, MAT CON, MAT IDN, matrix copy, addition, subtraction, multiplication, transpose, inverse, scalar multiply, column-vector MAT, vector/matrix cases, formula-driven actual dimensions, and active-dimension propagation through MAT arithmetic have executable coverage. Full profile-complete status still depends on the remaining manual compatibility audit. |
Dartmouth BASIC Third Edition (dartmouth-basic-3) |
Reserved | Known Dartmouth line, but no primary manual is available locally yet. |
Dartmouth BASIC Fourth Edition (dartmouth-basic-4) |
Planned | Target 0.70.0. Uses the local January 1968 Fourth Edition manual and text export. |
Dartmouth BASIC Fifth Edition (dartmouth-basic-5) |
Reserved | Needs a primary manual before implementation is scheduled. |
Dartmouth BASIC Sixth Edition (dartmouth-basic-6) |
Reserved | Needs a primary manual before implementation is scheduled. |
Dartmouth Structured BASIC (sbasic) |
Reserved | Needs a Dartmouth-specific primary source; the South-Western Structured BASIC textbook is mapped separately. |
Dartmouth BASIC Seventh Edition (dartmouth-basic-7) |
Reserved | Needs a primary manual before implementation is scheduled. |
Dartmouth ANSI-oriented BASIC (dartmouth-basic-ansi) |
Reserved | Needs a Dartmouth-specific Eighth Edition / ANSI profile source; ANSI and ECMA standards are separate future dialects. |
ANSI Full BASIC (ansi-basic) |
Planned | Mapped from ANSI X3.113-1987 / FIPS PUB 68-2 after the Dartmouth profiles. |
ECMA BASIC (ecma-basic-1, ecma-basic-2) |
Planned | Mapped from ECMA-116; graphics-module support remains a later scope decision. |
| Other BASIC manuals already mapped | Planned | Altair BASIC, Microsoft BASIC-80 / MBASIC, IBM PC BASIC/BASICA, Commodore BASIC, Atari BASIC variants, NEC BASIC variants, Control Data BASIC V2, ZBasic, and QuickBASIC profiles are tracked in the manual map. |
| Non-BASIC languages | Planned | COMAL, Pascal, Logo, Forth, REXX, Algol, Modula-2, Ada, Delphi/Object Pascal, COBOL, Fortran, dBASE/Clipper/FoxPro, and PL/M come after the BASIC-first line. |
See the full Language Release Plan and BASIC Manual Map.
- Standalone compiler goal: released binaries should compile supported source files without requiring users to install Rust, Cargo, a C compiler, or an external linker for the supported release path.
- Rust first: memory-safe implementation with a pinned modern Rust toolchain.
- Cranelift backend: native object-code generation through a Rust-native compiler backend.
- Many frontends, one backend: each legacy dialect gets an isolated parser that lowers into the shared AST.
- Security first: unsupported constructs fail explicitly, dependencies are audited, and releases require SBOM and reproducibility evidence.
Build the workspace:
cargo build --workspaceCheck a BASIC source file:
cargo run -p elderheim -- --dialect dartmouth-basic-1 --check examples/hello.basLink and run a BASIC control-flow example on Linux/macOS:
cargo run -p elderheim -- --dialect dartmouth-basic-1 --emit executable examples/basic-control.bas -o basic-control
./basic-controlPrint the parsed AST:
cargo run -p elderheim -- --dialect dartmouth-basic-1 --emit ast --allow-internal-emit examples/hello.basPrint semantic validation output:
cargo run -p elderheim -- --dialect dartmouth-basic-1 --emit semantic --allow-internal-emit examples/hello.basEmit a native object file for the currently supported minimal program shape:
cargo run -p elderheim -- --dialect dartmouth-basic-1 examples/end.bas -o end.oLink an executable for the current text-output subset on Linux/macOS. This
0.30.0 path currently requires a resolved absolute host C compiler and is
temporary. Set ELDERHEIM_CC=/absolute/path/to/cc to pin the compiler;
otherwise elderheim searches absolute PATH entries only:
cargo run -p elderheim -- --dialect dartmouth-basic-1 --emit executable examples/print-text.bas -o print-textRun the normal local gate:
scripts/checks.shelderheim/
├── crates/
│ ├── elderheim-ast/ # Shared language-neutral AST
│ ├── elderheim-parsers/ # Isolated frontends under src/languages/
│ ├── elderheim-codegen/ # Cranelift backend
│ └── elderheim-cli/ # User-facing compiler binary
├── docs/
├── examples/
├── release-notes/
└── scripts/
| Document | Purpose |
|---|---|
| Architecture | Compiler pipeline, crate boundaries, and frontend/backend model. |
| Versioning Plan | Stop points from 0.10.0 to 1.0.0. |
| Tag Stop Plan | Required local gates before each tag through 1.0.0. |
| Dartmouth BASIC Profiles | Active and reserved Dartmouth profile names. |
| Dartmouth BASIC Source Inventory | Local manual/source status for Dartmouth profile planning. |
| BASIC Manual Map | Manual-to-dialect mapping for BASIC sources and standards. |
| Language Release Plan | Planned manual-backed language and dialect rollout. |
| Roadmap | Current and future language scope. |
| Release Checklist | Required release validation and evidence. |
| Supply-Chain Security | Dependency and tooling review policy. |
| Security Policy | Security checks and reporting guidance. |
The project does not aim to make one giant parser that guesses every old language. Users should choose the dialect explicitly:
elderheim --dialect dartmouth-basic-1 program.bas -o program
elderheim --dialect cardbasic deck.bas -o deck
elderheim --dialect pascal app.pas -o appEach frontend should live in its own Rust source file and lower into the same compiler AST. The backend should remain shared.
