-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests of the example code in the OQ3 spec
This is the start of a big project. Especially becaue a good amount of the code fails. This is in part because we have been increasing the amount of semantic analysis. This is good because less incorrect code is silently allowed. However the are many false positives. This exercise is a good way to identify and organize features that are not supported or that have bugs. This commit covers all of "comments.rst" and 16 percent of the file "types.rst".
- Loading branch information
Showing
1 changed file
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
use oq3_semantics::asg; | ||
use oq3_semantics::semantic_error::SemanticErrorList; | ||
use oq3_semantics::symbols::SymbolTable; | ||
use oq3_semantics::syntax_to_semantics::parse_source_string; | ||
|
||
// This file tests code in the written OpenQASM 3 spec. | ||
// | ||
// The commit from which the example code was taken is written above each test. | ||
// | ||
// Tests that cause the parser to panic are commented out. | ||
// | ||
// Tests of unimplemented features are marked "Not supported". Note that if possible | ||
// these tests are designed to pass. The | ||
|
||
fn parse_string(code: &str) -> (asg::Program, SemanticErrorList, SymbolTable) { | ||
parse_source_string(code, None, None::<&[&std::path::Path]>) | ||
.take_context() | ||
.as_tuple() | ||
} | ||
|
||
// | ||
// comments.rst | ||
// | ||
|
||
// 17dedf | ||
#[test] | ||
fn test_spec_comments_1() { | ||
let code = r#" | ||
// A comment line | ||
/* | ||
A comment block | ||
*/ | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert!(program.is_empty()); | ||
} | ||
|
||
// 17dedf | ||
// NOTE! Two problems here. One: In this version of the spec, | ||
// the file is stdgates.qasm rather than the correct stdgates.inc | ||
// Two: This parser panics rather than gracefully recording an error | ||
// if an included file is not found. | ||
// There is a PR open to fix the spec https://github.com/openqasm/openqasm/pull/523 | ||
// In the meantime, I took the liberty of changing the code in the spec and testing that | ||
// instead. | ||
// Note that neither of the non-comment lines is translated to a statement, so the | ||
// program is still empty. | ||
#[test] | ||
fn test_spec_comments_2() { | ||
let code = r#" | ||
// First non-comment is a version string | ||
OPENQASM 3.0; | ||
include "stdgates.inc"; | ||
// Rest of QASM program | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert!(program.is_empty()); | ||
} | ||
|
||
// | ||
// types.rst | ||
// | ||
|
||
// 17dedf | ||
#[test] | ||
fn test_spec_types_1() { | ||
let code = r#" | ||
qubit q0; | ||
qubit q1; | ||
qubit q2; | ||
// and to declare a set of classical variables | ||
int[32] a; | ||
float[32] b = 5.5; | ||
bit[3] c; | ||
bool my_bool = false; | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert_eq!(program.len(), 7); | ||
} | ||
|
||
// 17dedf | ||
// Not supported | ||
// Issue #211 | ||
// #[test] | ||
// fn test_spec_types_2() { | ||
// let code = r#" | ||
// // Valid statements | ||
|
||
// include "stdgates.inc"; | ||
|
||
// qubit[5] q1; | ||
// const uint SIZE = 4; | ||
// uint runtime_u = 2; | ||
// qubit[SIZE] q2; // Declare a 4-qubit register. | ||
|
||
// x q1[0]; | ||
// z q2[SIZE - 2]; // The index operand is of type `const uint`. | ||
|
||
// // Validity is implementation-defined. | ||
|
||
// x q1[runtime_u]; | ||
// // Indexing with a value with a non-`const` type (`uint`, in this case) is | ||
// // not guaranteed to be supported. | ||
// "#; | ||
// let (_program, errors, _symbol_table) = parse_string(code); | ||
// assert_eq!(errors.len(), 0); | ||
// } | ||
|
||
// 17dedf | ||
#[test] | ||
fn test_spec_types_3() { | ||
let code = r#" | ||
// Declare a qubit | ||
qubit gamma; | ||
// Declare a qubit with a Unicode name | ||
qubit γ; | ||
// Declare a qubit register with 20 qubits | ||
qubit[20] qubit_array; | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert_eq!(program.len(), 3); | ||
} | ||
|
||
// 17dedf | ||
#[test] | ||
fn test_spec_types_4() { | ||
let code = r#" | ||
// Not in spec code block | ||
include "stdgates.inc"; | ||
// CNOT gate between physical qubits 0 and 1 | ||
CX $0, $1; | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert_eq!(program.len(), 1); | ||
} | ||
|
||
// 17dedf | ||
// Bug | ||
// Incorrect syntax error recorded. | ||
// Not supported in the semantic analysis. | ||
// Issue #210 | ||
#[test] | ||
fn test_spec_types_5() { | ||
let code = r#" | ||
defcal h $0 { } | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert_eq!(program.len(), 0); | ||
} | ||
|
||
#[test] | ||
fn test_spec_types_6() { | ||
let code = r#" | ||
// Declare a register of 20 bits | ||
bit[20] bit_array; | ||
// Declare and assign a register of bits with decimal value of 15 | ||
bit[8] name = "00001111"; | ||
"#; | ||
let (program, errors, _symbol_table) = parse_string(code); | ||
assert!(errors.is_empty()); | ||
assert_eq!(program.len(), 2); | ||
} |