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.
Elderheim depends on primary historical manuals to keep dialect support accurate. If you have leads on Dartmouth BASIC Third Edition, Dartmouth BASIC Versions 5 through 7, SBASIC, or other legacy language references, please use the GitHub discussion: Seeking Historical Documentation.
1.0.0 is the active first stable compiler workstream. The fixed
first-stable Dartmouth support set is dartmouth-basic-1,
dartmouth-basic-2, cardbasic, and dartmouth-basic-4. The main remaining
release blocker is replacing the temporary host C compiler linker path with a
supported standalone executable path through elderheim itself.
The dartmouth-basic-4 profile has executable coverage
for numeric INPUT, RESTORE / RESTORE* / RESTORE$, ON ... GOTO,
INT, SGN, repeatable RND with RANDOMIZE / RANDOM reseeding,
PRINT TAB(...), adjacent PRINT items, semicolon numeric PRINT spacing,
apostrophe comments, nested GOSUB, scalar string variables, scalar string
DATA / READ, and scalar string INPUT, plus the numeric MAT subset
including list and omitted-bound forms, numeric MAT INPUT, NUM / DET,
string vector MAT READ / MAT INPUT / MAT PRINT, plus CHANGE between
scalar strings and numeric vectors.
The dartmouth-basic-4 profile covers BASIC source programs compiled by
Elderheim. It does not implement the historical Dartmouth timesharing
environment around BASIC: teletype session commands, EDIT ..., library lookup
with ***, and paper-tape workflows are outside the compiler-language profile.
| Capability | Status | Notes |
|---|---|---|
| Cargo workspace | Working | Split into AST, BASIC frontend, parser routing, 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 active profiles | dartmouth-basic-1, dartmouth-basic-2, cardbasic, and dartmouth-basic-4 parse the active Dartmouth source-language statement sets. Fourth Edition includes numeric INPUT, RESTORE / RESTORE* / RESTORE$, ON ... GOTO / ON ... GO TO, INT floor semantics, COT, SGN, repeatable RND with RANDOMIZE / RANDOM reseeding, one-line multi-argument DEF FN, multiple-line DEF / FNEND with boundary validation, PRINT TAB(...), adjacent PRINT items, semicolon numeric PRINT spacing, apostrophe comments, nested GOSUB, scalar string variables, scalar string DATA / READ, scalar string INPUT, string vectors with MAT READ / MAT INPUT / MAT PRINT, numeric MAT including list and omitted-bound forms, numeric MAT INPUT with & continuation, NUM, DET, and CHANGE. |
| Dartmouth BASIC semantic validation | Working for active profiles | Rejects duplicate labels, missing branch targets, string-vs-numeric type mismatches, unmatched FOR / NEXT, undefined functions, later-profile features in earlier profiles, and unsupported constructs before codegen. |
| Cranelift backend | Working for active numeric and scalar string subset | Emits native objects for the active Dartmouth execution subset, including variables, assignments, control flow, loops, numeric and scalar string data reads, numeric and scalar string input, numeric functions, one-line multi-argument DEF FN, scalar string and string-vector assignment/printing/comparison, profile-specific print separators, PRINT TAB(...), profile-specific array bounds, CARDBASIC matrix commands, and the Fourth Edition numeric MAT list and omitted-bound forms / MAT INPUT / NUM / DET / string-vector MAT READ / MAT INPUT / MAT PRINT / RESTORE / ON ... GOTO / SGN / CHANGE source-language profile. |
| Text runtime/linking | 1.0 cutover | The temporary host C compiler path still links the full supported text runtime. The native Linux x86_64 ELF path can already link relocation-free programs plus string and integer PRINT programs without a C linker; completing native runtime coverage remains the active 1.0.0 blocker. |
| Unsupported codegen rejection | Working | Unsupported statements fail closed instead of producing wrong binaries. |
| Release/security gates | Working | Formatting, clippy, tests, dependency policy, audit, SBOM, reproducible-build scripts, release artifact validation, and permanent pentest evidence 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) |
Complete for 0.70 scope | Uses the local January 1968 Fourth Edition manual and text export. Current executable source-language profile covers numeric INPUT, RESTORE / RESTORE* / RESTORE$, ON ... GOTO / ON ... GO TO, Fourth Edition INT floor semantics, COT, SGN, repeatable RND with RANDOMIZE / RANDOM reseeding, one-line multi-argument DEF FN, multiple-line DEF / FNEND with function-name result variables, local GOSUB / RETURN, and boundary validation, PRINT TAB(...), adjacent PRINT items, semicolon numeric PRINT spacing, apostrophe comments, nested GOSUB, scalar string variables/comparisons, scalar string DATA / READ, scalar string INPUT, indexed string-vector INPUT, string vectors with MAT READ / MAT INPUT / MAT PRINT, numeric MAT list and omitted-bound forms, numeric MAT INPUT with & continuation, NUM, DET, and scalar string/numeric vector CHANGE. Historical teletype/editor/library/paper-tape workflows are out of compiler scope. |
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.
- Language-family frontend crates: each language family gets its own local workspace crate by default, while all frontends lower into the shared AST and backend.
- 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.shRun the focused 0.80.0 BASIC matrix gate before pentest:
scripts/validate-basic-matrix.shRun the focused 1.0.0 release-assets gate before release or pentest:
scripts/validate-release-assets.shelderheim/
├── crates/
│ ├── elderheim-ast/ # Shared language-neutral AST
│ ├── elderheim-basic/ # BASIC language-family frontend
│ ├── elderheim-parsers/ # Frontend routing facade
│ ├── 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. |
| Crate Boundaries | Local crate strategy and when to split language families. |
| Modularity Policy | 500-line file policy and split rules. |
| 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. |
| BASIC Compatibility Matrix | Active, reserved, and planned BASIC dialect compatibility status. |
| Language Release Plan | Planned manual-backed language and dialect rollout. |
| Release Artifacts | Package naming, target matrix, and release asset validation. |
| Roadmap | Current and future language scope. |
| Release Checklist | Required release validation and evidence. |
| Security Controls | Required compiler, release, and CodeQL controls. |
| Threat Model | Assets, trust boundaries, and residual risks. |
| Supply-Chain Security | Dependency and tooling review policy. |
| Pentest Reports | Permanent pentest digest process and release reports. |
| 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 language family should live in its own local workspace crate by default, with dialect/profile modules split inside that crate. The backend should remain shared.
