Skip to content

Commit

Permalink
Set type of measurement expression correctly (#52)
Browse files Browse the repository at this point in the history
* Set type of measurement expression correctly
That is measuring a qubit or hardware qubit results in a bit.
Measuring a qubit register results in a bit register of the same length.

* Log semantic error for incorrectly typed args to `measure`.

Closes #51
  • Loading branch information
jlapeyre authored Jan 19, 2024
1 parent 32e84de commit 3e99dd0
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 8 deletions.
10 changes: 7 additions & 3 deletions crates/oq3_semantics/src/asg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ impl Program {
let _ = &self.stmts.push(stmt);
}

// FIXME: This should probably log a semantic error rather than panic.
// The check should be done when checking syntax.
// This check may be overly restrictive, as one might want to manipulate
// or construct a `Program` in a way other than sequentially translating
Expand Down Expand Up @@ -578,10 +579,13 @@ impl MeasureExpression {
&self.operand
}

// FIXME: type may not be correct here.
// This assumes a single qubit is measured.
pub fn to_texpr(self) -> TExpr {
TExpr::new(Expr::MeasureExpression(self), Type::Bit(IsConst::False))
let out_type = match self.operand.get_type() {
Type::Qubit | Type::HardwareQubit => Type::Bit(IsConst::False),
Type::QubitArray(dims) => Type::BitArray(dims.clone(), IsConst::False),
_ => Type::Undefined,
};
TExpr::new(Expr::MeasureExpression(self), out_type)
}
}

Expand Down
14 changes: 10 additions & 4 deletions crates/oq3_semantics/src/syntax_to_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,18 @@ fn from_gate_operand(gate_operand: synast::GateOperand, context: &mut Context) -
synast::GateOperand::HardwareQubit(ref hwq) => {
asg::GateOperand::HardwareQubit(ast_hardware_qubit(hwq)).to_texpr(Type::HardwareQubit)
}
synast::GateOperand::Identifier(identifier) => {
let (astidentifier, typ) = ast_identifier(&identifier, context);
synast::GateOperand::Identifier(ref identifier) => {
let (astidentifier, typ) = ast_identifier(identifier, context);
if !matches!(typ, Type::Qubit | Type::HardwareQubit) {
context.insert_error(IncompatibleTypesError, &gate_operand);
}
asg::GateOperand::Identifier(astidentifier).to_texpr(typ)
}
synast::GateOperand::IndexedIdentifier(indexed_identifier) => {
let (indexed_identifier, typ) = ast_indexed_identifier(&indexed_identifier, context);
synast::GateOperand::IndexedIdentifier(ref indexed_identifier) => {
let (indexed_identifier, typ) = ast_indexed_identifier(indexed_identifier, context);
if !matches!(typ, Type::QubitArray(_)) {
context.insert_error(IncompatibleTypesError, &gate_operand);
}
asg::GateOperand::IndexedIdentifier(indexed_identifier).to_texpr(typ)
}
}
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 @@ -152,7 +152,7 @@ fn test_gate_call() {
mygate(x, y) q;
"##;
let (program, errors, _symbol_table) = parse_string(code);
assert_eq!(errors.len(), 4);
assert_eq!(errors.len(), 5);
assert_eq!(program.len(), 1);
}

Expand Down

0 comments on commit 3e99dd0

Please sign in to comment.