Skip to content

v1.108.310 — A #lang line selects a reader, and a grammar cannot follow it

Choose a tag to compare

@jgravelle jgravelle released this 30 Aug 14:17
· 2 commits to main since this release

A #lang line selects a reader, and a grammar cannot follow it

.rkt files are read by a Racket reader written in Python
(src/jcodemunch_mcp/parser/racket_reader.py) instead of tree-sitter-racket, and
the brace-blanking pre-pass is deleted. #564 by @otherjoel, the follow-on
#556 promised — seven commits, one finding each, every one with its test.

The reason is the one #556 gave for deferring it: a #lang line selects a
reader, and a grammar cannot follow it. at-exp text bodies were prose to Racket
and tokens to the grammar, and the grammar's error recovery re-parented internal
definitions to module level — the one thing an index must never do. The reader is
measured against read-syntax node for node.

require edges come from the reader now. imports.py carried its own
comment-stripper and form reader and found (require by regex — a second Racket
reader beside the parser's, and the weaker one. Measured over 2,489 files: 131
edges the regex produced that the reader does not, and none the other way.

No PARSER_GENERATION bump, deliberately. READER_GENERATION is stamped on
every local index holding Racket files, so the re-parse reaches exactly those
indexes rather than re-parsing every language for everybody; an index with no
stamp was parsed by tree-sitter. The shared parse cache keys on INDEX_VERSION,
not PARSER_GENERATION, so the Racket key carries :rr<generation> — without it
a .rkt parsed by tree-sitter last week would have been served after the swap. A
test bumps the constant and asserts the key moves.

Also fixed in this release: #lang rosette is S-expressions; #lang pollen/mode racket/base is Racket code rather than a Pollen document; a #| |# block comment
above #lang no longer hides the lang from the gate; and racket_langs can
declare a lang's at-exp command character.

CLAUDE.md's Key Files split

Maintenance housekeeping, no user-facing change. Key Files was 44.4% of a
140,000-char session budget. The descriptive half — what each module is — moved
to KEY-FILES.md; every entry stating a prohibition, a constraint whose violation
causes a defect, or a rationale stayed. 76 entries moved, 44 stayed, 138,719 →
122,913 chars. tests/test_key_files_split.py asserts every entry lives in
exactly one of the two files.


Tests: 9,005 passed / 13 skipped / 0 failed locally; 8,999 / 19 / 0 in a
CI-equivalent environment — 9,018 both ways. CI green on lint plus all 8 matrix
jobs.