Support &=, ^=, |= for macros#307
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the macro expression parser so macros using compound bitwise-assignment operators (&=, ^=, |=) are no longer dropped and can be translated into equivalent D expressions.
Changes:
- Added parsing support for
&=,^=, and|=in macro expressions. - Routed conditional-expression parsing through the new compound-assignment parse layer.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| alias parseAndSelfExpr = parseLeftAssoc!(AndExpr, parseLogicalOrExpr, "&="); | ||
| alias parseXorSelfExpr = parseLeftAssoc!(XorExpr, parseAndSelfExpr, "^="); | ||
| alias parseOrSelfExpr = parseLeftAssoc!(OrExpr, parseXorSelfExpr, "|="); | ||
|
|
||
| Expression parseCondExpr(ref Token[] tokens, Cursor[string] table, bool defined) | ||
| { | ||
| auto local = tokens; | ||
|
|
||
| Expression expr = parseLogicalOrExpr(local, table, defined); | ||
| Expression expr = parseOrSelfExpr(local, table, defined); |
There was a problem hiding this comment.
The new &=, ^=, |= parsing is wired in via parseLeftAssoc and a precedence chain (&= > ^= > |=) inside parseCondExpr. In C these compound-assignment operators all share the same precedence, are right-associative, and have lower precedence than the conditional ?:. As implemented, expressions like a &= b |= c will be parsed as (a &= b) |= c (should be a &= (b |= c)), and a &= b ? c : d will bind &= tighter than ?: (should be a &= (b ? c : d)), which can generate incorrect D output.
Consider introducing a dedicated assignment-expression parser (right-assoc) for &=, ^=, |= (and possibly other assignment ops), and call it from parseExpr rather than embedding it into the conditional-expression level. If you keep reusing AndExpr/XorExpr/OrExpr nodes, ensure the precedence/associativity matches C’s assignment grammar.
Consider macro like this:
Currently such macros with
&=,^=and|=are dropped.So this PR implements support for them and will produce D code like: