Repository navigation
fix(t27b): a port named after a t27 keyword is spelled with a trailing underscore (Closes #10061) - #10069
Merged
Conversation
gHashTag
enabled auto-merge (squash)
October 17, 2026 18:12
…g underscore (Closes #10061) The t27 lexer reserves `in`, `for`, `test`, `module`, `var`, ..., so a hardware module could not declare the Verilog port `in` that CVDP 8x3_priority_encoder_0001 requires: `const in : u8 = undefined;` is a parse error (KwIn), and the spec never reached Verilog. verilog_plan.t27 records the rule: a name that is a t27 keyword followed by exactly one `_` (`in_`) is written in Verilog as the keyword (`in`). It holds the keyword list (T27_KEYWORDS, the 29 words the bootstrap lexer reserves) and name_end, which drops that `_` and nothing else; `data_`, `in__`, `_` and `xin_` are unchanged. put_name in verilog_emit.t27 reads name_end, so the declaration and every read agree, and a stem that is also a Verilog keyword (`for_`) is escaped as before (`\for `). The rename is injective, since no t27 name can be a keyword. A raw-identifier syntax would need a lexer change in t27c (Rust), which is out of bounds. Tests: a_t27_keyword_with_one_trailing_underscore_names_the_keyword and an_input_spelled_in_underscore_is_the_port_in; negative control a_name_that_is_no_keyword_keeps_every_underscore, plus `data_` asserts in the emit fixture. gen/rust regenerated with t27c gen-rust; VerilogPlan and VerilogEmit resealed, and AstShape, TsPlan and EmitKit, whose seal closures record verilog_plan's hash. All on the Railway lab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
force-pushed
the
claude/keen-sinoussi-e73ac5
branch
from
October 17, 2026 18:15
d787335 to
811d118
Compare
Contributor
This was referenced Oct 17, 2026
dmitrii-f-t27
added a commit
to dmitrii-f-t27/t27
that referenced
this pull request
Oct 17, 2026
specs/tri/t27b/verilog_plan.t27: the two new header rules sat at the same place. Both are kept: this branch's PIN DECLARATION (gHashTag#8889) and master's NAME THAT IS A T27 KEYWORD (gHashTag#10061). The conflicts in the seals and in gen/rust/tri/t27b/verilog_{emit,plan}.rs are derived: the Rust is regenerated with this tree's t27c gen-rust, and both seals are re-saved. Checks with this tree: seals of verilog_emit, verilog_plan, eth_top_ax7203 and xc7_primitives verify; t27c test-report and t27b test 9/9, 17/17, 2/2; t27b verilog writes the board top with its 22 pin attributes, synthesizable part 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.
Closes #10061
What
A t27b hardware module can now declare a Verilog port whose name is a t27 keyword. Spell it with one trailing
_, andt27b verilogwrites the keyword:const in_ : u8 = undefined;givesinput wire [7:0] in,, and every read is writtenin;for_gives the escaped\for, becauseforis also a Verilog keyword and is escaped as before;data_,in__,_andxin_are unchanged. Only a t27 keyword followed by exactly one_loses the_.The rule is
T27_KEYWORDS+name_endinspecs/tri/t27b/verilog_plan.t27. The 29 keywords are the words the bootstrap lexer reserves. The writer isput_nameinspecs/tri/t27b/verilog_emit.t27, which already writes every Verilog name, so a declaration and its reads cannot disagree. Only.t27is hand-written.Why
The t27 lexer reserves
in, soconst in : u8 = undefined;is a parse error (Expected identifier after 'const', got KwIn). CVDP8x3_priority_encoder_0001requiresinput [7:0] in. In the Build-A-Chip-Bench proxy run, that alone cost arm B the task: the spec never reached Verilog.The rename is injective, because no t27 name can be a keyword, so
in_cannot collide with a namein. A raw-identifier syntax (@"in") would need a t27c lexer/parser change in Rust, which is out of bounds. The CPU backends are untouched and still seein_.Files
specs/tri/t27b/verilog_plan.t27: rule text in the header and in the Names section;T27_KEYWORDS,t27_keyword,name_end; 2 new tests.specs/tri/t27b/verilog_emit.t27:put_namereadsname_end; new asserts innumbers_ranges_literals_and_names_are_spelled; new testan_input_spelled_in_underscore_is_the_port_in.gen/rust/tri/t27b/verilog_{emit,plan}.rs: output oft27c gen-rust. Before regenerating, gen-rust on the pristine specs at a18d7ee reproduced the committed files byte for byte..trinity/seals/t27b_T27b{VerilogPlan,VerilogEmit,AstShape,TsPlan,EmitKit}.json:t27c seal --save. AstShape, TsPlan and EmitKit (t27b: emit_kit -- one home for the writers' shared helpers (Refs #9994) #10065) record verilog_plan's hash in their closure; none of them has a committed gen/rust file that changes. TsPlan's closure entry was already stale on master (it still had the pre-fix(t27b): fold a constant rst_n/en tie-off out of the clocked process (Closes #10046) #10057 hash); this reseal fixes that too.seal --verifydoes not compare closure hashes, so it reported MATCH for all three before the reseal.Lab receipts (Railway fs-lab, lane at a18d7ee (master, includes #10057 and #10065) + this diff, zig 0.16.0)
Spec tests (
t27c test-report)numbers_ranges_literals_and_names_are_spelledruns 12.Mutants, to show the tests are not vacuous
name_endnever strips (the old behavior):a_t27_keyword_with_one_trailing_underscore_names_the_keywordFAILS (plan 15/16).an_input_spelled_in_underscore_is_the_port_inandnumbers_ranges_literals_and_names_are_spelledFAIL (emit 6/8).name_endstrips any trailing_, with no keyword check: the negative controla_name_that_is_no_keyword_keeps_every_underscoreFAILS (plan 15/16), and the same two emit tests FAIL (emit 6/8).8x3_priority_encoder_0001, arm B: the bench's .t27 with
inspelledin_(two-line edit), emitted with master t27b and with the rebuilt t27b, run through the same gate driver:The spec's own emitted test bench (Icarus,
-DT27B_TESTBENCH) passes: 4 tests, 0 failed, 11 runtime asserts. The diff of the emitted .v is the twoin_->inlines and nothing else.Controls: master t27b vs this t27b, stdout + stderr + exit code compared
inspec (parse error).t27in the repo, plus the 10 bench specs (2483 files; 2333 emit, 150 refused)Wider checks
t27c seal --verify: MATCH for verilog_plan, verilog_emit, ast_shape, ts_plan and emit_kit after the reseal.🤖 Generated with Claude Code