use std::collections::HashMap;
use std::iter::FromIterator;
use crate::error::QasmSimError;
use crate::grammar::{ast, parse_program};
use crate::interpreter;
use crate::interpreter::runtime::RuntimeError;
use crate::linker::Linker;
use crate::qe;
use crate::semantics;
pub type Result<'src, T> = std::result::Result<T, QasmSimError<'src>>;
fn default_linker() -> Linker {
Linker::with_embedded(HashMap::from_iter(vec![(
"qelib1.inc".to_owned(),
qe::QELIB1.to_owned(),
)]))
}
pub fn parse_and_link(input: &str) -> Result<'_, ast::OpenQasmProgram> {
let linker = default_linker();
let program = parse_program(input)?;
linker
.link(program)
.map_err(|err| QasmSimError::from((input, err)))
}
type GateSignature = (String, Vec<String>, Vec<String>);
pub fn get_gate_info<'src>(
input: &'src str,
gate_name: &str,
) -> Result<'src, (String, GateSignature)> {
let linked = parse_and_link(input)?;
let semantics = semantics::extract_semantics(&linked)
.map_err(|err| QasmSimError::from((input, RuntimeError::from(err))))?;
let docstring =
semantics
.symbol_docstrings
.get(gate_name)
.ok_or(QasmSimError::UndefinedGate {
source: "",
lineno: 0,
symbol_name: String::from(gate_name),
})?;
let macro_def =
semantics
.macro_definitions
.get(gate_name)
.ok_or(QasmSimError::UndefinedGate {
source: "",
lineno: 0,
symbol_name: String::from(gate_name),
})?;
Ok((
docstring.to_string(),
(
macro_def.0.clone(),
macro_def.1.clone(),
macro_def.2.clone(),
),
))
}
pub use interpreter::runtime::simulate;
pub use interpreter::runtime::simulate_with_shots;