Skip to content

Commit 941e2d3

Browse files
olwangclaude
andcommitted
docs(selfhost): record 3-step frontend-parity progress (SH-025 286/576, SH-026)
Ledger + memory + plan updated for the /goal sweep: - SH-025 AST structure parity 245→286/576 (receiver calls, fn attrs/effects/body, explicit-fn closures, tuple/list patterns, interpolation, line-continuation; protocols/impls deferred as documented low-ROI residual; rss if-expression limitation noted). - SH-026 (new): step-2 diagnostics milestone 2a (RS0006/RS0016/RS0017, 4 codes byte-exact over 576 files) and step-3 lexer spans (Tok.len; all 3 tiers byte-exact). AST @l:C:N spans scoped as the remaining last phase. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 0ea359b commit 941e2d3

2 files changed

Lines changed: 55 additions & 16 deletions

File tree

docs/ledgers/rss-selfhost-ledger.md

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ gap is VM value-representation / intrinsic-dispatch cost (the next big lever).
868868
across all backends; RS0037 removed as a restriction and repurposed for arity;
869869
spec §20.1 amended.
870870

871-
### SH-025 — AST-dump parity: streaming rss producer at 245/569, residual grammar is the growing tail
871+
### SH-025 — AST-dump parity: streaming rss producer at 286/576, residual grammar is the growing tail
872872

