Documentation
Changelog
Dated history of the standalone interpreter, in order: the target/dialect axes, the CLI and monitor, the conformance work, and the review sweep.
Changelog
2026-06-27 — 0.2.0: type punning & value-model targets, FORTRAN 77 by default, the docs site
- 00:00 — Published the FORTRAN 66 reference manual (and F77 Appendix E, the differences from F66);
DOUBLE PRECISIONnow occupies its two genuine storage units inCOMMON/EQUIVALENCE. - 08:19 — Faithful type punning (
word_memory, off by default):COMMON/EQUIVALENCEstored as raw machine words/bytes so cross-type aliasing is bit-faithful — validated against a real PDP-10, which also caught aforbinnegative-double bug. - 09:11 — Pluggable value-model targets: added LP64LE (64-bit little-endian IEEE) and a provisional VAX alongside NATIVE and PDP10; storage is now codec-driven.
- 10:26 — Language features: the
Zhexadecimal edit descriptor, theDOUBLE COMPLEX(COMPLEX*16) type, and the F90RECURSIVEkeyword (per-procedure recursion opt-in). - 11:13 — Reorganized the API/CLI/DESIGN notes into a chaptered forterp manual.
- 12:30 — Engine refactor: extracted
refs.pyandintrinsics.pyleaf modules out ofengine.py(no behavior or performance change). - 13:17 — External-review fixes (faithful out-of-bounds under
word_memory; per-activation recursive localEQUIVALENCE; genuineOPENfailures reportIOSTAT=/ERR=; I/O keywords usable as array names;DOUBLE COMPLEXsized to four units) and a newpyf77command. - 13:49 — Dialect cleanup: split the overloaded
dec_intrinsicsflag intof77_intrinsics/dec_library/uuo_library, so strict F77 no longer acceptsCALL SLEEPorLSH. - 14:46 — FORTRAN 77 is now the default dialect (
run_source/parse_source/ theforterpCLI); F66 is the strict base, FORTRAN10 the DEC superset. - 16:07 — Docs site refocused & recolored: the faded sage-green of the X3.9-1978 cover, a FORTRAN-77-led home page, and a two-level chapter TOC in each manual's left rail.
2026-06-26 — FCVS: the whole conformance corpus now matches gfortran
- 00:24 — Filled the last language gaps the audit corpus needs: COMPLEX numbers in storage and I/O, CHARACTER-valued functions, and several formatted-output edge cases.
- 10:09 — Merged the two test corpora into one 192-routine FCVS suite, and added a second, independent check alongside each routine's own self-test: a byte-for-byte comparison of every routine's output against gfortran.
- 11:19 — Worked through the formatted-I/O punch-list that comparison turned up — a run of number- and text-field parsing and printing edge cases — and taught the harness to count the suite's one deliberately-failing self-test as the pass it is designed to be.
- 13:58 — Traced the remaining differences to their real cause: the test input decks were being rebuilt — lossily — from comments in the source. Vendored the original NIST input decks instead (public-domain, from the gklimowicz/FCVS project). With correct input, gfortran runs all 192 routines, forterp runs them too, and the input/output bugs this exposed are fixed.
- 14:05 — Cleared the final two differences (scientific-notation rounding and scale-factor handling). forterp now matches gfortran on 191 of 192 routines — the lone exception is one field where gfortran disagrees with the test's own stated correct answer and forterp is right.
- 14:28 — Wrote the conformance work up across the docs (see docs/forterp §13).
2026-06-25 — driving the FORTRAN 77 conformance suite to a clean pass
- 14:05 — A run of input-parsing fixes the audits depend on: numeric and list-directed field handling, width-less formats, and a few DO-loop edge cases.
- 16:00 — Direct-access files (record-addressed read/write that survives close-and-reopen), plus more formatted-I/O conformance.
- 18:00 — Real list-directed input and correct end-of-file / BACKSPACE behavior, so the file-I/O audits run as written.
- 20:15 — Hardened the test harness so it can't flatter the results: every routine must run all its declared sub-tests, and the print-only routines are checked against gfortran's output.
- 21:21 — Separated printer-style output from file-style output, then cleared a batch of per-routine differences (FORMAT labels, statement functions, PARAMETER constants, internal files) — taking the self-checking audits to zero failures.
2026-06-24 — FORTRAN 77 support (the f77 branch)
- 15:20 — Added the FORTRAN 77 dialect: the block
IF,DO WHILE,SAVE, and the generic intrinsic functions. - 15:42 — The
CHARACTER(text) data type end to end — variables, concatenation, comparison, substrings, and the string intrinsics — and character-based I/O, including treating a string as an in-memory file and theINQUIREstatement. - 16:36 — Restored the 140 FORTRAN-77 / CHARACTER audit routines and stood up their conformance baseline, then rounded out the F77 front end (keyword-style I/O lists, list-directed I/O,
PARAMETER, assumed-size arrays, the.EQV./.NEQV.operators, and assorted syntax) until the whole corpus parses. - 19:28 — File handling for the audits — scratch files for unconnected units and full FORMAT round-tripping — taking the F77 corpus to zero runtime errors.
- 20:13 — Caught a harness bug that had been hiding 111 failures, and added gfortran reference outputs so the print-only routines are checked without needing gfortran installed.
2026-06-24 — the monitor rename, override docs, and PyPI release wiring
- 09:58 — Dropped the
@builtindecorator alias —@fcall/@uuoare the two authoring decorators; "builtin" stays the registry noun (register_builtins/builtins_in/BUILTINS). Synced the guides + CHANGELOG to the host-layer work. - 10:23 — Reformatted this changelog as reverse-chronological day blocks (newest first), terse timed one-liners.
- 10:44 — Renamed the interactive shell
Monitor→CommandProcessor(forterp.command) and dropped the REPL'sMONITORreserved word — freeing "monitor" for the executive facade. - 10:59 — Renamed the
@uuofacadeHost→Monitor(monitor(eng),eng.monitor, themonitor=builder kwarg) —monnow abbreviates its actual type. - 11:09 — API guide: how to override the
Monitorfacade with your own (subclass + inject viamonitor=oreng.monitor; the bundleduuolibUUOs read the engine seam directly, not the facade). - 11:33 —
_load_builtinsno longer leakssys.path/sys.modules; theSTRarg mode strips a packed word's padding so it equals the literal text. - 11:38 — Documented the
hostlib.host_ppn/host_useridentity helpers alongsidemon.identity. - 11:56 — PyPI release wiring: publish through the
forterp-pypienvironment, with a manual approval gate (thereleaseenvironment + a required reviewer) fronting the tag-triggered publish. - 11:57 — Released 0.1.0 to PyPI (
pip install forterp). - 14:02 — The interactive command processor opens with an interpreter-style banner (version, dialect, target, host) and gains
COPYRIGHT/CREDITS/LICENSEcommands. - 14:02 —
^Cat the interactive prompt re-prompts instead of dumping a traceback (the command processor and the REPL);^Cduring a program run halts cleanly (?Interrupted, rc 130).
2026-06-23 — host services, terminal modes, and real binary files
- 02:17 —
hostlibSTRarg mode:args=(STR,)gives the body a Pythonstr(a quoted literal verbatim, or a packed word decoded via the target codec), lifting the StrLit-vs-packed resolution out of each body. - 04:05 — Real FOROTS binary files (opt-in
Engine(dec_files=True)): on-disk word↔byte packing + LSCW framing (forbin), validated against the V5 D-7/D-8 example byte-for-byte; plus end-to-end host-routine docs (API@fcall/@uuo+ arg modes +raw, DESIGN §7a). - 09:56 — Terminal echo-control seam (
Engine(set_echo=fn)+mon.tty.echo); renamed the host-services facadeHostServices/host_services→Host/host. - 12:24 —
run_sourceinstalls a default terminal echo (runtime.default_terminal_echoflips the tty's termiosECHO, restored after); added the autowrap seam (set_autowrap+mon.tty.autowrap,TRMOP..TONFC). - 17:50 — Host identity (
mon.identity— uid/gid/login/PPN);GETTABmodels the job tables (.GTPPN→ guest[0,0],.GTJTC→ 0), with aneng.gettabregistry andUnmodeledMonitorTablefor the rest. - 21:14 — Review fixes:
OUTSTRuses the target'schars_per_word; restored theOPENread'swith; a hostbuiltins=table no longer shadows a program-defined unit; a stdlib-shadowing.pyarg gives a clean?-diagnostic. - 21:52 — Two-word DOUBLE PRECISION binary I/O (the KL10 doubleword, lossless where the single rounded);
_bin_words/_assign_wordscode per declared type, per element; a config-mismatched binary file fails loud (OSError) instead of a garbage text read. - 23:29 — FORTRAN-10 free CR-LF:
emit()wraps terminal output at the carriage width host-side (Engine(tty_width=80, tty_autowrap=True), deferred margin); strict F66 never wraps; CLI--no-wrap.
2026-06-22 — host services for the embedder
- 12:33 —
hostlibhost-services half: a baselineHostServicesfacade (tty/files/clock, over the engine's host seam) + an@uuodecorator that injects it — the counterpart to@fcallfor routines that talk to the host; injectable viaeng.host_services.@builtin/@fcall/@uuogainalias=/origin=. - 13:17 — CLI
--recover-shifted-cols(opt-in shifted-column recovery); a dropped-in*.pymay define aregister(eng)hook, andrun_sourcegainssetup=fn(eng). - 14:43 —
OPENdecodes a packed numericFILE=/NAME=as a SIXBIT/ASCII filename (as it already doesDEVICE=), notstr()of the raw word. - 14:53 —
pyfortran10defaults--target pdp10(andpyf66staysnative), matching the prebuilt interpreters. - 16:21 —
uuolib: the standard TOPS-10 monitor UUOs (OUTSTR/OUTCHR/MSTIME/SLEEP/GETTAB), installed under the FORTRAN-10 dialect on the engine's host seam.
2026-06-21 — genuine-source demos, then the release-readiness sweep
- 16:16 —
demos/: genuine 1970s FORTRAN run as-is — netlib EISPACK/LINPACK/FFT/RKF45 with drivers, DECUS-tape sources, and Paul Boltwood's 1971 Game of Life. - 16:16 —
examples/: short Python scripts driving forterp as a library. - 16:16 — Multi-file linking: several source files linked by unit name, like
f77 main.f lib.f. - 16:16 — Dialect gaps closed (gated; F66 still rejects them): the optional comma before an I/O list, two-word
END FILE,DATAas an array name. - 16:16 —
READ/ACCEPTEOF fix: terminal input past end-of-stream branches toEND=instead of looping. - 16:16 — Sequence-association fix: an array element passed where the dummy is an array is re-viewed as a based array (LINPACK/RKF45 work-vector passing).
- 16:18 — Readability pass: clearer names, smaller focused dispatchers.
- 16:40 — Error-handling pass: clean
?-diagnostics in place of raw tracebacks. - 17:15 — Trimmed the evaluator hot path (~1.5× on tight loops).
- 18:14 — Capped a single array/
COMMONallocation; wrote down the interpreter-not-a-sandbox trust model. - 18:26 — Correctness vs
gfortran(differential testing): per-record carriage control, list-directed grammar, three-digit exponents. - 18:52 — Extended the dual-run harness to compare terminal output; pinned the public-API contracts.
- 20:00 — Packaging & CI: PyPI/distribution readiness —
build+twine, a 3.9–3.13 test matrix. - 20:13 — Committed the built docs site, kept in sync automatically by a pre-commit hook.
- 20:51 — Hardened the resource limits,
INCLUDEresolution, and duplicate-unit detection. - 20:58 — Tag-triggered PyPI release via OIDC Trusted Publishing, gated on tests/lint/format and
tag == __version__. - 21:42 — Docs hygiene: folded the origin history into this changelog; removed the HISTORY/HANDOFF/third-party files; recorded FCVS as public domain; trimmed the overuse of "faithful".
- 22:41 — ruff maintained at commit time (a pre-commit hook), with import-sort and dead-
noqarules. - 23:06 — CLI
--version; moved the engine builders intoforterp.runtime. - 23:23 — Slimmed the package root to exactly
__all__— dropped the back-compat aliases. - 23:33 —
forterp.debug.oob_census(): a public OOB-access census, so consumers no longer poke engine internals. - 23:47 — New docs: a CLI reference and a
forterp.*API programmer's guide. - 23:51 — Docs-site polish: a "Docs" breadcrumb, interpreter-design vocabulary on the home-page pipeline, a high-contrast beta stamp.
- 23:58 — CLI loads
.pyhost-routine modules beside FORTRAN source: a*.pyargument is imported and its@builtinroutines are discovered (hostlib.builtins_in) and registered — drop them in, no registry/__init__.
2026-06-20 — real-machine defaults, host marshalling, docs site
- 00:00 — The
fortran10preset drops cols 73+ by default; shifted-column recovery is opt-in. - 17:03 —
hostlib: a declarative marshalling layer for host builtins. - 23:25 — A GitHub Pages docs site: a
markdown-it-pystatic-site generator (gh-pages/), Actions deploy.
2026-06-19 — CLI, monitor, REPL, debugger, conformance
- 00:00 — Three console front-ends:
pyf66,pyfortran10,forterp --std. - 00:48 — Gated the DEC I/O surface, intrinsics, and random-access I/O under F66; added the V5 math/rotate intrinsics.
- 01:11 —
--check: parse and list diagnostics without running. - 10:16 — An interactive command monitor (a TOPS-10
.-prompt descendant). - 10:20 — An immediate-mode REPL, then refactored onto two reusable primitives.
- 11:03 — Factored target/dialect config into shared registries +
engine_kwargs. - 12:31 — An off-by-default per-statement tracer hook; on it, a debugger + profiler.
- 14:24 — Formatted-input conformance; fixed the random-access write clobber; CLI error hygiene.
- 21:10 — Exposed the embedding API; added the prebuilt
fortran10/f66interpreters. - 21:47 — Gated every non-F66 feature behind a
Dialectflag; dual-run F66 tests under both dialects. - 22:11 — Illegal
EQUIVALENCEshapes now raise; documented the multi-word storage boundary. - 23:06 — list-directed/NAMELIST bad fields raise like formatted;
forbinrejects unrepresentable floats.
2026-06-18 — pluggable seams, then standalone
- 08:58 — A pluggable
OPENdevice registry. - 09:23 — Extracted the machine value model behind a pluggable
Target. - 09:43 — Parameterized the front-end dialect (
Dialect). - 11:23 — A
fortran10layer atop thef66core; moved FOROTS binary I/O into it. - 13:44 — Split out to a standalone repo — a
src/package with a clean public API and the FCVS corpus. - 14:09 — Routed every wrap/pack/truthy site through
Target(INT/LSH, the logical algebra, the char codec). - 14:47 — Added the
NATIVE64-bit target and made it the default;PDP10the opt-in machine. - 15:19 — A provisional, unvalidated
VAXtarget. - 15:39 — Curated the FCVS corpus to F66-only (dropped the 140 F77/
CHARACTERroutines). - 16:25 — Adopted
rufflint +ruff format. - 23:59 — Renamed
f66→forterp; madeF66the default dialect.
2026-06-17 — hardening for the next program
- 22:49 —
COMMONsizing, dummy procedures, continuation comments, lowercasenHHollerith.
2026-06-16 — and so it begins...
- 15:29 — Initial FORTRAN-10 / F66 interpreter: lexer, parser, AST, tree-walking engine, the FORMAT runtime, the
forliblibrary, diagnostics. - 16:07 — F66 §3.1.6 blanks-insignificance, via a tokenizer parse-retry.
- 18:49 —
RAN/SETRAN, COMPLEX formatted input, NAMELIST and random-access I/O,%FTNLIDwarnings. - 18:51 — FOROTS binary-record codec (LSCW framing + DEC-10 float),
MODE='BINARY'. - 23:12 — Front-end: DEC TAB-format source, the bare main program, integer-vs-
.EQ.lexing.