Skip to content

Commit 1ad7321

Browse files
authored
Compile gphase, gatedef, and control flow statements (#2254)
This PR completes the lowering and compilation for: - [x] gate definitions - [x] gphase - [x] for stmt - [x] if stmt - [x] switch stmt - [x] return stmt - [x] classical function calls - [x] classical function decls It also does some partial work to make the compiler infallible, by returning `ExprKind::Err` instead of None when compiling expressions.
1 parent 14909fe commit 1ad7321

File tree

17 files changed

+1309
-403
lines changed

17 files changed

+1309
-403
lines changed

compiler/qsc_qasm3/src/ast_builder.rs

+60-18
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,7 @@ pub(crate) fn build_call_with_param(
810810
operand: Expr,
811811
name_span: Span,
812812
operand_span: Span,
813-
stmt_span: Span,
813+
call_span: Span,
814814
) -> Expr {
815815
let segments = build_idents(idents);
816816
let fn_name = Ident {
@@ -838,7 +838,38 @@ pub(crate) fn build_call_with_param(
838838

839839
Expr {
840840
id: NodeId::default(),
841-
span: stmt_span,
841+
span: call_span,
842+
kind: Box::new(call),
843+
}
844+
}
845+
846+
pub(crate) fn build_call_with_params(
847+
name: &str,
848+
idents: &[&str],
849+
operands: Vec<Expr>,
850+
name_span: Span,
851+
call_span: Span,
852+
) -> Expr {
853+
let segments = build_idents(idents);
854+
let fn_name = Ident {
855+
name: Rc::from(name),
856+
span: name_span,
857+
..Default::default()
858+
};
859+
let path_expr = Expr {
860+
kind: Box::new(ExprKind::Path(PathKind::Ok(Box::new(Path {
861+
segments,
862+
name: Box::new(fn_name),
863+
id: NodeId::default(),
864+
span: Span::default(),
865+
})))),
866+
..Default::default()
867+
};
868+
let call = ExprKind::Call(Box::new(path_expr), Box::new(build_tuple_expr(operands)));
869+
870+
Expr {
871+
id: NodeId::default(),
872+
span: call_span,
842873
kind: Box::new(call),
843874
}
844875
}
@@ -1186,8 +1217,10 @@ fn wrap_ty_in_array(ty: Ty) -> Ty {
11861217
}
11871218

11881219
pub(crate) fn build_for_stmt(
1189-
loop_var: &crate::symbols::Symbol,
1190-
iter: crate::types::QasmTypedExpr,
1220+
loop_var_name: &str,
1221+
loop_var_span: Span,
1222+
loop_var_qsharp_ty: &crate::types::Type,
1223+
iter: Expr,
11911224
body: Block,
11921225
stmt_span: Span,
11931226
) -> Stmt {
@@ -1197,15 +1230,15 @@ pub(crate) fn build_for_stmt(
11971230
Box::new(Pat {
11981231
kind: Box::new(PatKind::Bind(
11991232
Box::new(Ident {
1200-
name: loop_var.name.clone().into(),
1201-
span: loop_var.span,
1233+
name: loop_var_name.into(),
1234+
span: loop_var_span,
12021235
..Default::default()
12031236
}),
1204-
Some(Box::new(map_qsharp_type_to_ast_ty(&loop_var.qsharp_ty))),
1237+
Some(Box::new(map_qsharp_type_to_ast_ty(loop_var_qsharp_ty))),
12051238
)),
12061239
..Default::default()
12071240
}),
1208-
Box::new(iter.expr),
1241+
Box::new(iter),
12091242
Box::new(body),
12101243
)),
12111244
span: stmt_span,
@@ -1371,14 +1404,17 @@ pub(crate) fn build_gate_decl(
13711404
}
13721405
}
13731406

1374-
pub(crate) fn build_gate_decl_lambda<S: AsRef<str>>(
1407+
#[allow(clippy::too_many_arguments, clippy::too_many_lines)]
1408+
pub(crate) fn build_lambda<S: AsRef<str>>(
13751409
name: S,
13761410
cargs: Vec<(String, Ty, Pat)>,
13771411
qargs: Vec<(String, Ty, Pat)>,
13781412
body: Option<Block>,
13791413
name_span: Span,
13801414
body_span: Span,
13811415
gate_span: Span,
1416+
return_type: Option<Ty>,
1417+
kind: CallableKind,
13821418
) -> Stmt {
13831419
let args = cargs
13841420
.into_iter()
@@ -1413,15 +1449,15 @@ pub(crate) fn build_gate_decl_lambda<S: AsRef<str>>(
14131449
})
14141450
.map(Box::new)
14151451
.collect::<Vec<_>>();
1416-
let input_pat = if args.len() > 1 {
1452+
let input_pat = if args.len() == 1 {
14171453
ast::Pat {
1418-
kind: Box::new(PatKind::Tuple(name_args.into_boxed_slice())),
1454+
kind: Box::new(ast::PatKind::Paren(name_args[0].clone())),
14191455
span: Span { lo, hi },
14201456
..Default::default()
14211457
}
14221458
} else {
14231459
ast::Pat {
1424-
kind: Box::new(ast::PatKind::Paren(name_args[0].clone())),
1460+
kind: Box::new(PatKind::Tuple(name_args.into_boxed_slice())),
14251461
span: Span { lo, hi },
14261462
..Default::default()
14271463
}
@@ -1438,29 +1474,35 @@ pub(crate) fn build_gate_decl_lambda<S: AsRef<str>>(
14381474
let lambda_expr = Expr {
14391475
id: NodeId::default(),
14401476
kind: Box::new(ExprKind::Lambda(
1441-
CallableKind::Operation,
1477+
kind,
14421478
Box::new(input_pat),
14431479
Box::new(block_expr),
14441480
)),
14451481
span: gate_span,
14461482
};
14471483
let ty_args = args.iter().map(|(_, ty, _)| ty.clone()).collect::<Vec<_>>();
1448-
let input_ty = if args.len() > 1 {
1484+
let input_ty = if args.len() == 1 {
14491485
ast::Ty {
1450-
kind: Box::new(ast::TyKind::Tuple(ty_args.into_boxed_slice())),
1486+
kind: Box::new(ast::TyKind::Paren(Box::new(ty_args[0].clone()))),
14511487
..Default::default()
14521488
}
14531489
} else {
14541490
ast::Ty {
1455-
kind: Box::new(ast::TyKind::Paren(Box::new(ty_args[0].clone()))),
1491+
kind: Box::new(ast::TyKind::Tuple(ty_args.into_boxed_slice())),
14561492
..Default::default()
14571493
}
14581494
};
1495+
let return_type = if let Some(ty) = return_type {
1496+
ty
1497+
} else {
1498+
build_path_ident_ty("Unit")
1499+
};
1500+
14591501
let lambda_ty = ast::Ty {
14601502
kind: Box::new(ast::TyKind::Arrow(
1461-
CallableKind::Operation,
1503+
kind,
14621504
Box::new(input_ty),
1463-
Box::new(build_path_ident_ty("Unit")),
1505+
Box::new(return_type),
14641506
None,
14651507
)),
14661508
..Default::default()

compiler/qsc_qasm3/src/compile.rs

+18-15
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ use crate::ast_builder::{
99
build_barrier_call, build_binary_expr, build_cast_call, build_cast_call_two_params,
1010
build_classical_decl, build_complex_binary_expr, build_complex_from_expr,
1111
build_convert_call_expr, build_default_result_array_expr, build_expr_array_expr,
12-
build_gate_call_param_expr, build_gate_decl_lambda, build_if_expr_then_block,
13-
build_if_expr_then_block_else_block, build_if_expr_then_block_else_expr,
14-
build_if_expr_then_expr_else_expr, build_implicit_return_stmt,
15-
build_indexed_assignment_statement, build_lit_bigint_expr, build_lit_bool_expr,
16-
build_lit_complex_expr, build_lit_double_expr, build_lit_int_expr,
17-
build_lit_result_array_expr_from_bitstring, build_lit_result_expr, build_managed_qubit_alloc,
18-
build_math_call_no_params, build_measure_call, build_operation_with_stmts,
19-
build_path_ident_expr, build_range_expr, build_reset_call, build_stmt_semi_from_expr,
20-
build_stmt_wrapped_block_expr, build_top_level_ns_with_item, build_tuple_expr,
21-
build_unary_op_expr, build_unmanaged_qubit_alloc, build_unmanaged_qubit_alloc_array,
22-
build_wrapped_block_expr, is_complex_binop_supported, managed_qubit_alloc_array,
23-
map_qsharp_type_to_ast_ty,
12+
build_gate_call_param_expr, build_if_expr_then_block, build_if_expr_then_block_else_block,
13+
build_if_expr_then_block_else_expr, build_if_expr_then_expr_else_expr,
14+
build_implicit_return_stmt, build_indexed_assignment_statement, build_lambda,
15+
build_lit_bigint_expr, build_lit_bool_expr, build_lit_complex_expr, build_lit_double_expr,
16+
build_lit_int_expr, build_lit_result_array_expr_from_bitstring, build_lit_result_expr,
17+
build_managed_qubit_alloc, build_math_call_no_params, build_measure_call,
18+
build_operation_with_stmts, build_path_ident_expr, build_range_expr, build_reset_call,
19+
build_stmt_semi_from_expr, build_stmt_wrapped_block_expr, build_top_level_ns_with_item,
20+
build_tuple_expr, build_unary_op_expr, build_unmanaged_qubit_alloc,
21+
build_unmanaged_qubit_alloc_array, build_wrapped_block_expr, is_complex_binop_supported,
22+
managed_qubit_alloc_array, map_qsharp_type_to_ast_ty,
2423
};
2524

2625
use crate::oqasm_helpers::{
@@ -2318,8 +2317,10 @@ impl QasmCompiler {
23182317
};
23192318

23202319
Some(ast_builder::build_for_stmt(
2321-
&loop_var_symbol,
2322-
iterable,
2320+
&loop_var_symbol.name,
2321+
loop_var_symbol.span,
2322+
&loop_var_symbol.qsharp_ty,
2323+
iterable.expr,
23232324
body,
23242325
stmt_span,
23252326
))
@@ -2472,14 +2473,16 @@ impl QasmCompiler {
24722473
gate_span,
24732474
))
24742475
} else {
2475-
Some(build_gate_decl_lambda(
2476+
Some(build_lambda(
24762477
name.to_string(),
24772478
cargs,
24782479
qargs,
24792480
body,
24802481
name_span,
24812482
body_span,
24822483
gate_span,
2484+
None,
2485+
ast::CallableKind::Operation,
24832486
))
24842487
}
24852488
}

0 commit comments

Comments
 (0)