Skip to content

Simple OpenQASM 3.0 expressions and casts #7593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 331 commits into
base: master
Choose a base branch
from

Conversation

comp-phys-marc
Copy link
Contributor


Context: We would like to support manipulating classical and quantum variables with simple expressions and casts in the OpenQASM 3.0 interpreter.

Description of the Change: Adds support for binary and unary expressions as well as casts.

Benefits: Allows more classical arithmetic to be done in QASM programs.

Possible Drawbacks: Does not support everything in the QASM 3.0 spec as of yet.

Related ShortCut Stories: [sc-92514]

Comment on lines 218 to 243
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[0]:
self.vars[name].val = value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[1]:
self.vars[name].val = self.vars[name].val + 1
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[2]:
self.vars[name].val += value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[3]:
self.vars[name].val -= value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[4]:
self.vars[name].val = self.vars[name].val * value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[5]:
self.vars[name].val = self.vars[name].val / value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[6]:
self.vars[name].val = self.vars[name].val & value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[7]:
self.vars[name].val = self.vars[name].val | value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[8]:
self.vars[name].val = self.vars[name].val ^ value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[9]:
self.vars[name].val = self.vars[name].val << value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[10]:
self.vars[name].val = self.vars[name].val >> value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[11]:
self.vars[name].val = self.vars[name].val % value
if node.op.name == ASSIGNMENT_CLASSICAL_OPERATORS[12]:
self.vars[name].val = self.vars[name].val ** value
Copy link
Contributor

Choose a reason for hiding this comment

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

LOL maybe a switch-case is better here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

haha sure if you prefer :')

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Screenshot 2025-06-05 at 5 40 15 PM

I am scratching my head over this...

Copy link
Contributor

Choose a reason for hiding this comment

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

What's your Python version?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

3.10.16

Copy link
Contributor

Choose a reason for hiding this comment

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

NVM yeah each case must be a literal, it cannot be dynamically indexed from a list. I think literals make the code a lot more readable here anyways.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

alright

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Python should have called visit() instead of always interpreting a literal! haha

Base automatically changed from feature/variables to master June 5, 2025 21:50
@comp-phys-marc comp-phys-marc marked this pull request as ready for review June 6, 2025 15:36
@comp-phys-marc comp-phys-marc changed the title [WIP] Simple OpenQASM 3.0 expressions and casts Simple OpenQASM 3.0 expressions and casts Jun 6, 2025
@PennyLaneAI PennyLaneAI deleted a comment from github-actions bot Jun 6, 2025
Comment on lines 217 to 243
if node.op.name in ASSIGNMENT_CLASSICAL_OPERATORS:
if node.op.name == "=":
self.vars[name].val = value
if node.op.name == "++":
self.vars[name].val = self.vars[name].val + 1
if node.op.name == "+=":
self.vars[name].val += value
if node.op.name == "-=":
self.vars[name].val -= value
if node.op.name == "*=":
self.vars[name].val = self.vars[name].val * value
if node.op.name == "/=":
self.vars[name].val = self.vars[name].val / value
if node.op.name == "&=":
self.vars[name].val = self.vars[name].val & value
if node.op.name == "|=":
self.vars[name].val = self.vars[name].val | value
if node.op.name == "^=":
self.vars[name].val = self.vars[name].val ^ value
if node.op.name == "<<=":
self.vars[name].val = self.vars[name].val << value
if node.op.name == ">>=":
self.vars[name].val = self.vars[name].val >> value
if node.op.name == "%=":
self.vars[name].val = self.vars[name].val % value
if node.op.name == "**=":
self.vars[name].val = self.vars[name].val ** value
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if node.op.name in ASSIGNMENT_CLASSICAL_OPERATORS:
if node.op.name == "=":
self.vars[name].val = value
if node.op.name == "++":
self.vars[name].val = self.vars[name].val + 1
if node.op.name == "+=":
self.vars[name].val += value
if node.op.name == "-=":
self.vars[name].val -= value
if node.op.name == "*=":
self.vars[name].val = self.vars[name].val * value
if node.op.name == "/=":
self.vars[name].val = self.vars[name].val / value
if node.op.name == "&=":
self.vars[name].val = self.vars[name].val & value
if node.op.name == "|=":
self.vars[name].val = self.vars[name].val | value
if node.op.name == "^=":
self.vars[name].val = self.vars[name].val ^ value
if node.op.name == "<<=":
self.vars[name].val = self.vars[name].val << value
if node.op.name == ">>=":
self.vars[name].val = self.vars[name].val >> value
if node.op.name == "%=":
self.vars[name].val = self.vars[name].val % value
if node.op.name == "**=":
self.vars[name].val = self.vars[name].val ** value
match node.op.name:
case "=":
self.vars[name].val = value
case "++":
self.vars[name].val = self.vars[name].val + 1
case "+=":
self.vars[name].val += value
case "-=":
self.vars[name].val -= value
case "*=":
self.vars[name].val = self.vars[name].val * value
case "/=":
self.vars[name].val = self.vars[name].val / value
case "&=":
self.vars[name].val = self.vars[name].val & value
case "|=":
self.vars[name].val = self.vars[name].val | value
case "^=":
self.vars[name].val = self.vars[name].val ^ value
case "<<=":
self.vars[name].val = self.vars[name].val << value
case ">>=":
self.vars[name].val = self.vars[name].val >> value
case "%=":
self.vars[name].val = self.vars[name].val % value
case "**=":
self.vars[name].val = self.vars[name].val ** value
case _:
raise SyntaxError(...)

This should work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should indeed!

if node.op.name in NON_ASSIGNMENT_CLASSICAL_OPERATORS:
match node.op.name:
case "==":
ret = lhs == rhs
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not

Suggested change
ret = lhs == rhs
return lhs == rhs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is a fine suggestion. No problem with that.

Copy link

codecov bot commented Jun 6, 2025

Codecov Report

Attention: Patch coverage is 92.17391% with 9 lines in your changes missing coverage. Please review.

Project coverage is 99.66%. Comparing base (5322c9b) to head (28ccbf5).
Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
pennylane/io/qasm_interpreter.py 92.17% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7593      +/-   ##
==========================================
- Coverage   99.68%   99.66%   -0.02%     
==========================================
  Files         531      531              
  Lines       51979    52091     +112     
==========================================
+ Hits        51815    51919     +104     
- Misses        164      172       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

2 participants