|
|
@@ -26,19 +26,21 @@ Everything below is measured against the tree at tag `v-TP3-INTERRUPT-RESTORE`
|
|
|
2. **Compile first, run second.** The gate is the compiler's verdict, not a
|
|
|
working spreadsheet. A construct may be *incomplete* only if it is *loudly*
|
|
|
incomplete (`Err (ENoLib)`); it may never be accepted and mis-compiled.
|
|
|
- This project has already shipped that bug once and it is currently shipping
|
|
|
- it twice:
|
|
|
+ This project has already shipped that bug once. One of the two cases below
|
|
|
+ is now closed (Stage 2); the other is not:
|
|
|
|
|
|
- `var` parameters are **silently accepted and passed by value** —
|
|
|
`ProcFunc` drops the `var` (`DropB (MatchKey (tok))`, comment "VAR
|
|
|
parameter recorded as value in this milestone"); `writeln (g)` after
|
|
|
`q (g)` prints `7`, not `42`. Ten CALC routines take `var` parameters.
|
|
|
- - `{$I CALC.INC}` is **silently swallowed as a comment**, so `CALC.PAS`
|
|
|
- without its include compiles green. Measured:
|
|
|
- `program p; {$I part.inc} begin halt end.` → `OK code=32 data=4`, with
|
|
|
- `part.inc` never opened.
|
|
|
+ - `{$I CALC.INC}` was **silently swallowed as a comment**, so `CALC.PAS`
|
|
|
+ without its include compiled green (`program p; {$I part.inc} begin halt
|
|
|
+ end.` → `OK code=32 data=4`, `part.inc` never opened). **Closed at Stage
|
|
|
+ 2**: the include is expanded before parsing and an unopenable file is
|
|
|
+ error 90, not a comment.
|
|
|
|
|
|
- Both must be closed by implementation, and until then by an explicit `Err`.
|
|
|
+ The `var`-parameter case is still open and must be closed by
|
|
|
+ implementation, or by an explicit `Err` until it is (Stage 10).
|
|
|
|
|
|
3. **One fixture and one ratchet per step.** Every stage lands with a fixture
|
|
|
that is provably red before and green after, plus a move of the ratchet
|
|
|
@@ -98,6 +100,11 @@ Current rungs (measured today, normalised positions):
|
|
|
| 8060 | `SetOfAttri = Set of Attributes` (`ERR 102`, `ENoLib`) |
|
|
|
| 8237 | `CellRec = record` (`ERR 102`, `ENoLib`) |
|
|
|
|
|
|
+The include is at normalised `9404`, **after** the current stop, so Stage 2
|
|
|
+does not move the row (it is pinned by t56/t57/t58 instead); the first rung
|
|
|
+that moves it is Stage 4, which removes the 7791 blocker and lets the compiler
|
|
|
+reach the include and everything behind it.
|
|
|
+
|
|
|
---
|
|
|
|
|
|
## 2. The census — what CALC actually needs
|
|
|
@@ -109,7 +116,7 @@ stripped.
|
|
|
|
|
|
| construct | where | status today |
|
|
|
|---|---|---|
|
|
|
-| `{$I CALC.INC}` | `CALC.PAS:150` | **swallowed silently** |
|
|
|
+| `{$I CALC.INC}` | `CALC.PAS:150` | **done (Stage 2)** — expanded before parsing; `t56`/`t57`/`t58` |
|
|
|
| typed constants (`X : T = v`) | `CALC.PAS:111,113,114,137`; `CALC.INC:777` | `ERR 1` |
|
|
|
| enum type `(Constant,Formula,…)` | `CALC.PAS:120` | `ERR 41` |
|
|
|
| subrange types `'A'..'G'`, `0..20`, `string[70]` | `CALC.PAS:117,119,130` | OK |
|
|
|
@@ -349,17 +356,26 @@ ladder order (each stage removes the blocker the previous one exposed).
|
|
|
|
|
|
### Session state — where to resume
|
|
|
|
|
|
-Last touched 2026-10-19. **No compiler change has been made yet** — Stage 1 is
|
|
|
-the measuring device, not a compiler feature, so the front end is still exactly
|
|
|
-the *pre*-CALC baseline that every later stage must build on.
|
|
|
+Last touched 2026-10-19. **The front end now has its first CALC feature** — the
|
|
|
+`{$I}` include (Stage 2) — and the measuring device (Stage 1) under it.
|
|
|
|
|
|
-- **HEAD** `ce7e8cd` (this document) plus the Stage 1 commit. Nothing pushed;
|
|
|
- `origin/master` is behind.
|
|
|
+- **HEAD** `ce7e8cd` (the plan) plus the Stage 1 and Stage 2 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 is
|
|
|
`CALC.PAS ERR 1 7791`, and it was **proved red first** (row set to 7792 →
|
|
|
`FAIL expected ERR 1 7792 / actual ERR 1 7791`, rc 1) before the real value
|
|
|
- was written back. The compile matrix is still **56/56**.
|
|
|
+ was written back.
|
|
|
+- **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
|
|
|
+ beside its including file, and the errors are TP3's own: 90 file-not-found, 96
|
|
|
+ illegal nesting. Fixtures `t56_include` (OK, and its `.out` proves the
|
|
|
+ included procedure runs), `t57_include_missing` (ERR 90),
|
|
|
+ `t58_include_nest` (ERR 96). `TextBuf.InsertStr` is the new bulk,
|
|
|
+ capacity-checked paste. **The ladder row does not move** — the include is at
|
|
|
+ normalised 9404 and the compiler still stops at 7791 — which is expected and
|
|
|
+ pinned by the three fixtures instead.
|
|
|
- **One surprise on resuming:** the working tree was found holding the
|
|
|
nonvacuity script's *frame-rule* mutation of `shell/Compiler.mod` (the
|
|
|
`locFree := 0FFFEH` / pre-decrement-base revert), i.e. a mutation from a
|
|
|
@@ -369,8 +385,8 @@ the *pre*-CALC baseline that every later stage must build on.
|
|
|
byte-for-byte the same for INTEGER locals, so the compile matrix would have
|
|
|
been green and only `t40_readln` (and later CALC) would have noticed.
|
|
|
- **Verified baseline, run on this commit:** `./tests/run_all.sh` →
|
|
|
- **OVERALL: ALL PASS**, compile matrix **56/56**, CALC ladder **1/1**. Those are
|
|
|
- the numbers Stage 1's ratchet must leave intact.
|
|
|
+ **OVERALL: ALL PASS**, compile matrix **59/59**, CALC ladder **1/1**, 49 `.COM`
|
|
|
+ linked and 49 executed under both qemu and Exec86.
|
|
|
- **Not re-run this session:** `tests/nonvacuity.sh` (78 ok / 0 failed at the
|
|
|
last run). It is not in the default `run_all.sh` and must be run **manually**
|
|
|
after touching any check — including, now, `run_compile_tests.sh`'s
|
|
|
@@ -413,22 +429,44 @@ it was set to 7791. It also resolved Q4 in favour of staging copies in
|
|
|
`tmp/calc_ladder/` rather than teaching the compile matrix about companion
|
|
|
files.
|
|
|
|
|
|
-**Stage 2 — `{$I file}` include.** Small, self-contained, and a prerequisite:
|
|
|
-`CALC.PAS:150` *is* the program.
|
|
|
-- In `Skip` (`Compiler.mod:1315`), the `{$` path currently reads a letter and a
|
|
|
- sign and discards to `}`. Split it: `{$I+}` / `{$I-}` stay the I/O-check
|
|
|
- toggle (`dirs.chk`, used at `CALC.INC:396,399`); `{$I <name>}` reads a file
|
|
|
- name and splices that file's text into the buffer at `srcPos`.
|
|
|
-- `{$A-}` (`CALC.INC:712`) is not a TP3 directive; being ignored is correct.
|
|
|
- But *unknown-but-evaluated* directives must not be the same code path as
|
|
|
- *include*: a directive we cannot honour is an `Err`, not a comment.
|
|
|
-- Design points: path resolved relative to the including file; a nesting cap;
|
|
|
- an unopenable file is an error; the splice grows `srcLen` and leaves `srcPos`
|
|
|
- moving forward so `pos` stays meaningful (see the ratchet trap in §1).
|
|
|
-- Fixture: a pair (`*.pas` + a companion `.inc`) — **check first that
|
|
|
- `run_compile_tests.sh` can stage a companion file**, which is an open
|
|
|
- question (§6 Q4). Prove red by the current behaviour:
|
|
|
- `program p; {$I part.inc} begin halt end.` compiles OK today.
|
|
|
+**Stage 2 — `{$I file}` include. DONE.**
|
|
|
+
|
|
|
+Implemented as a **pre-pass, not in `Skip`**, and that is the one design point
|
|
|
+worth recording. `Skip` is called by lookahead routines (`DeclaresProc`,
|
|
|
+`PeekKw`, `KwAhead`) that save and restore `srcPos`; splicing inside `Skip`
|
|
|
+runs once during the lookahead and again for real, and the second pass sees the
|
|
|
+first splice's text and reports error 96 (and a splice grows the buffer, which
|
|
|
+a rewind cannot undo). So `ExpandIncludes` resolves every include in one
|
|
|
+forward scan *before parsing*, and the parser — including `DeclaresProc`'s scan
|
|
|
+for a `PROCEDURE` keyword, which must see a procedure that lives only in the
|
|
|
+include — sees one finished buffer. The scan recognises what the lexer does (a
|
|
|
+quoted literal, then star-paren comments, then brace comments, then a brace
|
|
|
+directive), so `{$I}` written inside a comment stays inert (t56 depends on it).
|
|
|
+
|
|
|
+- `{$I <name>}` is spliced at the directive (buffer grows, `srcLen` updated) in
|
|
|
+ the **expanded-buffer** coordinates the ladder already measures in; `{$I+}` /
|
|
|
+ `{$I-}` remain the I/O-check toggle (`dirs.chk`, `CALC.INC:396,399`).
|
|
|
+- Path resolved against the **including file's** directory — the compiler now
|
|
|
+ gets the source path through `Compiler.SetSource`, called by the three
|
|
|
+ loaders. Extension defaults to `.PAS` when absent (TPSRC10 `kpasext`).
|
|
|
+- An unopenable file is **error 90** ("File not found", TPSRC10 `cdincl` `errb`)
|
|
|
+ at the directive; a nested include is **error 96** ("Illegal nesting of
|
|
|
+ include files", TPSRC10 `cdincl`). Both measured, not assumed.
|
|
|
+- `{$A-}` is in fact a real TP3 directive (TPSRC10:783, Absolute code) that TP3
|
|
|
+ accepts and this port ignores; the "not a TP3 directive" note was wrong. The
|
|
|
+ rule that mattered is kept: an include can never fall through to the comment
|
|
|
+ path.
|
|
|
+- Fixtures: `t56_include` (+`t56_include.inc`, red 41 → green OK, and its
|
|
|
+ `.out` proves the included procedure *runs*), `t57_include_missing`
|
|
|
+ (red OK → `ERR 90`), `t58_include_nest` (+`t58_include_a.inc`, red OK →
|
|
|
+ `ERR 96`). Q4 resolved: the compile matrix needs no companion-file notion,
|
|
|
+ because the `.inc` simply sits beside the `.pas` in `tests/fixtures/` and the
|
|
|
+ include resolves there.
|
|
|
+- **The ladder does not move at this stage.** `CALC.PAS`'s include is at
|
|
|
+ normalised `9404`, and the compiler stops at `7791` — the typed constant of
|
|
|
+ Stage 4 — so the include is never reached for `CALC.PAS` yet. Stage 2 is
|
|
|
+ pinned by t56/t57/t58 until Stage 4 lets the compiler get to it; the rung
|
|
|
+ moving is a Stage 4 event.
|
|
|
|
|
|
**Stage 3 — lexical `#nn` and `^X` character constants.** Small; both are `ERR`
|
|
|
today. `#27` (decimal) and `#255`, `$FF` (hex works already), `^M`/`^E`/`^[`.
|