The MDL Programming Language

The MDL Programming Language manual (vendored)

The authoritative MDL/MUDDLE language reference — The MDL Programming Language by S.W. Galley and Greg Pfister (MIT LCS, 1979) — converted to Markdown.

  • Source: https://github.com/taradinoc/mdl-docs (vendored 2026-06-27)
  • 24 chapters + 9 appendices (00-front-matter.mdappendix-9-*.md); start at index.md.

One local addition. 00-front-matter.md opens with a title page that is not part of the upstream transcription, which begins at the abstract. It is a reconstruction, marked as such in a note on the page itself, assembled only from bibliographic facts the transcription already carries: title, authors, institution, date, the releases described, and the sponsor and distribution statements. Nothing else in this directory has been changed; on a re-vendor, re-apply that block and drop nothing else.

We use it as the spec to check pymdl's fidelity against. Most useful files:

File For
appendix-2-predefined-subroutines.md the full SUBR/FSUBR catalogue (coverage below)
appendix-3-predefined-types.md the complete primitive/built-in TYPE list
06-data-types.md, 07-structured-objects.md type system, REST/BACK/TOP views
08-truth.md FALSE vs everything-else semantics
14-data-type-declarations.md #DECL grammar (our decl.py)
17-macro-operations.md DEFMAC/macro expansion
21-interrupts.md, 22-storage-management.md interrupts (implemented), GC (stubbed)

SUBR coverage vs Appendix 2 (re-measured 2026-06-30)

273 / 275 catalogued F/SUBRs implemented (~99%). The only two missing are PCODE (the pure-code-vector builder) and REP (the LISTEN-loop function); both are facilities pymdl models differently rather than omits (see below).

The full manual — chapters 1–24 and all nine appendices — has since been audited chapter by chapter. No witnessed difference remains open. The divergences that are accepted rather than closed are documented where each lives -- matxgp.mud for MAT's XGP switches, test_mudbug.py for SUBRFY's surviving source, test_its_call.py for .CALL LOAD, builtins2.py for a SAVE taken under opaque code -- because a tracker listing only closed and accepted items is a tracker with nothing to track.

Correctness audit (manual's worked examples)

tests/test_manual_examples.py runs the manual's own <form>$ ⇒ result pairs verbatim (chapters 4, 7, 8, 13). All pass. This caught real association bugs now fixed: PUT/GET did not fall back to PUTPROP/GETPROP when the indicator wasn't a FIX/OFFSET (they errored), and PUTPROP returned the value instead of the item (ch.13).

Known gap (xfail): <==? .A (!.A)>T in the manual (ch.8) — a SEGMENT in Direct Representation of a LIST is non-copying, so the rebuilt list shares storage. pymdl copies, so it returns #FALSE (). Subtle representation detail, not exercised by Zork.

What's deliberately different

These are modelled differently rather than implemented identically, because they don't map onto a pure-Python host:

  • Compiled code / RSUBRs (ch.19): RSUBR/RSUBR-ENTRY construct and CHTYPE but don't execute PDP-10 machine code; where the game needs a compiled routine it is supplied as a Python substitute. No PCODE code generation, fixups, or linking.
  • Garbage collection (ch.22): pymdl rides on Python's GC, so GC/BLOAT/ BLOAT-STAT/PURIFY are stubs and SUBSTITUTE is a no-op.
  • Internal storage model (appendix 1): Python objects, not 36-bit TYPE/value pairs, dope words, byte pointers, or control-stack frames; TUPLE shares VECTOR storage.
  • Interactive LISTEN loop (ch.16): no REP/L-INS/L-OUTS/LAST-OUT (the host is batch / line-buffered).
  • Error names (appendix 4): all 152 error atoms are interned (so NAME!-ERRORS references resolve), but errors signal with ad-hoc message strings rather than the canonical NAME!-ERRORS atoms.

Everything else is implemented, including the areas earlier versions of this note listed as missing: coroutines (PROCESS/RESUME/RESUMER/MAIN/ME/STATE/ SUICIDE/1STEP), the interrupt system (EVENT/HANDLER/ON/OFF/INT-LEVEL/ DISMISS and READ/WRITE monitors), IPC (SEND/SEND-WAIT/IPC-ON/IPC-OFF over Unix-domain sockets), locatives (LLOC/GLOC/AT/IN/SETLOC/LOCATIVE?), FREEZE/GROW, the transcendental math SUBRs (SIN/COS/ATAN/SQRT/EXP/LOG), and file/decl I/O (READ/READB/PRINTB/LISTEN/LOAD/FLOAD/GET-DECL/ PUT-DECL/DECL-CHECK/SORT/REMOVE/CLOSURE).