Skip to content

Commit

Permalink
New: support DEFCIRCUIT
Browse files Browse the repository at this point in the history
  • Loading branch information
notmgsk committed Jul 22, 2021
1 parent 78cff3d commit 305f529
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ impl fmt::Display for Instruction {
} => {
let mut parameter_str: String = parameters
.iter()
.map(|p| p.to_string())
.map(|p| format!("%{}", p.to_string()))
.collect::<Vec<String>>()
.join(", ");
if !parameter_str.is_empty() {
Expand Down
102 changes: 101 additions & 1 deletion src/parser/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ use super::{
expression::parse_expression,
instruction, ParserInput, ParserResult,
};
use crate::parser::common::parse_variable_qubits;
use crate::parser::instruction::parse_block;
use crate::{
instruction::{
ArithmeticOperand, ArithmeticOperator, Calibration, FrameIdentifier, Instruction, Waveform,
Expand Down Expand Up @@ -151,6 +153,29 @@ pub fn parse_defwaveform<'a>(input: ParserInput<'a>) -> ParserResult<'a, Instruc
))
}

pub fn parse_defcircuit<'a>(input: ParserInput<'a>) -> ParserResult<'a, Instruction> {
let (input, name) = token!(Identifier(v))(input)?;
let (input, parameters) = opt(delimited(
token!(LParenthesis),
separated_list0(token!(Comma), token!(Variable(v))),
token!(RParenthesis),
))(input)?;
let parameters = parameters.unwrap_or_default();
let (input, qubit_variables) = parse_variable_qubits(input)?;
let (input, _) = token!(Colon)(input)?;
let (input, instructions) = parse_block(input)?;

Ok((
input,
Instruction::CircuitDefinition {
name,
parameters,
qubit_variables,
instructions,
},
))
}

/// Parse the contents of a `DELAY` instruction.
pub fn parse_delay<'a>(input: ParserInput<'a>) -> ParserResult<'a, Instruction> {
let (input, qubits) = parse_qubits(input)?;
Expand Down Expand Up @@ -328,7 +353,8 @@ mod tests {
make_test,
};

use super::{parse_declare, parse_measurement, parse_pragma};
use super::{parse_declare, parse_defcircuit, parse_measurement, parse_pragma};
use crate::expression::Expression;

make_test!(
declare_instruction_length_1,
Expand Down Expand Up @@ -414,4 +440,78 @@ mod tests {
data: Some("{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q35_ro_rx/filter','publish':true,'params':{},'_type':'FilterNode'}".to_owned())
}
);

make_test!(
defcircuit_no_params,
parse_defcircuit,
"BELL a b:
H a
CNOT a b",
Instruction::CircuitDefinition {
name: "BELL".to_owned(),
parameters: vec![],
qubit_variables: vec!["a".to_owned(), "b".to_owned()],
instructions: vec![
Instruction::Gate {
name: "H".to_owned(),
parameters: vec![],
qubits: vec![Qubit::Variable("a".to_owned())],
modifiers: vec![],
},
Instruction::Gate {
name: "CNOT".to_owned(),
parameters: vec![],
qubits: vec![
Qubit::Variable("a".to_owned()),
Qubit::Variable("b".to_owned())
],
modifiers: vec![],
}
]
}
);

make_test!(
defcircuit_with_params,
parse_defcircuit,
"BELL(%a) a b:
RZ(%a) a
RX(%a) a
RZ(%a) a
CNOT a b",
Instruction::CircuitDefinition {
name: "BELL".to_owned(),
parameters: vec!["a".to_owned()],
qubit_variables: vec!["a".to_owned(), "b".to_owned()],
instructions: vec![
Instruction::Gate {
name: "RZ".to_owned(),
parameters: vec![Expression::Variable("a".to_owned())],
qubits: vec![Qubit::Variable("a".to_owned())],
modifiers: vec![],
},
Instruction::Gate {
name: "RX".to_owned(),
parameters: vec![Expression::Variable("a".to_owned())],
qubits: vec![Qubit::Variable("a".to_owned())],
modifiers: vec![],
},
Instruction::Gate {
name: "RZ".to_owned(),
parameters: vec![Expression::Variable("a".to_owned())],
qubits: vec![Qubit::Variable("a".to_owned())],
modifiers: vec![],
},
Instruction::Gate {
name: "CNOT".to_owned(),
parameters: vec![],
qubits: vec![
Qubit::Variable("a".to_owned()),
Qubit::Variable("b".to_owned())
],
modifiers: vec![],
}
]
}
);
}
22 changes: 21 additions & 1 deletion src/parser/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub fn parse_qubit(input: ParserInput) -> ParserResult<Qubit> {
match input.split_first() {
None => Err(nom::Err::Error(Error {
input,
error: ErrorKind::UnexpectedEOF("something else".to_owned()),
error: ErrorKind::UnexpectedEOF("a qubit".to_owned()),
})),
Some((Token::Integer(value), remainder)) => Ok((remainder, Qubit::Fixed(*value))),
Some((Token::Variable(name), remainder)) => Ok((remainder, Qubit::Variable(name.clone()))),
Expand All @@ -170,6 +170,26 @@ pub fn parse_qubits(input: ParserInput) -> ParserResult<Vec<Qubit>> {
many0(parse_qubit)(input)
}

/// Parse a variable qubit (i.e. a named qubit)
pub fn parse_variable_qubit(input: ParserInput) -> ParserResult<String> {
match input.split_first() {
None => Err(nom::Err::Error(Error {
input,
error: ErrorKind::UnexpectedEOF("a variable qubit".to_owned()),
})),
Some((Token::Variable(name), remainder)) => Ok((remainder, name.clone())),
Some((Token::Identifier(name), remainder)) => Ok((remainder, name.clone())),
Some((other_token, _)) => {
expected_token!(input, other_token, stringify!($expected_variant).to_owned())
}
}
}

/// Parse zero or more variable qubits in sequence
pub fn parse_variable_qubits(input: ParserInput) -> ParserResult<Vec<String>> {
many0(parse_variable_qubit)(input)
}

/// Parse a "vector" which is an integer index, such as `[0]`
pub fn parse_vector<'a>(input: ParserInput<'a>) -> ParserResult<'a, Vector> {
let (input, data_type_token) = token!(DataType(v))(input)?;
Expand Down
2 changes: 1 addition & 1 deletion src/parser/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub fn parse_instruction(input: ParserInput) -> ParserResult<Instruction> {
// Command::Convert => {}
Command::Declare => command::parse_declare(remainder),
Command::DefCal => command::parse_defcal(remainder),
// Command::DefCircuit => {}
Command::DefCircuit => command::parse_defcircuit(remainder),
Command::DefFrame => command::parse_defframe(remainder),
// Command::DefGate => Ok((remainder, cut(parse_command_defgate))),
Command::DefWaveform => command::parse_defwaveform(remainder),
Expand Down

0 comments on commit 305f529

Please sign in to comment.