Compose the void marker with the readonly glyph: wipe! =! -> - #312
Merged
Merged
Conversation
A bang-named definition (`save! = ->`) is void: the implicit return and the trailing-loop comprehension are suppressed. A readonly binding (`x =! v`) never changes after its declaration. The two markers now compose, so `wipe! =! (xs) ->` declares a const void function, and `export flush! =! ->` its exported form. Both were a parse error. Lexer: DAMMIT directly before READONLY_ASSIGN mints VOID_MARKER, as it already did before `=`. Grammar: `void-readonly` rows beside `void-assign` in Assign and ExportAssign, over the same RHS shapes (inline, wrapped, indented). The `readonly` kind gains the `voidMarker` role; the parser regenerates under the manifest gate with no conflict drift. Emitter: `void-readonly` dispatches through the readonly path and registers the value as void, so a non-function value is rejected with the void-marker error (now listing the `=!` spelling) and a later write is rejected as a readonly violation. The TS face declares it as a readonly. Editor grammars: the VS Code and Vim readonly-name rules admit the bang between the name and `=!`, scoping it as the void marker; the lockstep test pins the captures against the compiled output. highlight.js already reads both glyphs as operators and needs no change. Tests: battery rows in assignment.rip (undefined return, thin and fat arrow, const void emission, exported form) and sweep.rip (wrapped and indented pins, which reduce the next-line RHS productions the grammar coverage gate requires); the void-marker lane and corpus gain the `=!` case. Corpus bytes: voidmarker.js/.sexpr.json/.map.json regenerate for the one added definition; every other snapshot is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
save! = ->defines a void function (no implicit return, no trailing-loop comprehension).x =! vis a readonly binding. They now compose:emits
const wipe = (function(xs) { for (...) {...} return; });andexport const flush = .... Previously both forms were a parse error.Changes
=!mints VOID_MARKER, as it already did before=.void-readonlyrows besidevoid-assignin Assign and ExportAssign over the same RHS shapes;readonlykind gains thevoidMarkerrole; parser regenerated under the manifest gate, no conflict drift.n! =! 5is rejected with the void-marker error;wipe = 2after the definition is rejected as a readonly write. TS face declares it readonly.assignment.ripandsweep.rip(the wrapped/indented pins reduce the next-line RHS productions the coverage gate requires); void-marker lane and corpus gain the=!case. Corpus: onlyvoidmarker.*regenerate.Verification
bun run test:rip: 3284 pass, 0 failbun test test/toolchain: 661 pass (production coverage, kinds registry, generated-parser gates)bun run corpus: stable after regenerationbun run test:all: 26 lanes, 9895 tests passeddist/@ripregenerated under Bun 1.4.0