You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two places in src/common/parsing/CodePreprocessing.cpp parse a register reference of the form name or name[index] with almost identical logic:
validateTargets does it for qubit targets in gate calls (x q[0], cx q[0], q[1], assert-ent q[0], q[1], ...). It parses the shape (find [, find ], check the bracket, check that the index is digits, convert to size_t) and then validates the result against definedRegisters (existence + bounds).
parseBitRegisterRef does the first half of the same work for classical bits referenced in an if condition. It was extracted in the refactor for ✨ Support if (c) and if (c[k]) as boolean-only conditions #462 without noticing that the structural-parsing logic already lived inside validateTargets.
The result is duplicated code paths that treat qubits and classical bits differently even though the parsing shape is the same. Any new check (lexical, semantic, or otherwise) has to be added in two places, and the two sides drift.
Depends on #462: this refactor builds on the parseBitRegisterRef helper introduced in the PR that closes #462, so it can only land after that PR is merged.
Proposed solution
Extract the shared shape-parsing logic into a single helper (working name: parseRegisterRef) that returns something like the current BitRegisterRef (a name plus an optional index). Both validateTargets and the classical-condition path call it. validateTargets continues to apply its qubit-specific validation (definedRegisters, bounds) on top of the parsed result; parseBitRegisterRef can either become a thin wrapper or disappear.
Behavior is unchanged; this PR would be a pure refactor.
🤖 AI text below 🤖
Problem statement
Two places in
src/common/parsing/CodePreprocessing.cppparse a register reference of the formnameorname[index]with almost identical logic:validateTargetsdoes it for qubit targets in gate calls (x q[0],cx q[0], q[1],assert-ent q[0], q[1], ...). It parses the shape (find[, find], check the bracket, check that the index is digits, convert tosize_t) and then validates the result againstdefinedRegisters(existence + bounds).parseBitRegisterRefdoes the first half of the same work for classical bits referenced in anifcondition. It was extracted in the refactor for ✨ Supportif (c)andif (c[k])as boolean-only conditions #462 without noticing that the structural-parsing logic already lived insidevalidateTargets.The result is duplicated code paths that treat qubits and classical bits differently even though the parsing shape is the same. Any new check (lexical, semantic, or otherwise) has to be added in two places, and the two sides drift.
Surfaced while planning #468.
Depends on #462: this refactor builds on the
parseBitRegisterRefhelper introduced in the PR that closes #462, so it can only land after that PR is merged.Proposed solution
Extract the shared shape-parsing logic into a single helper (working name:
parseRegisterRef) that returns something like the currentBitRegisterRef(a name plus an optional index). BothvalidateTargetsand the classical-condition path call it.validateTargetscontinues to apply its qubit-specific validation (definedRegisters, bounds) on top of the parsed result;parseBitRegisterRefcan either become a thin wrapper or disappear.Behavior is unchanged; this PR would be a pure refactor.
Out of scope