@@ -11,17 +11,17 @@ use qsc_frontend::{compile::SourceMap, error::WithSource};
11
11
use crate :: {
12
12
ast_builder:: {
13
13
build_adj_plus_ctl_functor, build_arg_pat, build_array_reverse_expr,
14
- build_assignment_statement, build_barrier_call , build_binary_expr , build_call_no_params ,
15
- build_call_with_param , build_call_with_params , build_cast_call_by_name ,
16
- build_classical_decl , build_complex_from_expr , build_convert_call_expr ,
17
- build_expr_array_expr , build_for_stmt , build_function_or_operation ,
18
- build_gate_call_param_expr , build_gate_call_with_params_and_callee ,
19
- build_global_call_with_two_params , build_if_expr_then_block ,
20
- build_if_expr_then_block_else_block , build_if_expr_then_block_else_expr ,
21
- build_if_expr_then_expr_else_expr , build_implicit_return_stmt ,
22
- build_indexed_assignment_statement , build_lit_angle_expr , build_lit_bigint_expr ,
23
- build_lit_bool_expr, build_lit_complex_expr, build_lit_double_expr, build_lit_int_expr ,
24
- build_lit_result_array_expr_from_bitstring, build_lit_result_expr,
14
+ build_assignment_statement, build_attr , build_barrier_call , build_binary_expr ,
15
+ build_call_no_params , build_call_with_param , build_call_with_params ,
16
+ build_cast_call_by_name , build_classical_decl , build_complex_from_expr ,
17
+ build_convert_call_expr , build_end_stmt , build_expr_array_expr , build_for_stmt ,
18
+ build_function_or_operation , build_gate_call_param_expr ,
19
+ build_gate_call_with_params_and_callee , build_global_call_with_two_params ,
20
+ build_if_expr_then_block , build_if_expr_then_block_else_block ,
21
+ build_if_expr_then_block_else_expr , build_if_expr_then_expr_else_expr ,
22
+ build_implicit_return_stmt , build_indexed_assignment_statement , build_lit_angle_expr ,
23
+ build_lit_bigint_expr , build_lit_bool_expr, build_lit_complex_expr, build_lit_double_expr,
24
+ build_lit_int_expr , build_lit_result_array_expr_from_bitstring, build_lit_result_expr,
25
25
build_managed_qubit_alloc, build_math_call_from_exprs, build_math_call_no_params,
26
26
build_measure_call, build_operation_with_stmts, build_path_ident_expr,
27
27
build_qasm_import_decl, build_qasm_import_items, build_range_expr, build_reset_call,
@@ -379,6 +379,19 @@ impl QasmCompiler {
379
379
}
380
380
381
381
fn compile_stmt ( & mut self , stmt : & crate :: semantic:: ast:: Stmt ) -> Option < qsast:: Stmt > {
382
+ if !stmt. annotations . is_empty ( )
383
+ && !matches ! (
384
+ stmt. kind. as_ref( ) ,
385
+ semast:: StmtKind :: QuantumGateDefinition ( ..) | semast:: StmtKind :: Def ( ..)
386
+ )
387
+ {
388
+ for annotation in & stmt. annotations {
389
+ self . push_semantic_error ( SemanticErrorKind :: InvalidAnnotationTarget (
390
+ annotation. span ,
391
+ ) ) ;
392
+ }
393
+ }
394
+
382
395
match stmt. kind . as_ref ( ) {
383
396
semast:: StmtKind :: Alias ( stmt) => self . compile_alias_decl_stmt ( stmt) ,
384
397
semast:: StmtKind :: Assign ( stmt) => self . compile_assign_stmt ( stmt) ,
@@ -391,10 +404,10 @@ impl QasmCompiler {
391
404
self . compile_calibration_grammar_stmt ( stmt)
392
405
}
393
406
semast:: StmtKind :: ClassicalDecl ( stmt) => self . compile_classical_decl ( stmt) ,
394
- semast:: StmtKind :: Def ( stmt ) => self . compile_def_stmt ( stmt) ,
407
+ semast:: StmtKind :: Def ( def_stmt ) => self . compile_def_stmt ( def_stmt , & stmt. annotations ) ,
395
408
semast:: StmtKind :: DefCal ( stmt) => self . compile_def_cal_stmt ( stmt) ,
396
409
semast:: StmtKind :: Delay ( stmt) => self . compile_delay_stmt ( stmt) ,
397
- semast:: StmtKind :: End ( stmt) => self . compile_end_stmt ( stmt) ,
410
+ semast:: StmtKind :: End ( stmt) => Self :: compile_end_stmt ( stmt) ,
398
411
semast:: StmtKind :: ExprStmt ( stmt) => self . compile_expr_stmt ( stmt) ,
399
412
semast:: StmtKind :: ExternDecl ( stmt) => self . compile_extern_stmt ( stmt) ,
400
413
semast:: StmtKind :: For ( stmt) => self . compile_for_stmt ( stmt) ,
@@ -405,7 +418,9 @@ impl QasmCompiler {
405
418
semast:: StmtKind :: OutputDeclaration ( stmt) => self . compile_output_decl_stmt ( stmt) ,
406
419
semast:: StmtKind :: MeasureArrow ( stmt) => self . compile_measure_stmt ( stmt) ,
407
420
semast:: StmtKind :: Pragma ( stmt) => self . compile_pragma_stmt ( stmt) ,
408
- semast:: StmtKind :: QuantumGateDefinition ( stmt) => self . compile_gate_decl_stmt ( stmt) ,
421
+ semast:: StmtKind :: QuantumGateDefinition ( gate_stmt) => {
422
+ self . compile_gate_decl_stmt ( gate_stmt, & stmt. annotations )
423
+ }
409
424
semast:: StmtKind :: QubitDecl ( stmt) => self . compile_qubit_decl_stmt ( stmt) ,
410
425
semast:: StmtKind :: QubitArrayDecl ( stmt) => self . compile_qubit_array_decl_stmt ( stmt) ,
411
426
semast:: StmtKind :: Reset ( stmt) => self . compile_reset_stmt ( stmt) ,
@@ -600,7 +615,11 @@ impl QasmCompiler {
600
615
Some ( stmt)
601
616
}
602
617
603
- fn compile_def_stmt ( & mut self , stmt : & semast:: DefStmt ) -> Option < qsast:: Stmt > {
618
+ fn compile_def_stmt (
619
+ & mut self ,
620
+ stmt : & semast:: DefStmt ,
621
+ annotations : & List < semast:: Annotation > ,
622
+ ) -> Option < qsast:: Stmt > {
604
623
let symbol = self . symbols [ stmt. symbol_id ] . clone ( ) ;
605
624
let name = symbol. name . clone ( ) ;
606
625
@@ -627,6 +646,10 @@ impl QasmCompiler {
627
646
qsast:: CallableKind :: Function
628
647
} ;
629
648
649
+ let attrs = annotations
650
+ . iter ( )
651
+ . filter_map ( |annotation| self . compile_annotation ( annotation) ) ;
652
+
630
653
// We use the same primitives used for declaring gates, because def declarations
631
654
// in QASM3 can take qubits as arguments and call quantum gates.
632
655
Some ( build_function_or_operation (
@@ -640,6 +663,7 @@ impl QasmCompiler {
640
663
return_type,
641
664
kind,
642
665
None ,
666
+ list_from_iter ( attrs) ,
643
667
) )
644
668
}
645
669
@@ -653,9 +677,8 @@ impl QasmCompiler {
653
677
None
654
678
}
655
679
656
- fn compile_end_stmt ( & mut self , stmt : & semast:: EndStmt ) -> Option < qsast:: Stmt > {
657
- self . push_unimplemented_error_message ( "end statements" , stmt. span ) ;
658
- None
680
+ fn compile_end_stmt ( stmt : & semast:: EndStmt ) -> Option < qsast:: Stmt > {
681
+ Some ( build_end_stmt ( stmt. span ) )
659
682
}
660
683
661
684
fn compile_expr_stmt ( & mut self , stmt : & semast:: ExprStmt ) -> Option < qsast:: Stmt > {
@@ -866,6 +889,7 @@ impl QasmCompiler {
866
889
fn compile_gate_decl_stmt (
867
890
& mut self ,
868
891
stmt : & semast:: QuantumGateDefinition ,
892
+ annotations : & List < semast:: Annotation > ,
869
893
) -> Option < qsast:: Stmt > {
870
894
let symbol = self . symbols [ stmt. symbol_id ] . clone ( ) ;
871
895
let name = symbol. name . clone ( ) ;
@@ -902,6 +926,10 @@ impl QasmCompiler {
902
926
903
927
let body = Some ( self . compile_block ( & stmt. body ) ) ;
904
928
929
+ let attrs = annotations
930
+ . iter ( )
931
+ . filter_map ( |annotation| self . compile_annotation ( annotation) ) ;
932
+
905
933
Some ( build_function_or_operation (
906
934
name,
907
935
cargs,
@@ -913,9 +941,27 @@ impl QasmCompiler {
913
941
None ,
914
942
qsast:: CallableKind :: Operation ,
915
943
Some ( build_adj_plus_ctl_functor ( ) ) ,
944
+ list_from_iter ( attrs) ,
916
945
) )
917
946
}
918
947
948
+ fn compile_annotation ( & mut self , annotation : & semast:: Annotation ) -> Option < qsast:: Attr > {
949
+ match annotation. identifier . as_ref ( ) {
950
+ "SimulatableIntrinsic" | "Config" => Some ( build_attr (
951
+ & annotation. identifier ,
952
+ annotation. value . as_ref ( ) ,
953
+ annotation. span ,
954
+ ) ) ,
955
+ _ => {
956
+ self . push_semantic_error ( SemanticErrorKind :: UnknownAnnotation (
957
+ format ! ( "@{}" , annotation. identifier) ,
958
+ annotation. span ,
959
+ ) ) ;
960
+ None
961
+ }
962
+ }
963
+ }
964
+
919
965
fn compile_qubit_decl_stmt ( & mut self , stmt : & semast:: QubitDeclaration ) -> Option < qsast:: Stmt > {
920
966
let symbol = self . symbols [ stmt. symbol_id ] . clone ( ) ;
921
967
let name = & symbol. name ;
0 commit comments