Skip to content

Commit

Permalink
Give correct type to qubit register param in def (#184)
Browse files Browse the repository at this point in the history
Previously the type of any quantum parameter was `Qubit`. This
commit gives a qubit register the correct type, that is a one
dimensional qubit array.

A test was in place that verified the wrong behavior. Now it verifies
the correct behavior.

Unrelated changes made while debugging: Some default match arms
were changed to be explicit.
  • Loading branch information
jlapeyre committed Mar 21, 2024
1 parent e120cab commit 4694478
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 9 deletions.
13 changes: 6 additions & 7 deletions crates/oq3_parser/src/grammar/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn _param_list_openqasm(p: &mut Parser<'_>, flavor: DefFlavor, m: Option<Marker>
let want_parens = matches!(flavor, GateParams | DefParams | DefCalParams);
match flavor {
GateParams | DefParams | DefCalParams => p.bump(T!['(']),
_ => (),
GateQubits | GateCallQubits | DefCalQubits | ExpressionList => (),
}
// FIXME: find implementation that does not require [T![')'], T![')']]
// I tried using TokenSet, which should give exactly the same result.
Expand Down Expand Up @@ -87,9 +87,10 @@ fn _param_list_openqasm(p: &mut Parser<'_>, flavor: DefFlavor, m: Option<Marker>
true
}
GateCallQubits => arg_gate_call_qubit(p, m),
// FIXME: this can't work. These two variants have different reqs on params
DefParams | DefCalParams => param_typed(p, m),
// The following is pretty ugly. Probably inefficient as well
_ => param_untyped(p, m),
GateParams | GateQubits | DefCalQubits => param_untyped(p, m),
};
if !found_param {
break;
Expand Down Expand Up @@ -118,12 +119,12 @@ fn _param_list_openqasm(p: &mut Parser<'_>, flavor: DefFlavor, m: Option<Marker>
GateParams | ExpressionList if num_params < 1 => {
p.error("expected one or more parameters");
}
_ => {}
GateParams | ExpressionList => {}
GateQubits | GateCallQubits | DefParams | DefCalParams | DefCalQubits => {}
};
if let Some(m) = param_marker {
m.abandon(p);
}
// FIXME: rewrite followig as match statement.
// Error if we don't find closing paren.
if want_parens {
p.expect(T![')']);
Expand All @@ -134,11 +135,9 @@ fn _param_list_openqasm(p: &mut Parser<'_>, flavor: DefFlavor, m: Option<Marker>
GateCallQubits => QUBIT_LIST,
ExpressionList => EXPRESSION_LIST,
DefParams | DefCalParams => TYPED_PARAM_LIST,
_ => PARAM_LIST,
GateParams => PARAM_LIST,
};
list_marker.complete(p, kind);
// let is_qubits = matches!(flavor, GateQubits | DefCalQubits);
// list_marker.complete(p, if is_qubits {QUBIT_LIST} else {PARAM_LIST});
}

const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST
Expand Down
8 changes: 7 additions & 1 deletion crates/oq3_semantics/src/syntax_to_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,13 @@ fn from_scalar_type(
synast::ScalarTypeKind::None => panic!("You have found a bug in oq3_parser"),
synast::ScalarTypeKind::Stretch => Type::Stretch(isconst.into()),
synast::ScalarTypeKind::UInt => Type::UInt(width, isconst.into()),
synast::ScalarTypeKind::Qubit => Type::Qubit,
// The spec says a qubit register is equivalent to a 1D qubit array.
// Trying to maintain a non-existent distinction would lead to bad confusion.
// This is the point where we eliminate the distinction. (Code is repeated elsewhere.)
synast::ScalarTypeKind::Qubit => match width {
Some(width) => Type::QubitArray(ArrayDims::D1(width as usize)),
None => Type::Qubit,
},
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oq3_semantics/tests/from_string_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,6 @@ def xcheck(qubit[4] d, qubit a) -> bit {
}
"##;
let (program, errors, _symbol_table) = parse_string(code);
assert_eq!(errors.len(), 1);
assert_eq!(errors.len(), 0);
assert_eq!(program.len(), 2);
}

0 comments on commit 4694478

Please sign in to comment.