Skip to content

Commit

Permalink
Implement reset end to end (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
jlapeyre authored Feb 16, 2024
1 parent 61fd2e1 commit b174b2b
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 33 deletions.
61 changes: 32 additions & 29 deletions crates/oq3_parser/src/grammar/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> {
T![defcal] => defcal_(p, m),
T![cal] => cal_(p, m),
T![defcalgrammar] => defcalgrammar_(p, m),
T![reset] => reset_(p, m),
T![reset] => reset_stmt(p, m),
T![barrier] => barrier_(p, m),
T![OPENQASM] => version_string(p, m),
T![include] => include(p, m),
Expand Down Expand Up @@ -191,43 +191,46 @@ fn qubit_declaration_stmt(p: &mut Parser<'_>, m: Marker) {
// can be used in so many places in Rust. Eg. `myfunc(arg1, arg2)[ind1]`.
// But in OQ3, a qubit needs to
// Be an identifier or an identifier followed by '[', etc.
pub(crate) fn ident_or_index_expr(p: &mut Parser<'_>) {
let m = p.start();
match p.current() {
IDENT => {
p.bump(IDENT);
match p.current() {
T!['['] => {
let newm = m.complete(p, IDENTIFIER);
expressions::index_expr(p, newm);
}
_ => {
// FIXME: m.complete(p, IDENT) is valid, but it should not be
// it is a source of bugs!
m.complete(p, IDENTIFIER);
}
}
}
HARDWAREIDENT => {
p.bump(HARDWAREIDENT);
m.complete(p, HARDWARE_QUBIT);
}
_ => panic!(),
}
}

fn reset_(p: &mut Parser<'_>, m: Marker) {
// pub(crate) fn ident_or_index_expr(p: &mut Parser<'_>) {
// let m = p.start();
// match p.current() {
// IDENT => {
// p.bump(IDENT);
// match p.current() {
// T!['['] => {
// let newm = m.complete(p, IDENTIFIER);
// expressions::index_expr(p, newm);
// }
// _ => {
// // FIXME: m.complete(p, IDENT) is valid, but it should not be
// // it is a source of bugs!
// m.complete(p, IDENTIFIER);
// }
// }
// }
// HARDWAREIDENT => {
// p.bump(HARDWAREIDENT);
// m.complete(p, HARDWARE_QUBIT);
// }
// _ => panic!(),
// }
// }

fn reset_stmt(p: &mut Parser<'_>, m: Marker) {
p.bump(T![reset]);
match p.current() {
IDENT | HARDWAREIDENT => {
ident_or_index_expr(p);
let m1 = p.start();
// Parses elements that can be cast to GateOperand
params::arg_gate_call_qubit(p, m1);
}
_ => {
p.error("expecting name of qubit to reset");
p.error("expecting name of qubit or register to reset");
m.abandon(p);
return;
}
}
p.expect(SEMICOLON);
m.complete(p, RESET);
}

Expand Down
17 changes: 16 additions & 1 deletion crates/oq3_semantics/src/asg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub enum Stmt {
NullStmt, // for testing
OldStyleDeclaration, // stub
Pragma(Pragma),
Reset, // stub
Reset(Reset),
Return, // stub
SwitchCaseStmt(SwitchCaseStmt),
While(While),
Expand Down Expand Up @@ -689,6 +689,21 @@ impl ModifiedGPhaseCall {
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Reset {
gate_operand: TExpr,
}

impl Reset {
pub fn new(gate_operand: TExpr) -> Reset {
Reset { gate_operand }
}

pub fn gate_operand(&self) -> &TExpr {
&self.gate_operand
}
}

// This is one of several examples where instead of `enum Literal`
// we could do something like `struct Literal<T>`.
// However, if the dispatch must occur at runtime (In Rust called "dynamic",
Expand Down
7 changes: 7 additions & 0 deletions crates/oq3_semantics/src/syntax_to_semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,12 @@ fn from_stmt(stmt: synast::Stmt, context: &mut Context) -> Option<asg::Stmt> {
Some(asg::Stmt::Barrier(asg::Barrier::new(gate_operands)))
}

synast::Stmt::Reset(reset) => {
let gate_operand = reset.gate_operand().unwrap(); // FIXME: check this
let gate_operand_asg = from_gate_operand(gate_operand, context);
Some(asg::Stmt::Reset(asg::Reset::new(gate_operand_asg)))
}

synast::Stmt::Include(include) => {
if context.symbol_table().current_scope_type() != ScopeType::Global {
context.insert_error(IncludeNotInGlobalScopeError, &include);
Expand All @@ -349,6 +355,7 @@ fn from_stmt(stmt: synast::Stmt, context: &mut Context) -> Option<asg::Stmt> {
let _ = version.split_into_parts();
None
}

_ => None,
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/oq3_syntax/openqasm3.ungram
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ Version =
// TODO: make this more precise.
// I was getting errors when trying
Reset =
'reset' qubit:Expr
'reset' GateOperand

Measure =
'measure' qubit:Expr ';'
Expand Down
2 changes: 1 addition & 1 deletion crates/oq3_syntax/src/ast/generated/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ impl Reset {
pub fn reset_token(&self) -> Option<SyntaxToken> {
support::token(&self.syntax, T![reset])
}
pub fn qubit(&self) -> Option<Expr> {
pub fn gate_operand(&self) -> Option<GateOperand> {
support::child(&self.syntax)
}
}
Expand Down
3 changes: 2 additions & 1 deletion local_CI.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@

cargo fmt --all -- --check || exit 1
cargo build --release --verbose || exit 1
cargo clippy --all-targets -- -D warnings -D clippy::dbg_macro || exit 1
cargo test --verbose --lib --tests -- --skip sourcegen_ast --skip sourcegen_ast_nodes || exit 1
cargo clippy --all-targets -- -D warnings -D clippy::dbg_macro || exit 1

0 comments on commit b174b2b

Please sign in to comment.