@@ -22,27 +22,25 @@ use crate::{
22
22
build_gate_call_param_expr, build_gate_call_with_params_and_callee,
23
23
build_if_expr_then_block, build_if_expr_then_block_else_block,
24
24
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,
32
31
build_qasmstd_convert_call_with_two_params, build_range_expr, build_reset_all_call,
33
32
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,
39
37
} ,
40
38
io:: SourceResolver ,
41
39
parser:: ast:: { list_from_iter, List } ,
42
40
semantic:: {
43
41
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 ,
46
44
} ,
47
45
symbols:: { IOKind , Symbol , SymbolId , SymbolTable } ,
48
46
types:: { promote_types, Type } ,
@@ -435,7 +433,6 @@ impl QasmCompiler {
435
433
match stmt. kind . as_ref ( ) {
436
434
semast:: StmtKind :: Alias ( stmt) => self . compile_alias_decl_stmt ( stmt) ,
437
435
semast:: StmtKind :: Assign ( stmt) => self . compile_assign_stmt ( stmt) ,
438
- semast:: StmtKind :: IndexedAssign ( stmt) => self . compile_indexed_assign_stmt ( stmt) ,
439
436
semast:: StmtKind :: Barrier ( stmt) => Self :: compile_barrier_stmt ( stmt) ,
440
437
semast:: StmtKind :: Box ( stmt) => self . compile_box_stmt ( stmt) ,
441
438
semast:: StmtKind :: Block ( stmt) => self . compile_block_stmt ( stmt) ,
@@ -454,7 +451,11 @@ impl QasmCompiler {
454
451
semast:: StmtKind :: For ( stmt) => self . compile_for_stmt ( stmt) ,
455
452
semast:: StmtKind :: If ( stmt) => self . compile_if_stmt ( stmt) ,
456
453
semast:: StmtKind :: GateCall ( stmt) => self . compile_gate_call_stmt ( stmt) ,
454
+ semast:: StmtKind :: ImplicitReturn ( expr) => self . compile_implicit_return_stmt ( expr) ,
457
455
semast:: StmtKind :: Include ( stmt) => self . compile_include_stmt ( stmt) ,
456
+ semast:: StmtKind :: IndexedClassicalTypeAssign ( stmt) => {
457
+ self . compile_indexed_classical_type_assign_stmt ( stmt)
458
+ }
458
459
semast:: StmtKind :: InputDeclaration ( stmt) => self . compile_input_decl_stmt ( stmt) ,
459
460
semast:: StmtKind :: OutputDeclaration ( stmt) => self . compile_output_decl_stmt ( stmt) ,
460
461
semast:: StmtKind :: MeasureArrow ( stmt) => self . compile_measure_stmt ( stmt) ,
@@ -482,107 +483,26 @@ impl QasmCompiler {
482
483
}
483
484
484
485
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 ) ;
489
487
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 ) )
492
489
}
493
490
494
- fn compile_indexed_assign_stmt (
491
+ fn compile_indexed_classical_type_assign_stmt (
495
492
& mut self ,
496
- stmt : & semast:: IndexedAssignStmt ,
493
+ stmt : & semast:: IndexedClassicalTypeAssignStmt ,
497
494
) -> 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
+ ) ) ) ,
582
503
} ;
583
504
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 ) )
586
506
}
587
507
588
508
fn compile_barrier_stmt ( stmt : & semast:: BarrierStmt ) -> Option < qsast:: Stmt > {
@@ -1066,6 +986,11 @@ impl QasmCompiler {
1066
986
Some ( build_stmt_semi_from_expr ( expr) )
1067
987
}
1068
988
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
+
1069
994
fn compile_return_stmt ( & mut self , stmt : & semast:: ReturnStmt ) -> Option < qsast:: Stmt > {
1070
995
let expr = stmt. expr . as_ref ( ) . map ( |expr| self . compile_expr ( expr) ) ;
1071
996
@@ -1171,9 +1096,6 @@ impl QasmCompiler {
1171
1096
..Default :: default ( )
1172
1097
} ,
1173
1098
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
- }
1177
1099
semast:: ExprKind :: UnaryOp ( unary_op_expr) => self . compile_unary_op_expr ( unary_op_expr) ,
1178
1100
semast:: ExprKind :: BinaryOp ( binary_op_expr) => {
1179
1101
self . compile_binary_op_expr ( binary_op_expr)
@@ -1192,7 +1114,9 @@ impl QasmCompiler {
1192
1114
self . compile_literal_expr ( & value, expr. span )
1193
1115
}
1194
1116
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
+ }
1196
1120
semast:: ExprKind :: Paren ( pexpr) => self . compile_paren_expr ( pexpr, expr. span ) ,
1197
1121
semast:: ExprKind :: Measure ( mexpr) => self . compile_measure_expr ( mexpr, & expr. ty ) ,
1198
1122
}
@@ -1219,31 +1143,6 @@ impl QasmCompiler {
1219
1143
}
1220
1144
}
1221
1145
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
-
1247
1146
fn compile_unary_op_expr ( & mut self , unary : & UnaryOpExpr ) -> qsast:: Expr {
1248
1147
match unary. op {
1249
1148
semast:: UnaryOp :: Neg => self . compile_neg_expr ( & unary. expr , unary. span ) ,
@@ -1451,23 +1350,14 @@ impl QasmCompiler {
1451
1350
cast_expr
1452
1351
}
1453
1352
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)
1471
1361
}
1472
1362
1473
1363
fn compile_paren_expr ( & mut self , paren : & Expr , span : Span ) -> qsast:: Expr {
0 commit comments