|
|
@@ -0,0 +1,85 @@
|
|
|
+# Step: TopSpeed V3 corpus validation
|
|
|
+
|
|
|
+Tag `v3-topspeed-corpus`. V3 suite **151/151**, fixpoint OK
|
|
|
+(unchanged — this touches only the sidecar).
|
|
|
+
|
|
|
+## Why
|
|
|
+
|
|
|
+After self-hosting, the next "normal" step was to exercise the
|
|
|
+front-end on a **real corpus**. The historical TopSpeed/JPI V3 corpus
|
|
|
+is the natural target: `$HOME/bin/Dos/M2/TS-V3` — **662 files**
|
|
|
+(352 `.DEF` + 310 `.MOD`).
|
|
|
+
|
|
|
+V3's own `M2.atg` is the classic/Redux subset and would not take this
|
|
|
+dialect (pragmas `(*#...)`, conditional compilation `(*%...)`, `H`/`C`/
|
|
|
+`B` literals, `::=`, address constructors `[seg:ofs]^`, `CLASS`/`IS`,
|
|
|
+manifest constants, ...). The project already carries a
|
|
|
+**sidecar** grammar for it, `compiler/src/TopSpeed-V3-M2.atg`, whose
|
|
|
+deliverable is *parsing* the dialect (unlowered constructs end in the
|
|
|
+standard `230`, parse-now / lower-later).
|
|
|
+
|
|
|
+That sidecar had never been compiled and run over the full corpus.
|
|
|
+
|
|
|
+## What was done
|
|
|
+
|
|
|
+1. **Built the sidecar** (`tools/topspeed-grammar/build.sh`) — copies
|
|
|
+ the grammar + the V3 frames + `SymTab`/`QbeGen`/`FileIO`, runs
|
|
|
+ `CR -m -C`, `gm2 -fiso`, links `build/TSM2`.
|
|
|
+2. **Fixed API drift** vs the current `SymTab`/`QbeGen` (the sidecar
|
|
|
+ predated several changes):
|
|
|
+ - `SymTab.NewArray(e)` → `SymTab.NewOpenArray(e)`;
|
|
|
+ - `SymTab.FixPending(t)` / `SetProcRes(t)` now return `BOOLEAN`;
|
|
|
+ - `QbeGen.EndModule` now takes the module name.
|
|
|
+3. **Three real grammar gaps** the corpus exposed:
|
|
|
+ - **tagless variant** `CASE : T OF` (anonymous selector) — TopSpeed
|
|
|
+ accepted, the sidecar required a named tag;
|
|
|
+ - **manifest constants without `CONST`** (`NAME = value;` at
|
|
|
+ declaration level);
|
|
|
+ - **trailing `|`** in a variant list (`TRUE: …; | FALSE: …; |`).
|
|
|
+4. **Corpus harness** (`tools/topspeed-grammar/corpus.sh`) — runs
|
|
|
+ `TSM2` over every `.DEF`/`.MOD` in a scratch tree (so listings never
|
|
|
+ touch the corpus) and classifies each file as *parse-OK* (only the
|
|
|
+ deliberate `230`/semantic markers) or *syntax-bad* (a real Coco/R
|
|
|
+ error).
|
|
|
+
|
|
|
+## Result
|
|
|
+
|
|
|
+| | files |
|
|
|
+| --- | --- |
|
|
|
+| corpus | **662** (352 `.DEF` + 310 `.MOD`) |
|
|
|
+| **parse-OK** (230/semantic only) | **631** |
|
|
|
+| syntax-bad | **31** |
|
|
|
+
|
|
|
+Coverage rose **590 → 627 → 631** as the fixes landed.
|
|
|
+
|
|
|
+### Remaining 31 syntax-bad
|
|
|
+
|
|
|
+- **17 use `(*%…*)` conditional compilation** — a lexer feature the
|
|
|
+ sidecar does not implement; text inside a disabled block is parsed
|
|
|
+ as code. (Pragmas `(*#…)` are already fine — they lex as ordinary
|
|
|
+ `(* … *)` comments.)
|
|
|
+- **14 assorted**, e.g. a typed set constructor in an argument list
|
|
|
+ (`GetMenu("…", CharSet{'N','P','T'}, ch)`), address constructors,
|
|
|
+ and a few files with malformed/commented-out regions
|
|
|
+ (`END (*QMLB` …). Full list in the harness output.
|
|
|
+
|
|
|
+## Reproduce
|
|
|
+
|
|
|
+```sh
|
|
|
+cd tools/topspeed-grammar
|
|
|
+./build.sh # -> build/TSM2
|
|
|
+./corpus.sh # -> 631 parse-OK / 31 syntax-bad
|
|
|
+```
|
|
|
+
|
|
|
+## Notes
|
|
|
+
|
|
|
+- V3's own compiler (`M2.atg`) and the self-hosting path are untouched;
|
|
|
+ the sidecar is a separate grammar built on demand.
|
|
|
+- The sidecar now tracks the V3 `SymTab`/`QbeGen` API; if those drift
|
|
|
+ again, `build.sh` is where the small patch belongs.
|
|
|
+
|
|
|
+## Files
|
|
|
+
|
|
|
+`compiler/src/TopSpeed-V3-M2.atg` (three grammar fixes),
|
|
|
+`tools/topspeed-grammar/{build.sh,corpus.sh,README.md}`,
|
|
|
+`.gitignore` (build dir), this doc.
|