refactor(syntax): generalize the macro repetition separator node - #10310
Conversation
ed9467d to
86cbcf4
Compare
931afdd to
be641de
Compare
86cbcf4 to
03aed4c
Compare
be641de to
e0049dd
Compare
03aed4c to
524388b
Compare
PR SummaryLow Risk Overview The parser still only accepts a comma there (with a TODO to widen parsing later) but now builds the new wrapper shape. Semantics centralizes separator handling in Behavior is intended to be unchanged for macro rules: matching, expansion, and diagnostics (e.g. separator with Reviewed by Cursor Bugbot for commit ec7ba69. Bugbot is set up for automated code reviews on this repo. Configure here. |
e0049dd to
df241a0
Compare
33168c9 to
519e671
Compare
579ae55 to
3165739
Compare
519e671 to
1a0a27c
Compare
3165739 to
d21cca4
Compare
1a0a27c to
8ab7d32
Compare
d21cca4 to
92a2c32
Compare
a2b6efa to
5369cd5
Compare
92a2c32 to
206cb86
Compare
5369cd5 to
ce73864
Compare
206cb86 to
737f5e6
Compare
orizi
left a comment
There was a problem hiding this comment.
@orizi+AGNT made 1 comment and resolved 1 discussion.
Reviewable status: 0 of 8 files reviewed, all discussions resolved (waiting on TomerStarkware).
crates/cairo-lang-syntax-codegen/src/cairo_spec.rs line 911 at r1 (raw file):
Previously, eytan-starkware+AGNT (Agent AGNT for eytan-starkware) wrote…
after this change
OptionTerminalCommaexists only forTokenTreeRepetition(l.825). move it up next to that node so it's obvious it dies together with theTODO(Dean): Remove TokenTreeRepetition.
Done - moved next to TokenTreeRepetition with a note that it goes away together with it; syntax regenerated.
ce73864 to
9601577
Compare
5109fa0 to
79c24e3
Compare
0e35946 to
dcfcdf2
Compare
aa2dab6 to
e6cba8d
Compare
a8121d3 to
f256911
Compare
9b464cf to
c71ea1c
Compare
f256911 to
9c68261
Compare
9c68261 to
c99f95d
Compare
c71ea1c to
3bf564a
Compare
`MacroRepetition.separator` was `OptionTerminalComma`, baking the only separator
the parser currently accepts into the grammar. Replace it with
`OptionMacroRepetitionSeparator`, wrapping a `MacroRepetitionSeparator` struct
whose single `token` child is a `TokenNode` — the codegen's all-terminals enum —
so the grammar can hold any terminal as a separator.
An option must wrap a node that has a `SyntaxKind`, and enums do not get one
(`generate_kinds_code` filters `NodeKind::Enum` out), hence the small wrapper
struct — the same reason `TokenTreeLeaf` wraps `TokenNode`. The syntax crate is
regenerated by `generate-syntax`, not hand-edited.
Behavior is unchanged. The parser still accepts only `TerminalComma` in that
slot, and the semantic matcher and expansion still treat only a comma as a
separator, now via a single `repetition_separator` helper that returns `None`
for any other token — the same branch as "no separator" — rather than
panicking, so loosening the parser later cannot introduce a panic.
`$($x:ident);*` is still rejected with the same `Missing macro repetition
operator` diagnostic. The only golden churn is in the parser partial_trees:
`OptionTerminalCommaEmpty` becomes `OptionMacroRepetitionSeparatorEmpty`, and
existing comma separators gain the `MacroRepetitionSeparator` level. No semantic
golden changed.
`TokenTreeRepetition.separator` is deliberately left as `OptionTerminalComma`.
The adjacent `TODO(Dean): Remove TokenTreeRepetition and TokenTreeParam (it's
redundant)` intends to delete that node outright, so migrating it would be churn
on code slated for removal and would couple the call-site token-tree grammar to
the macro-rule grammar that TODO wants to disentangle. That refactor is
explicitly not folded in here; `.add_option("TerminalComma")` stays for it and
becomes dead only once it lands.
The `unreachable!()` on `ast::MacroParamKind::Missing` in `macro_declaration.rs`
is not made reachable by this change, so no guard was added. The accepted token
language is identical before and after, so no new tree shape is produced, and
the separator slot is structurally disjoint from `ParamKind`. Checked
empirically that it also stays unreachable in general: `macro m { ($x:foo) => {
1 }; }` reports `Missing tokens. Expected a macro rule parameter kind.` and the
rule is then dropped by the `descendants(..).any(is_missing)` filter in
`priv_macro_declaration_data`, so the matcher never converts a missing param
kind. That filter is unaffected here — `OptionMacroRepetitionSeparatorEmpty` is
a plain struct kind, not a missing kind, exactly like the
`OptionTerminalCommaEmpty` it replaces.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3bf564a to
ec7ba69
Compare

MacroRepetition.separatorwasOptionTerminalComma, baking the only separatorthe parser currently accepts into the grammar. Replace it with
OptionMacroRepetitionSeparator, wrapping aMacroRepetitionSeparatorstructwhose single
tokenchild is aTokenNode— the codegen's all-terminals enum —so the grammar can hold any terminal as a separator.
An option must wrap a node that has a
SyntaxKind, and enums do not get one(
generate_kinds_codefiltersNodeKind::Enumout), hence the small wrapperstruct — the same reason
TokenTreeLeafwrapsTokenNode. The syntax crate isregenerated by
generate-syntax, not hand-edited.Behavior is unchanged. The parser still accepts only
TerminalCommain thatslot, and the semantic matcher and expansion still treat only a comma as a
separator, now via a single
repetition_separatorhelper that returnsNonefor any other token — the same branch as "no separator" — rather than
panicking, so loosening the parser later cannot introduce a panic.
$($x:ident);*is still rejected with the sameMissing macro repetition operatordiagnostic. The only golden churn is in the parser partial_trees:OptionTerminalCommaEmptybecomesOptionMacroRepetitionSeparatorEmpty, andexisting comma separators gain the
MacroRepetitionSeparatorlevel. No semanticgolden changed.
TokenTreeRepetition.separatoris deliberately left asOptionTerminalComma.The adjacent
TODO(Dean): Remove TokenTreeRepetition and TokenTreeParam (it's redundant)intends to delete that node outright, so migrating it would be churnon code slated for removal and would couple the call-site token-tree grammar to
the macro-rule grammar that TODO wants to disentangle. That refactor is
explicitly not folded in here;
.add_option("TerminalComma")stays for it andbecomes dead only once it lands.
The
unreachable!()onast::MacroParamKind::Missinginmacro_declaration.rsis not made reachable by this change, so no guard was added. The accepted token
language is identical before and after, so no new tree shape is produced, and
the separator slot is structurally disjoint from
ParamKind. Checkedempirically that it also stays unreachable in general:
macro m { ($x:foo) => { 1 }; }reportsMissing tokens. Expected a macro rule parameter kind.and therule is then dropped by the
descendants(..).any(is_missing)filter inpriv_macro_declaration_data, so the matcher never converts a missing paramkind. That filter is unaffected here —
OptionMacroRepetitionSeparatorEmptyisa plain struct kind, not a missing kind, exactly like the
OptionTerminalCommaEmptyit replaces.Co-Authored-By: Claude Fable 5 noreply@anthropic.com