diff --git a/crates/oq3_parser/src/grammar/items.rs b/crates/oq3_parser/src/grammar/items.rs index 42cbfa6..9ab04ca 100644 --- a/crates/oq3_parser/src/grammar/items.rs +++ b/crates/oq3_parser/src/grammar/items.rs @@ -417,7 +417,7 @@ fn version_(p: &mut Parser<'_>) -> bool { fn barrier_(p: &mut Parser<'_>, m: Marker) { p.bump(T![barrier]); if !p.at(T![;]) { - params::param_list_gate_qubits(p); + params::arg_list_gate_call_qubits(p); } p.expect(SEMICOLON); m.complete(p, BARRIER); diff --git a/crates/oq3_semantics/src/asg.rs b/crates/oq3_semantics/src/asg.rs index 7bb110c..5a5797c 100644 --- a/crates/oq3_semantics/src/asg.rs +++ b/crates/oq3_semantics/src/asg.rs @@ -171,7 +171,7 @@ pub enum Stmt { Alias, // stub AnnotatedStmt(AnnotatedStmt), Assignment(Assignment), - Barrier, // stub + Barrier(Barrier), Block(Block), Box, // stub Break, @@ -589,6 +589,21 @@ impl MeasureExpression { } } +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Barrier { + qubits: Vec, +} + +impl Barrier { + pub fn new(qubits: Vec) -> Barrier { + Barrier { qubits } + } + + pub fn qubits(&self) -> &Vec { + &self.qubits + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct GateCall { name: SymbolIdResult, diff --git a/crates/oq3_semantics/src/syntax_to_semantics.rs b/crates/oq3_semantics/src/syntax_to_semantics.rs index edc8fb2..919c5a0 100644 --- a/crates/oq3_semantics/src/syntax_to_semantics.rs +++ b/crates/oq3_semantics/src/syntax_to_semantics.rs @@ -249,7 +249,7 @@ fn from_gate_operand(gate_operand: synast::GateOperand, context: &mut Context) - } synast::GateOperand::Identifier(ref identifier) => { let (astidentifier, typ) = ast_identifier(identifier, context); - if !matches!(typ, Type::Qubit | Type::HardwareQubit) { + if !matches!(typ, Type::Qubit | Type::HardwareQubit | Type::QubitArray(_)) { context.insert_error(IncompatibleTypesError, &gate_operand); } asg::GateOperand::Identifier(astidentifier).to_texpr(typ) @@ -485,6 +485,16 @@ fn from_item(item: synast::Item, context: &mut Context) -> Option { ))) } + synast::Item::Barrier(barrier) => { + let gate_operands: Vec<_> = barrier + .qubit_list() + .unwrap() + .gate_operands() + .map(|qubit| from_gate_operand(qubit, context)) + .collect(); + Some(asg::Stmt::Barrier(asg::Barrier::new(gate_operands))) + } + synast::Item::Include(include) => { if context.symbol_table().current_scope_type() != ScopeType::Global { context.insert_error(IncludeNotInGlobalScopeError, &include); diff --git a/crates/oq3_semantics/tests/from_string_tests.rs b/crates/oq3_semantics/tests/from_string_tests.rs index 63fb0c7..3eeb805 100644 --- a/crates/oq3_semantics/tests/from_string_tests.rs +++ b/crates/oq3_semantics/tests/from_string_tests.rs @@ -245,3 +245,15 @@ h q[1]; assert!(errors.is_empty()); assert_eq!(program.len(), 3); } + +#[test] +fn test_from_string_barrier() { + let code = r#" +qubit[5] q; +barrier q; +barrier $0, $1; +"#; + let (program, errors, _symbol_table) = parse_string(code); + assert!(errors.is_empty()); + assert_eq!(program.len(), 3); +}