873873
- **Context:** step 2 of frontend object parity (after the AST-dump format +
874874
oracle keystone, SH-adjacent). `selfhost/astdump.rss` is a recursive-descent
@@ -892,18 +892,57 @@ gap is VM value-representation / intrinsic-dispatch cost (the next big lever).
892892
**match expressions**, **`!`/`~` unary desugars**, **negative numbers**, try `?`,
893893
parens, literals. Patterns: variant/binding/wildcard/literal/struct (fields with
894894
shorthand/`_`/effect/nested, `..` rest).
895-
- **Milestones (this session, each a commit + ratcheted floor):** base fns 58 →
896-
decls 121 → match 178 → generic calls 225 → closures 239 → for+literals 242 →
897-
unary/negative 245.
898-
- **Residual (the tail):** interpolated strings, effect-receiver calls
899-
(`read x.m()` → ReceiverCall), the explicit-`fn(...)` closure form (captures /
900-
declared effects), fn attributes (`#deprecated`/`#lower_name`), effect/retains
901-
clauses, tuple/list patterns, protocols/impls/native-modules (they dump in a
902-
separate program section, not source order, so streaming can't place them), and
903-
`statement_end` operator/postfix line continuation. Remaining mismatched files
904-
typically stack several of these at once (diminishing per-feature ROI). Each is
905-
additive; the floor ratchets as they land.
895+
Also covered (2026-07-02 sweep): **effect-receiver + no-effect receiver calls**
896+
(`read x.m()` / `self.m()` → ReceiverCall), **fn attributes** (`#deprecated`/
897+
`#lower_name`), **effect/retains clauses**, **default-impl marker**, always-emit
898+
`body`/`block` for no-body fns, **explicit-`fn` closures** (captures/declared-
899+
effects), **tuple/list patterns** (`__TupleN` desugar, `pat-list` prefix/suffix/
900+
rest), **interpolated strings** (`$"…{e}…"` → String.format desugar, embedded
901+
exprs re-tokenized), and **statement_end line-continuation** (`;` terminator,
902+
`.`/`?` postfix, `| & + * / % ^` operator wrapping, generic-angle depth).
903+
- **Milestones (each a commit + ratcheted floor):** base fns 58 → decls 121 →
904+
match 178 → generic calls 225 → closures 239 → for+literals 242 → unary/negative
905+
245 → **effect-receiver 248 → no-effect-receiver+attrs+effects+body 273 →
906+
explicit-fn+tuple/list-patterns 279 → interpolation 280 → line-continuation 286**.
907+
- **Residual (the tail):** **protocols/impls/native-modules** — DEFERRED: needs a
908+
two-pass driver (items in source order, then protocol/impl decl sections) plus an
909+
`emit_function` refactor to reproduce the synthetic method transforms (inject
910+
`Self: Managed` generic, append `native` effect, `protocol.method`/`module.fn`
911+
name mangling) for only ~11 corpus files — lowest ROI/complexity ratio. Plus the
912+
interpolation malformed-inner-expr case (emit_expr can't signal parse failure)
913+
and any remaining stacked constructs. Each is additive; the floor ratchets.
914+
- **rss limitation found:** `if/else` is not valid as an *expression*
915+
(`let x = if c {..} else {..}` → RS0015) — worked around with helper functions.
906916
- **Status:** open (growing tail). The producer + parity gate + risk mitigations
907-
(curated fast gate; module-story decision recorded in AST_FORMAT.md) are in
908-
place; full 556-file byte parity is incremental, tracked by the ratcheting
909-
floor.
917+
(curated fast gate; module-story decision in AST_FORMAT.md) are in place; full
918+
byte parity is incremental, tracked by the ratcheting floor.
919+
920+
### SH-026 — Frontend object parity: diagnostics-codes (step 2) + lexer spans (step 3)
921+
922+
- **Context:** the frontend-object-parity ladder beyond AST structure. Two arms
923+
advanced together with the SH-025 AST work.
924+
- **Diagnostics (step 2, milestone 2a):** `selfhost/check.rss` now reproduces
925+
**RS0006 / RS0016 / RS0017** (duplicate feature-header / unknown file feature /
926+
duplicate feature within a header) in addition to RS0005, all decidable from the
927+
top-level token scan (per-header seen-set matches `parse_features`).
928+
`CHECKER_TARGET_CODES` extended to the 4 codes; `checker_parity_corpus` is
929+
byte-exact over **576 files, code-mismatches 0**; each code + CLEAN verified
930+
firing on crafted inputs and the `unknown-file-feature` fixture. Next increments
931+
(scoped, not done): RS0002/RS0003 (signature explicitness — needs all-function
932+
traversal incl. protocol/native blocks); RS0021 exhaustiveness / RS0024
933+
unknown-type (needs a `Map<String,Def>` symbol-table pass — the first genuinely
934+
semantic self-hosted check).
935+
- **Lexer spans (step 3):** added a `len` field to the shared `Tok`
936+
(= consumed source span `j-i`, matching the Rust lexer's `index-start`) and made
937+
`lexer.rss` emit the real `<line>:<col>:<len>` prefix. `lexer_parity_corpus` is
938+
now byte-exact at **all three tiers** (0 kind+payload, 1 +line/col, 2 +length) —
939+
576 files, token-mismatches 0 each. The lexer span ladder is fully closed; the
940+
additive `Tok.len` left parser/checker/astdump parity untouched.
941+
- **AST spans (step 3, remaining "last phase"):** NOT done. Would need each
942+
`astdump.rss` `emit` to carry the correct token's span and the oracle serializer
943+
to append ` @L:C:N` per node (plus a tier-strip so tier-0 stays green). Feasible
944+
but large + precise: node spans are mostly `tokens[start]` but not uniformly
945+
(`Try` uses the `?` token, some binary the operator, ReceiverCall the receiver),
946+
so it is an invasive per-node-type effort across ~150 emit sites — its own phase.
947+
- **Status:** open. Step-2 milestone 2a and step-3 lexer spans are done and gated;
948+
step-2 deeper checks and step-3 AST spans are the scoped remainder.

docs/self-hosting-stress-test-plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ materialized). Parity harness: `ast_parity_tiny_sample` + `ast_parity_samples`
285285
count still clears the floor). That corpus gate runs the reg-VM over ~570 files and
286286
is slow in a debug build — run it in `--release` for a quick measurement (~100s);
287287
the fast non-ignored inner-loop gate is `ast_parity_samples`. Current reach:
288-
**245/569 byte-exact, 0 run-failures** (the producer never crashes; unsupported
288+
**286/576 byte-exact (AST structure), 0 run-failures** (the producer never crashes; unsupported
289289
constructs mismatch rather than panic), roughly doubled this session via ratcheted
290290
milestones: base fns 58 → declarations 121 → match 178 → generic calls 225 →
291291
closures 239 → for/literals 242 → unary/negative 245. Covered: fns (generics/

0 commit comments

Comments
 (0)