Skip to content

Commit 905deeb

Browse files
committed
bitstring processing is more efficient
1 parent 95933e1 commit 905deeb

File tree

3 files changed

+31
-25
lines changed

3 files changed

+31
-25
lines changed

compiler/qsc_qasm/src/ast_builder.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -211,30 +211,13 @@ pub(crate) fn build_lit_result_expr(value: qsc_ast::ast::Result, span: Span) ->
211211
}
212212
}
213213

214-
pub(crate) fn build_lit_result_array_expr_from_bitstring<S: AsRef<str>>(
215-
bitstring: S,
214+
pub(crate) fn build_lit_result_array_expr<I: IntoIterator<Item = ast::Result>>(
215+
values: I,
216216
span: Span,
217217
) -> Expr {
218-
let values = bitstring
219-
.as_ref()
220-
.chars()
221-
.filter_map(|c| {
222-
if c == '0' {
223-
Some(ast::Result::Zero)
224-
} else if c == '1' {
225-
Some(ast::Result::One)
226-
} else {
227-
None
228-
}
229-
})
230-
.collect();
231-
build_lit_result_array_expr(values, span)
232-
}
233-
234-
pub(crate) fn build_lit_result_array_expr(values: Vec<qsc_ast::ast::Result>, span: Span) -> Expr {
235218
let exprs: Vec<_> = values
236219
.into_iter()
237-
.map(|v| build_lit_result_expr(v, Span::default()))
220+
.map(|value| build_lit_result_expr(value, Span::default()))
238221
.collect();
239222
build_expr_array_expr(exprs, span)
240223
}

compiler/qsc_qasm/src/compiler.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
build_if_expr_then_block_else_expr, build_if_expr_then_expr_else_expr,
2525
build_implicit_return_stmt, build_index_expr, build_indexed_assignment_statement,
2626
build_lit_angle_expr, build_lit_bigint_expr, build_lit_bool_expr, build_lit_complex_expr,
27-
build_lit_double_expr, build_lit_int_expr, build_lit_result_array_expr_from_bitstring,
27+
build_lit_double_expr, build_lit_int_expr, build_lit_result_array_expr,
2828
build_lit_result_expr, build_managed_qubit_alloc, build_math_call_from_exprs,
2929
build_math_call_no_params, build_measure_call, build_operation_with_stmts,
3030
build_path_ident_expr, build_path_ident_ty, build_qasm_import_decl,
@@ -1534,12 +1534,29 @@ impl QasmCompiler {
15341534

15351535
fn compile_bitstring_literal(value: &BigInt, width: u32, span: Span) -> qsast::Expr {
15361536
let width = width as usize;
1537-
let bitstring = if value == &BigInt::ZERO && width == 0 {
1538-
"Bitstring(\"\")".to_string()
1537+
// Handle the special case where the value is zero and width is zero
1538+
if value == &BigInt::ZERO && width == 0 {
1539+
return build_lit_result_array_expr(vec![], span);
1540+
}
1541+
1542+
let binary = value.to_str_radix(2).into_bytes().into_iter().map(|b| {
1543+
// the string bytes are ASCII bytes, so we check their value offset from b'0'
1544+
if (b - b'0') == 0 {
1545+
qsast::Result::Zero
1546+
} else {
1547+
qsast::Result::One
1548+
}
1549+
});
1550+
// Pad the binary representation with leading zeros to match the width
1551+
let values = if binary.len() < width {
1552+
let mut padded = vec![qsast::Result::Zero; width - binary.len()];
1553+
padded.extend(binary);
1554+
padded
15391555
} else {
1540-
format!("Bitstring(\"{:0>width$}\")", value.to_str_radix(2))
1556+
binary.collect()
15411557
};
1542-
build_lit_result_array_expr_from_bitstring(bitstring, span)
1558+
1559+
build_lit_result_array_expr(values, span)
15431560
}
15441561

15451562
fn compile_complex_literal(real: f64, imag: f64, span: Span) -> qsast::Expr {

compiler/qsc_qasm/src/tests/fuzz.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,9 @@ fn fuzz_2392() {
113113
let source = "e[π:";
114114
compile_qasm_best_effort(source, Profile::Unrestricted);
115115
}
116+
117+
#[test]
118+
fn fuzz_2397() {
119+
let source = "creg a[551615";
120+
compile_qasm_best_effort(source, Profile::Unrestricted);
121+
}

0 commit comments

Comments
 (0)