Skip to content

Commit 11dfc2b

Browse files
authored
Merge 9ca4839 into fed61c0
2 parents fed61c0 + 9ca4839 commit 11dfc2b

File tree

24 files changed

+884
-699
lines changed

24 files changed

+884
-699
lines changed

library/std/src/Std/OpenQASM/Angle.qs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// Export the Angle type and its associated functions.
99
export Angle;
1010
// Export the array conversion functions for Angle.
11-
export AngleAsBoolArrayBE, AngleAsResultArray;
11+
export AngleAsBoolArrayBE, AngleAsResultArrayBE;
1212
// Export cast from Angle to other types.
1313
export AngleAsDouble, AngleAsBool, AngleAsResult;
1414
// Export cast from other types to Angle.
@@ -34,10 +34,6 @@ function AngleAsBoolArrayBE(angle : Angle) : Bool[] {
3434
Std.Arrays.Reversed(Std.Convert.IntAsBoolArray(angle.Value, angle.Size))
3535
}
3636

37-
function AngleAsResultArray(angle : Angle) : Result[] {
38-
Std.OpenQASM.Convert.IntAsResultArrayBE(angle.Value, angle.Size)
39-
}
40-
4137
function AngleAsDouble(angle : Angle) : Double {
4238
let F64_MANTISSA_DIGITS = 53;
4339
let angle = if angle.Size > F64_MANTISSA_DIGITS {

source/compiler/qsc_qasm/src/ast_builder.rs

Lines changed: 1 addition & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -402,90 +402,7 @@ pub(crate) fn build_path_ident_expr<S: AsRef<str>>(
402402
}
403403
}
404404

405-
pub(crate) fn build_indexed_assignment_statement<S: AsRef<str>>(
406-
name_span: Span,
407-
string_name: S,
408-
index_expr: ast::Expr,
409-
rhs: Expr,
410-
stmt_span: Span,
411-
) -> ast::Stmt {
412-
let ident = ast::Ident {
413-
id: NodeId::default(),
414-
span: name_span,
415-
name: Rc::from(string_name.as_ref()),
416-
};
417-
418-
let lhs = ast::Expr {
419-
id: NodeId::default(),
420-
span: name_span,
421-
kind: Box::new(ast::ExprKind::Path(PathKind::Ok(Box::new(ast::Path {
422-
id: NodeId::default(),
423-
span: name_span,
424-
segments: None,
425-
name: Box::new(ident.clone()),
426-
})))),
427-
};
428-
429-
let assign_up = ast::StmtKind::Semi(Box::new(ast::Expr {
430-
id: NodeId::default(),
431-
span: Span::default(),
432-
kind: Box::new(ast::ExprKind::AssignUpdate(
433-
Box::new(lhs),
434-
Box::new(index_expr),
435-
Box::new(rhs),
436-
)),
437-
}));
438-
ast::Stmt {
439-
id: NodeId::default(),
440-
span: stmt_span,
441-
kind: Box::new(assign_up),
442-
}
443-
}
444-
445-
pub(crate) fn build_ternary_update_expr(
446-
lhs: ast::Expr,
447-
index: ast::Expr,
448-
rhs: ast::Expr,
449-
) -> ast::Expr {
450-
let span = Span {
451-
lo: lhs.span.lo,
452-
hi: rhs.span.hi,
453-
};
454-
455-
ast::Expr {
456-
id: Default::default(),
457-
span,
458-
kind: Box::new(ast::ExprKind::TernOp(
459-
ast::TernOp::Update,
460-
Box::new(lhs),
461-
Box::new(index),
462-
Box::new(rhs),
463-
)),
464-
}
465-
}
466-
467-
pub(crate) fn build_assignment_statement<S: AsRef<str>>(
468-
name_span: Span,
469-
name: S,
470-
rhs: Expr,
471-
assignment_span: Span,
472-
) -> ast::Stmt {
473-
let ident = ast::Ident {
474-
id: NodeId::default(),
475-
span: name_span,
476-
name: Rc::from(name.as_ref()),
477-
};
478-
let path = ast::Path {
479-
id: NodeId::default(),
480-
span: name_span,
481-
name: Box::new(ident),
482-
segments: None,
483-
};
484-
let lhs = ast::Expr {
485-
id: NodeId::default(),
486-
span: name_span,
487-
kind: Box::new(ast::ExprKind::Path(PathKind::Ok(Box::new(path)))),
488-
};
405+
pub(crate) fn build_assignment_statement(lhs: Expr, rhs: Expr, assignment_span: Span) -> ast::Stmt {
489406
let expr_kind = ast::ExprKind::Assign(Box::new(lhs), Box::new(rhs));
490407
let expr = ast::Expr {
491408
id: NodeId::default(),

source/compiler/qsc_qasm/src/compiler.rs

Lines changed: 45 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,25 @@ use crate::{
2222
build_gate_call_param_expr, build_gate_call_with_params_and_callee,
2323
build_if_expr_then_block, build_if_expr_then_block_else_block,
2424
build_if_expr_then_block_else_expr, build_if_expr_then_expr_else_expr,
25-
build_implicit_return_stmt, build_index_expr, build_indexed_assignment_statement,
26-
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,
28-
build_lit_result_expr, build_managed_qubit_alloc, build_math_call_from_exprs,
29-
build_math_call_no_params, build_measure_call, build_measureeachz_call,
30-
build_operation_with_stmts, build_path_ident_expr, build_path_ident_ty,
31-
build_qasm_import_decl, build_qasm_import_items,
25+
build_implicit_return_stmt, build_index_expr, build_lit_angle_expr, build_lit_bigint_expr,
26+
build_lit_bool_expr, build_lit_complex_expr, build_lit_double_expr, build_lit_int_expr,
27+
build_lit_result_array_expr, build_lit_result_expr, build_managed_qubit_alloc,
28+
build_math_call_from_exprs, build_math_call_no_params, build_measure_call,
29+
build_measureeachz_call, build_operation_with_stmts, build_path_ident_expr,
30+
build_path_ident_ty, build_qasm_import_decl, build_qasm_import_items,
3231
build_qasmstd_convert_call_with_two_params, build_range_expr, build_reset_all_call,
3332
build_reset_call, build_return_expr, build_return_unit, build_stmt_semi_from_expr,
34-
build_stmt_semi_from_expr_with_span, build_ternary_update_expr,
35-
build_top_level_ns_with_items, build_tuple_expr, build_unary_op_expr,
36-
build_unmanaged_qubit_alloc, build_unmanaged_qubit_alloc_array, build_while_stmt,
37-
build_wrapped_block_expr, managed_qubit_alloc_array, map_qsharp_type_to_ast_ty,
38-
wrap_expr_in_parens,
33+
build_stmt_semi_from_expr_with_span, build_top_level_ns_with_items, build_tuple_expr,
34+
build_unary_op_expr, build_unmanaged_qubit_alloc, build_unmanaged_qubit_alloc_array,
35+
build_while_stmt, build_wrapped_block_expr, managed_qubit_alloc_array,
36+
map_qsharp_type_to_ast_ty, wrap_expr_in_parens,
3937
},
4038
io::SourceResolver,
4139
parser::ast::{list_from_iter, List},
4240
semantic::{
4341
ast::{
44-
Array, BinaryOpExpr, Cast, Expr, GateOperand, GateOperandKind, Index, IndexExpr,
45-
IndexedIdent, LiteralKind, MeasureExpr, Set, TimeUnit, UnaryOpExpr,
42+
Array, BinaryOpExpr, Cast, Expr, GateOperand, GateOperandKind, Index, IndexedExpr,
43+
LiteralKind, MeasureExpr, Set, TimeUnit, UnaryOpExpr,
4644
},
4745
symbols::{IOKind, Symbol, SymbolId, SymbolTable},
4846
types::{promote_types, Type},
@@ -435,7 +433,6 @@ impl QasmCompiler {
435433
match stmt.kind.as_ref() {
436434
semast::StmtKind::Alias(stmt) => self.compile_alias_decl_stmt(stmt),
437435
semast::StmtKind::Assign(stmt) => self.compile_assign_stmt(stmt),
438-
semast::StmtKind::IndexedAssign(stmt) => self.compile_indexed_assign_stmt(stmt),
439436
semast::StmtKind::Barrier(stmt) => Self::compile_barrier_stmt(stmt),
440437
semast::StmtKind::Box(stmt) => self.compile_box_stmt(stmt),
441438
semast::StmtKind::Block(stmt) => self.compile_block_stmt(stmt),
@@ -454,7 +451,11 @@ impl QasmCompiler {
454451
semast::StmtKind::For(stmt) => self.compile_for_stmt(stmt),
455452
semast::StmtKind::If(stmt) => self.compile_if_stmt(stmt),
456453
semast::StmtKind::GateCall(stmt) => self.compile_gate_call_stmt(stmt),
454+
semast::StmtKind::ImplicitReturn(expr) => self.compile_implicit_return_stmt(expr),
457455
semast::StmtKind::Include(stmt) => self.compile_include_stmt(stmt),
456+
semast::StmtKind::IndexedClassicalTypeAssign(stmt) => {
457+
self.compile_indexed_classical_type_assign_stmt(stmt)
458+
}
458459
semast::StmtKind::InputDeclaration(stmt) => self.compile_input_decl_stmt(stmt),
459460
semast::StmtKind::OutputDeclaration(stmt) => self.compile_output_decl_stmt(stmt),
460461
semast::StmtKind::MeasureArrow(stmt) => self.compile_measure_stmt(stmt),
@@ -482,107 +483,26 @@ impl QasmCompiler {
482483
}
483484

484485
fn compile_assign_stmt(&mut self, stmt: &semast::AssignStmt) -> Option<qsast::Stmt> {
485-
let symbol = self.symbols[stmt.symbol_id].clone();
486-
let name = &symbol.name;
487-
let stmt_span = stmt.span;
488-
let name_span = stmt.lhs_span;
486+
let lhs = self.compile_expr(&stmt.lhs);
489487
let rhs = self.compile_expr(&stmt.rhs);
490-
let stmt = build_assignment_statement(name_span, name, rhs, stmt_span);
491-
Some(stmt)
488+
Some(build_assignment_statement(lhs, rhs, stmt.span))
492489
}
493490

494-
fn compile_indexed_assign_stmt(
491+
fn compile_indexed_classical_type_assign_stmt(
495492
&mut self,
496-
stmt: &semast::IndexedAssignStmt,
493+
stmt: &semast::IndexedClassicalTypeAssignStmt,
497494
) -> Option<qsast::Stmt> {
498-
let symbol = self.symbols[stmt.indexed_ident.symbol_id].clone();
499-
let name = &symbol.name;
500-
501-
// We collect the indices in the reverse order, so that we can use `Vec::pop`.
502-
let mut indices: Vec<_> = stmt
503-
.indexed_ident
504-
.indices
505-
.iter()
506-
.rev()
507-
.map(|elem| self.compile_index(elem))
508-
.collect();
509-
510-
let rhs = self.compile_expr(&stmt.rhs);
511-
512-
if indices.is_empty() {
513-
return None;
514-
}
515-
516-
let first_index = indices.pop().expect("there is at least one index");
517-
518-
// If we have a single index, we build a `w/=` expr.
519-
let stmt = if indices.is_empty() {
520-
build_indexed_assignment_statement(
521-
stmt.indexed_ident.name_span,
522-
symbol.name.clone(),
523-
first_index,
524-
rhs,
525-
stmt.span,
526-
)
527-
}
528-
// If there is more than one index. We still use a `w/=` for the
529-
// first index, since that is more efficient. But we use `w/`
530-
// expressions for the rest of the indices.
531-
else {
532-
let lhs = build_path_ident_expr(
533-
name,
534-
stmt.indexed_ident.name_span,
535-
stmt.indexed_ident.name_span,
536-
);
537-
let indexed_lhs_span = Span {
538-
lo: lhs.span.lo,
539-
hi: first_index.span.hi,
540-
};
541-
let indexed_lhs = build_index_expr(lhs, first_index.clone(), indexed_lhs_span);
542-
let rhs = Self::compile_ternary_update_expr(indexed_lhs, indices, rhs);
543-
544-
build_indexed_assignment_statement(
545-
stmt.indexed_ident.name_span,
546-
symbol.name.clone(),
547-
first_index,
548-
rhs,
549-
stmt.span,
550-
)
551-
};
552-
553-
Some(stmt)
554-
}
555-
556-
fn compile_ternary_update_expr(
557-
lhs: qsast::Expr,
558-
mut indices: Vec<qsast::Expr>,
559-
rhs: qsast::Expr,
560-
) -> qsast::Expr {
561-
// Base case: no indices. We shouldn't reach this case.
562-
let ternary_expr = if indices.is_empty() {
563-
err_expr(lhs.span)
564-
}
565-
// Base case: single index.
566-
else if indices.len() == 1 {
567-
let index = indices.pop().expect("there is exactly one index");
568-
build_ternary_update_expr(lhs, index, rhs)
569-
}
570-
// Recursive case.
571-
else {
572-
let index = indices.pop().expect("there is exactly one index");
573-
let rhs = {
574-
let span = Span {
575-
lo: lhs.span.lo,
576-
hi: index.span.hi,
577-
};
578-
let lhs = build_index_expr(lhs.clone(), index.clone(), span);
579-
Self::compile_ternary_update_expr(lhs, indices, rhs)
580-
};
581-
build_ternary_update_expr(lhs, index, rhs)
495+
let lhs = self.compile_expr(&stmt.lhs);
496+
497+
let rhs = qsast::Expr {
498+
id: Default::default(),
499+
span: stmt.rhs.span,
500+
kind: Box::new(qsast::ExprKind::Block(Box::new(
501+
self.compile_block(&stmt.rhs),
502+
))),
582503
};
583504

584-
let paren_span = ternary_expr.span;
585-
wrap_expr_in_parens(ternary_expr, paren_span)
505+
Some(build_assignment_statement(lhs, rhs, stmt.span))
586506
}
587507

588508
fn compile_barrier_stmt(stmt: &semast::BarrierStmt) -> Option<qsast::Stmt> {
@@ -1066,6 +986,11 @@ impl QasmCompiler {
1066986
Some(build_stmt_semi_from_expr(expr))
1067987
}
1068988

989+
fn compile_implicit_return_stmt(&mut self, expr: &semast::Expr) -> Option<qsast::Stmt> {
990+
let expr = self.compile_expr(expr);
991+
Some(build_implicit_return_stmt(expr))
992+
}
993+
1069994
fn compile_return_stmt(&mut self, stmt: &semast::ReturnStmt) -> Option<qsast::Stmt> {
1070995
let expr = stmt.expr.as_ref().map(|expr| self.compile_expr(expr));
1071996

@@ -1171,9 +1096,6 @@ impl QasmCompiler {
11711096
..Default::default()
11721097
},
11731098
semast::ExprKind::Ident(symbol_id) => self.compile_ident_expr(*symbol_id, expr.span),
1174-
semast::ExprKind::IndexedIdent(indexed_ident) => {
1175-
self.compile_indexed_ident_expr(indexed_ident)
1176-
}
11771099
semast::ExprKind::UnaryOp(unary_op_expr) => self.compile_unary_op_expr(unary_op_expr),
11781100
semast::ExprKind::BinaryOp(binary_op_expr) => {
11791101
self.compile_binary_op_expr(binary_op_expr)
@@ -1192,7 +1114,9 @@ impl QasmCompiler {
11921114
self.compile_literal_expr(&value, expr.span)
11931115
}
11941116
semast::ExprKind::Cast(cast) => self.compile_cast_expr(cast),
1195-
semast::ExprKind::IndexExpr(index_expr) => self.compile_index_expr(index_expr),
1117+
semast::ExprKind::IndexedExpr(index_expr) => {
1118+
self.compile_indexed_array_expr(index_expr)
1119+
}
11961120
semast::ExprKind::Paren(pexpr) => self.compile_paren_expr(pexpr, expr.span),
11971121
semast::ExprKind::Measure(mexpr) => self.compile_measure_expr(mexpr, &expr.ty),
11981122
}
@@ -1219,31 +1143,6 @@ impl QasmCompiler {
12191143
}
12201144
}
12211145

1222-
/// The lowerer eliminated indexed identifiers with zero indices.
1223-
/// So we are safe to assume that the indices are non-empty.
1224-
fn compile_indexed_ident_expr(&mut self, indexed_ident: &IndexedIdent) -> qsast::Expr {
1225-
let span = indexed_ident.span;
1226-
let index: Vec<_> = indexed_ident
1227-
.indices
1228-
.iter()
1229-
.map(|elem| self.compile_index(elem))
1230-
.collect();
1231-
1232-
if index.len() != 1 {
1233-
self.push_unimplemented_error_message(
1234-
"multi-dimensional array index expressions",
1235-
span,
1236-
);
1237-
return err_expr(indexed_ident.span);
1238-
}
1239-
1240-
let symbol = &self.symbols[indexed_ident.symbol_id];
1241-
1242-
let ident =
1243-
build_path_ident_expr(&symbol.name, indexed_ident.name_span, indexed_ident.span);
1244-
build_index_expr(ident, index[0].clone(), span)
1245-
}
1246-
12471146
fn compile_unary_op_expr(&mut self, unary: &UnaryOpExpr) -> qsast::Expr {
12481147
match unary.op {
12491148
semast::UnaryOp::Neg => self.compile_neg_expr(&unary.expr, unary.span),
@@ -1451,23 +1350,14 @@ impl QasmCompiler {
14511350
cast_expr
14521351
}
14531352

1454-
fn compile_index_expr(&mut self, index_expr: &IndexExpr) -> qsast::Expr {
1455-
let mut expr = self.compile_expr(&index_expr.collection);
1456-
1457-
for index in &index_expr.indices {
1458-
let index = self.compile_index(index);
1459-
let span = Span {
1460-
lo: index_expr.span.lo,
1461-
hi: index.span.hi,
1462-
};
1463-
expr = qsast::Expr {
1464-
id: qsast::NodeId::default(),
1465-
span,
1466-
kind: Box::new(qsast::ExprKind::Index(Box::new(expr), Box::new(index))),
1467-
}
1468-
}
1469-
1470-
expr
1353+
fn compile_indexed_array_expr(&mut self, index_expr: &IndexedExpr) -> qsast::Expr {
1354+
let expr = self.compile_expr(&index_expr.collection);
1355+
let index = self.compile_index(&index_expr.index);
1356+
let span = Span {
1357+
lo: expr.span.lo,
1358+
hi: index.span.hi,
1359+
};
1360+
build_index_expr(expr, index, span)
14711361
}
14721362

14731363
fn compile_paren_expr(&mut self, paren: &Expr, span: Span) -> qsast::Expr {

0 commit comments

Comments
 (0)