Skip to content

Commit

Permalink
Fix: Append '_' to the variable names that are reserved keywords
Browse files Browse the repository at this point in the history
1. Fixed few existing test cases that got affected due to this change
2. Added reserved keyword list
  • Loading branch information
atharva-satpute committed Jun 10, 2024
1 parent aebde14 commit 54ff709
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 13 deletions.
84 changes: 83 additions & 1 deletion src/autoqasm/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,63 @@
from autoqasm.program.gate_calibrations import GateCalibration
from autoqasm.types import QubitIdentifierType as Qubit

reserved_keywords = [
"angle",
"array",
"barrier",
"bit",
"bool",
"box",
"cal",
"case",
"complex",
"const",
"creg",
"ctrl",
"default",
"defcal",
"defcalgrammar",
"delay",
"duration",
"durationof",
"end",
"euler",
"extern",
"false",
"float",
"frame",
"gate",
"gphase",
"im",
"include",
"input",
"int",
"inv",
"let",
"OPENQASM",
"measure",
"mutable",
"negctrl",
"output",
"pi",
"port",
"pragma",
"qreg", # For backward compatibility
"qubit",
"readonly",
"reset",
"return",
"sizeof",
"stretch",
"switch",
"tau",
"true",
"U",
"uint",
"void",
"waveform",
]


def main(
func: Callable | None = None,
Expand Down Expand Up @@ -400,6 +457,19 @@ def _convert_subroutine(
return program_conversion_context.return_variable


def is_reserved_keyword(name: str) -> bool:
"""
Method to check whether or not 'name' is a reserved keyword
Args:
name (str): Name of the variable to be checked
Returns:
bool: True, if 'name' is a reserved keyword, False otherwise
"""
return name in reserved_keywords


def _wrap_for_oqpy_subroutine(f: Callable, options: converter.ConversionOptions) -> Callable:
"""Wraps the given function into a callable expected by oqpy.subroutine.
Expand All @@ -419,6 +489,12 @@ def _wrap_for_oqpy_subroutine(f: Callable, options: converter.ConversionOptions)
def _func(*args, **kwargs) -> Any:
inner_program: oqpy.Program = args[0]
with aq_program.get_program_conversion_context().push_oqpy_program(inner_program):
# Bind args and kwargs to '_func' signature
sig = inspect.signature(_func)
bound_args = sig.bind(*args, **kwargs)
bound_args.apply_defaults()
args = bound_args.args
kwargs = bound_args.kwargs
result = aq_transpiler.converted_call(f, args[1:], kwargs, options=options)
inner_program.autodeclare()
return result
Expand All @@ -440,9 +516,15 @@ def _func(*args, **kwargs) -> Any:
f'Parameter "{param.name}" for subroutine "{_func.__name__}" '
"is missing a required type hint."
)
# Check whether 'param.name' is a OpenQasm keyword
if is_reserved_keyword(param.name):
_name = f"{param.name}_"
_func.__annotations__.pop(param.name)
else:
_name = param.name

new_param = inspect.Parameter(
name=param.name,
name=_name,
kind=param.kind,
annotation=aq_types.map_parameter_type(param.annotation),
)
Expand Down
8 changes: 4 additions & 4 deletions test/unit_tests/autoqasm/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ def sub(float[64] alpha, float[64] theta) {
rx(theta) __qubits__[0];
rx(alpha) __qubits__[1];
}
def rx_alpha(int[32] qubit) {
rx(alpha) __qubits__[qubit];
def rx_alpha(int[32] qubit_) {
rx(alpha) __qubits__[qubit_];
}
float alpha = 0.5;
float beta = 1.5;
Expand All @@ -427,8 +427,8 @@ def parametric(alpha: float, beta: float):
bound_prog = parametric.build().make_bound_program({"beta": np.pi})

expected = """OPENQASM 3.0;
def rx_alpha(int[32] qubit, float[64] theta) {
rx(theta) __qubits__[qubit];
def rx_alpha(int[32] qubit_, float[64] theta) {
rx(theta) __qubits__[qubit_];
}
input float alpha;
float beta = 3.141592653589793;
Expand Down
4 changes: 2 additions & 2 deletions test/unit_tests/autoqasm/test_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ def zne() -> aq.BitVar:
def expected(scale, angle):
return (
"""OPENQASM 3.0;
def circuit(float[64] angle) {
rx(angle) __qubits__[0];
def circuit(float[64] angle_) {
rx(angle_) __qubits__[0];
cnot __qubits__[0], __qubits__[1];
}
output bit return_value;
Expand Down
12 changes: 6 additions & 6 deletions test/unit_tests/autoqasm/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def main():
annotation_test(True)

expected = """OPENQASM 3.0;
def annotation_test(bool input) {
def annotation_test(bool input_) {
}
annotation_test(true);"""

Expand All @@ -328,7 +328,7 @@ def main():
annotation_test(1)

expected = """OPENQASM 3.0;
def annotation_test(int[32] input) {
def annotation_test(int[32] input_) {
}
annotation_test(1);"""

Expand All @@ -347,7 +347,7 @@ def main():
annotation_test(1.0)

expected = """OPENQASM 3.0;
def annotation_test(float[64] input) {
def annotation_test(float[64] input_) {
}
annotation_test(1.0);"""

Expand All @@ -366,7 +366,7 @@ def main():
annotation_test(1)

expected = """OPENQASM 3.0;
def annotation_test(qubit input) {
def annotation_test(qubit input_) {
}
qubit[2] __qubits__;
annotation_test(__qubits__[1]);"""
Expand Down Expand Up @@ -403,7 +403,7 @@ def main():
annotation_test(a)

expected = """OPENQASM 3.0;
def annotation_test(bit input) {
def annotation_test(bit input_) {
}
bit a = 1;
annotation_test(a);"""
Expand All @@ -423,7 +423,7 @@ def main():
annotation_test(aq.BitVar(1))

expected = """OPENQASM 3.0;
def annotation_test(bit input) {
def annotation_test(bit input_) {
}
bit __bit_0__ = 1;
annotation_test(__bit_0__);"""
Expand Down

0 comments on commit 54ff709

Please sign in to comment.