Skip to content

Support &=, ^=, |= for macros#307

Open
davispuh wants to merge 1 commit intojacob-carlborg:masterfrom
davispuh:macro
Open

Support &=, ^=, |= for macros#307
davispuh wants to merge 1 commit intojacob-carlborg:masterfrom
davispuh:macro

Conversation

@davispuh
Copy link
Copy Markdown

Consider macro like this:

#define FLAG_CLEAR(S, Flag) (S->Flags &= ~(Flag))

Currently such macros with &=, ^= and |= are dropped.
So this PR implements support for them and will produce D code like:

extern (D) auto FLAG_CLEAR(T0, T1)(auto ref T0 S, auto ref T1 Flag)
{
    return S.Flags &= ~Flag;
}

Copilot AI review requested due to automatic review settings March 19, 2026 22:02
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +999 to +1007
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);
Copy link

Copilot AI Mar 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

@jacob-carlborg jacob-carlborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no test added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants