Browse Source

docs: CALC-COMPILE.md — the session log and the concrete next-session plan

Nine stages landed in one session (ladder 7791 -> 10350, inside CALC.INC), each
a commit with a tag.  This records them as a table, states the verified baseline
(run_all ALL PASS, matrix 67/67, 58 linked / 56 executed; nonvacuity 86 ok/0),
and replaces the stale "next rung is an ENUM" text with an ordered plan driven
by what the ladder will actually hit: the string value parameter at 10350, then
file operations, variable-index subscripts + `with`, pointers, `var` params,
6-byte real, the string builtins, CRT, recursion, case labels - and then the two
out-of-ladder gates: the layout change (§3) and raising the exec boot sector's
8 KB read so a 27,901-byte CALC.COM can boot.

Also fixes the stale "everything below is measured against 2ae00d1" line.
Eric Streit 11 hours ago
parent
commit
3a98e044a9
1 changed files with 102 additions and 25 deletions
  1. 102 25
      CALC-COMPILE.md

+ 102 - 25
CALC-COMPILE.md

@@ -9,8 +9,10 @@ It is deliberately **not** the same goal as `CALC-PORT.md` (porting MicroCalc to
 native GNU Modula-2 on top of `Term.mod`). That is a separate piece of work and a
 separate session; nothing here changes it, and nothing here depends on it.
 
-Everything below is measured against the tree at tag `v-TP3-INTERRUPT-RESTORE`
-(`2ae00d1`) unless it is marked **inferred** or **unknown**.
+The measurements were taken against the tree at tag `v-TP3-INTERRUPT-RESTORE`
+(`2ae00d1`); the ladder and the stages have moved on since (HEAD is
+`v-TP3-CALC-FILES`, and §1's rung table and the "Session state" section are the
+current figures).
 
 ---
 
@@ -386,16 +388,33 @@ ladder order (each stage removes the blocker the previous one exposed).
 
 ### Session state — where to resume
 
-Last touched 2026-10-19. **Stages 1-4 are landed** — the measuring device, the
-`{$I}` include, the lexical character constants, and the scalar typed constant.
-The ladder row now sits on **sets**.
+Last touched 2026-10-19. **Nine stages are landed in one session** (Stages 1-4,
+sets increment 1, enums, record types, array declarations, element/field access,
+and file types). The ladder row has moved repeatedly, from the first typed
+constant at 7791 to **10350, inside `CALC.INC`** — the compiler now accepts all
+of `CALC.PAS`'s own declarations and is compiling the include's body.
 
-- **HEAD** `ce7e8cd` (the plan) plus the Stage 1, 2 and (this one) 3+4 commits.
-  Nothing pushed; `origin/master` is behind.
-- **Stage 1 (the ratchet) is landed:** `tests/fixtures/calc_ladder.tsv` +
-  `tests/calc_ladder.sh`, wired into `run_all.sh` as `CALC ladder`. The row was
-  **proved red first** and may only move forward; it has moved once:
-  `ERR 1 7791` → **`ERR 102 7972`**.
+The nine commits and their tags, in order (each is one rung with its own
+fixture, red proof, and — where the harness allows — execution under qemu and
+Exec86):
+
+| commit | tag | ladder after |
+|---|---|---|
+| `a2b09a9` | `v-TP3-CALC-LADDER` | `ERR 1 7791` (the measuring device) |
+| `7eec556` | `v-TP3-CALC-INCLUDE` | `ERR 1 7791` (include does not move it: it is at 9404) |
+| `c40d29b` | `v-TP3-CALC-TYPEDCONST` | `ERR 102 7972` |
+| `eed46b2` | `v-TP3-CALC-SETS` | `ERR 41 8098` |
+| `a7d06cd` | `v-TP3-CALC-ENUMS` | `ERR 102 8362` |
+| `7be2276` | `v-TP3-CALC-RECORDS` | `ERR 1 8705` |
+| `123193d` | `v-TP3-CALC-ARRAYS` | `ERR 102 9202` |
+| `2a31b35` | `v-TP3-CALC-ELEMACCESS` | `ERR 102 9202` (element access) |
+| `14dbcdb` | `v-TP3-CALC-FILES` | **`ERR 102 10350`** (inside `CALC.INC`) |
+
+- **HEAD** `14dbcdb` (`v-TP3-CALC-FILES`). Nothing pushed; `origin/master` is
+  behind by nine commits.
+- **The measuring device:** `tests/fixtures/calc_ladder.tsv` +
+  `tests/calc_ladder.sh`, wired into `run_all.sh` as `CALC ladder`. The row may
+  only move forward; every move is recorded in the tsv next to the blocker.
 - **Stage 2 (`{$I file}`) is landed.** `ExpandIncludes` resolves includes as a
   pre-pass (not in `Skip`, because `DeclaresProc`'s lookahead rewinds `srcPos`),
   `Compiler.SetSource` gives the compiler the source path so an include resolves
@@ -483,20 +502,78 @@ The ladder row now sits on **sets**.
   to implement for §3 — match the original's orientation, or a dynamic data
   base with fixups. Everything else in the stages below is mechanical.
 
-### Next session
-
-**The next rung is an ENUM.** The ladder stops at `ERR 41 8098` on
-`Attributes = (Constant, Formula, Txt, OverWritten, Locked, Calculated)`: a
-type whose definition is a parenthesised list of identifiers, which `ParseType`
-has no arm for. Land the enumeration type next (Stage 5), then the set-over-enum
-lines at `CALC.PAS:121,127` follow immediately, and the rest of the set
-operations (run-time `in`, set variables, `+`/`*`/`=`/assignment) alongside.
-
-The storage decision that sets needed is **settled and recorded** (Stage 6): a
-typed constant's bytes live in the code stream behind a `jmp`, addressable
-through `DS`; no `seg cs`, because a `.COM` is one segment. That is the same
-decision the enum-indexed array of strings (`CALC.INC:767-778`) and `XPOS` will
-use, so it does not need re-litigating.
+### Next session — the concrete plan
+
+The ladder is at `ERR 102 10350`, **inside `CALC.INC`**.  Everything below is
+ordered by what the ladder will hit next, not by the original stage numbers
+(which the measurements have already reordered twice).  Each item is the same
+shape as this session's nine: one focused change, one fixture that is red before
+and green after, an execution proof where the image fits, and a commit.
+
+1. **A string VALUE parameter** — the current rung:
+   `procedure Center(S : AnyString)` (`CALC.INC:17`).  `ProcFunc` refuses a
+   parameter wider than a word; a `string[n]` parameter is `n+1` bytes.  TP3
+   passes a large value parameter how?  Check `TPSRC7`'s parameter machinery
+   (and `RESUME-TP3.md` §3.11, which covers `var` parameters: SEG then OFFSET).
+   The cheap first cut is a string parameter passed **by address with a copy
+   into a callee slot** the way TP3 does, or - if that is the wrong shape - a
+   loud `Err` and move on.  `var` parameters proper are item 4.
+2. **The rest of the declaration part**, if the rung is still there: local
+   `type`/`const`/`var` inside a nested function (`CALC.INC:767-778`, the
+   enum-indexed array of strings), `Succ`/`Pred`/`Ord`/`Chr`.
+3. **File OPERATIONS** (`Assign`, `Reset`, `Rewrite`, `Close`, `EndOfFile`,
+   `IoResult`; `read`/`write` with a leading file argument).  Runtime entries
+   doing `INT 21h` open/create/read/write/close, text-mode newline and `^Z`.
+   The file *types* and variables are already in place (`FileVarSize`).
+4. **Variable-index subscripts** (`Sheet[FX,FY]`, `XPOS[Ch]`, `b[i]`) and
+   **`with`** — scaled run-time addressing; the second dimension strides by the
+   first range's count.  Constant indices and `.field` are already done.
+5. **Pointers and the heap** (`^T`, `New`, `Dispose`, `Buffer^[i]`), 4-byte
+   (offset then segment); the heap must hold `Pages` (16,281 bytes).
+6. **`var` parameters by reference** (SEG then OFFSET; 2 bytes per value
+   parameter, 4 per `var`), and **remove the silent by-value acceptance**.
+7. **6-byte `real`** — literals, `+ - * /` and the six comparisons,
+   `and`/`or` on results, integer conversions, `Str`/`Val` with widths and
+   decimals, and `ln`/`exp`/`abs`/`sqrt`/`sqr`/`sin`/`cos`/`arctan`/`int`.
+8. **The string builtins** (`length`, `copy`, `delete`, `insert`, `str`, `val`)
+   and named string constants.
+9. **The CRT identifiers** (`GotoXY`, `LowVideo`/`NormVideo`, `ClrEol`,
+   `ClrScr`, `KeyPressed`, `Delay`, `Read (Kbd, Ch)`) — needed for CALC to
+   *resolve*; a running CALC needs them right, which is a later question.
+10. **Recursion, `forward`, nesting** — `Fact` (direct self-recursion) and
+    `Expression`/`Factor` (mutual via `forward`, the definition repeating only
+    the name).
+11. **The `case` labels** (`^E`, `^X, ^J`, `#27`, comma lists) once `case` over
+    enumerators and chars is reached.
+
+Then the two that are *outside* the ladder and gate the goal as stated:
+
+12. **The layout change (§3)** — re-orient the image so the compiler can emit
+    CALC's **16,560 bytes** of code and hold **12,032 bytes** of data; the
+    port's `dataBase := rtSz + 1000H` caps code at 4 KiB.  Decide "match the
+    original" (data low, code high) vs a dynamic data base with fixups, and
+    re-baseline `t43_codewindow` in the same commit.  This is the only stage
+    that blocks *emitting* the whole program.
+13. **Raise the execution harness's read.**  `tests/exec/bootcom.s` reads 16
+    sectors (8192 bytes); `t64_arrays` is already compile-only for that reason,
+    and CALC's measured `.COM` is **27,901 bytes**.  Without this, "executable
+    tested" cannot be demonstrated for CALC even once it compiles.
+
+**Two things settled this session, not to re-litigate:**
+
+- **The typed-constant storage decision** (Stage 6): a typed constant's bytes
+  are emitted in the code stream behind a `jmp`, addressed through `DS`; no
+  `seg cs`, because a `.COM` is one segment.  Sets, `XPOS` and (later) the
+  enum-indexed string array all use it.
+- **The byte-checker's clause F** (`check_8086.py`) cannot assert "sweeps clean
+  ⇒ pure code" over a region that holds code-resident constant DATA; fixtures
+  that emit such data are listed in `CODE_RESIDENT_CONST` and the clause is
+  skipped for them.
+
+**Still open from the plan (§6):** the layout decision above, and Q6 (one
+memory-mode `TURBO` run in dosemu to see whether CALC reports overflow #99).
+
+The per-stage entries below are the historical record of how each landed.
 
 **Stage 1 — the ratchet (§1). DONE.** `tests/calc_ladder.tsv` +
 `tests/calc_ladder.sh`, wired into `run_all.sh`; proved red against 7792 before