microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
dmitryv/select-updated

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_fir/src/mut_visit.rs

198lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::fir::{
5 Block, BlockId, CallableDecl, Expr, ExprId, ExprKind, Ident, Item, ItemKind, Package, Pat,
6 PatId, PatKind, QubitInit, QubitInitKind, SpecBody, SpecDecl, Stmt, StmtId, StmtKind,
7 StringComponent,
8};
9
10pub trait MutVisitor<'a>: Sized {
11 fn visit_package(&mut self, package: &'a mut Package) {
12 walk_package(self, package);
13 }
14
15 fn visit_item(&mut self, item: &'a mut Item) {
16 walk_item(self, item);
17 }
18
19 fn visit_callable_decl(&mut self, decl: &'a mut CallableDecl) {
20 walk_callable_decl(self, decl);
21 }
22
23 fn visit_spec_decl(&mut self, decl: &'a mut SpecDecl) {
24 walk_spec_decl(self, decl);
25 }
26
27 fn visit_block(&mut self, block: BlockId) {
28 walk_block(self, block);
29 }
30
31 fn visit_stmt(&mut self, stmt: StmtId) {
32 walk_stmt(self, stmt);
33 }
34
35 fn visit_expr(&mut self, expr: ExprId) {
36 walk_expr(self, expr);
37 }
38
39 fn visit_pat(&mut self, pat: PatId) {
40 walk_pat(self, pat);
41 }
42
43 fn visit_qubit_init(&mut self, init: &'a mut QubitInit) {
44 walk_qubit_init(self, init);
45 }
46
47 fn visit_ident(&mut self, _: &'a mut Ident) {}
48
49 fn get_block(&mut self, id: BlockId) -> &'a mut Block;
50 fn get_expr(&mut self, id: ExprId) -> &'a mut Expr;
51 fn get_pat(&mut self, id: PatId) -> &'a mut Pat;
52 fn get_stmt(&mut self, id: StmtId) -> &'a mut Stmt;
53}
54
55pub fn walk_package<'a>(vis: &mut impl MutVisitor<'a>, package: &'a mut Package) {
56 package.items.values_mut().for_each(|i| vis.visit_item(i));
57 package.entry.iter_mut().for_each(|e| vis.visit_expr(*e));
58}
59
60pub fn walk_item<'a>(vis: &mut impl MutVisitor<'a>, item: &'a mut Item) {
61 match &mut item.kind {
62 ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
63 ItemKind::Namespace(name, _) | ItemKind::Ty(name, _) => vis.visit_ident(name),
64 }
65}
66
67pub fn walk_callable_decl<'a>(vis: &mut impl MutVisitor<'a>, decl: &'a mut CallableDecl) {
68 vis.visit_ident(&mut decl.name);
69 vis.visit_pat(decl.input);
70 vis.visit_spec_decl(&mut decl.body);
71 decl.adj
72 .iter_mut()
73 .for_each(|spec| vis.visit_spec_decl(spec));
74 decl.ctl
75 .iter_mut()
76 .for_each(|spec| vis.visit_spec_decl(spec));
77 decl.ctl_adj
78 .iter_mut()
79 .for_each(|spec| vis.visit_spec_decl(spec));
80}
81
82pub fn walk_spec_decl<'a>(vis: &mut impl MutVisitor<'a>, decl: &'a mut SpecDecl) {
83 match &mut decl.body {
84 SpecBody::Gen(_) => {}
85 SpecBody::Impl(pat, block) => {
86 pat.iter().for_each(|pat| vis.visit_pat(*pat));
87 vis.visit_block(*block);
88 }
89 }
90}
91
92pub fn walk_block<'a>(vis: &mut impl MutVisitor<'a>, block: BlockId) {
93 let block = vis.get_block(block);
94 block.stmts.iter().for_each(|s| vis.visit_stmt(*s));
95}
96
97pub fn walk_stmt<'a>(vis: &mut impl MutVisitor<'a>, id: StmtId) {
98 let stmt = vis.get_stmt(id);
99 match &mut stmt.kind {
100 StmtKind::Item(_) => {}
101 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(*expr),
102 StmtKind::Local(_, pat, value) => {
103 vis.visit_pat(*pat);
104 vis.visit_expr(*value);
105 }
106 StmtKind::Qubit(_, pat, init, block) => {
107 vis.visit_pat(*pat);
108 vis.visit_qubit_init(init);
109 block.iter().for_each(|b| vis.visit_block(*b));
110 }
111 }
112}
113
114pub fn walk_expr<'a>(vis: &mut impl MutVisitor<'a>, expr: ExprId) {
115 let expr = vis.get_expr(expr);
116 match &expr.kind {
117 ExprKind::Array(exprs) => exprs.iter().for_each(|e| vis.visit_expr(*e)),
118 ExprKind::ArrayRepeat(item, size) => {
119 vis.visit_expr(*item);
120 vis.visit_expr(*size);
121 }
122 ExprKind::Assign(lhs, rhs)
123 | ExprKind::AssignOp(_, lhs, rhs)
124 | ExprKind::BinOp(_, lhs, rhs) => {
125 vis.visit_expr(*lhs);
126 vis.visit_expr(*rhs);
127 }
128 ExprKind::AssignField(record, _, replace) | ExprKind::UpdateField(record, _, replace) => {
129 vis.visit_expr(*record);
130 vis.visit_expr(*replace);
131 }
132 ExprKind::AssignIndex(array, index, replace) => {
133 vis.visit_expr(*array);
134 vis.visit_expr(*index);
135 vis.visit_expr(*replace);
136 }
137 ExprKind::Block(block) => vis.visit_block(*block),
138 ExprKind::Call(callee, arg) => {
139 vis.visit_expr(*callee);
140 vis.visit_expr(*arg);
141 }
142 ExprKind::Fail(msg) => vis.visit_expr(*msg),
143 ExprKind::Field(record, _) => vis.visit_expr(*record),
144 ExprKind::If(cond, body, otherwise) => {
145 vis.visit_expr(*cond);
146 vis.visit_expr(*body);
147 otherwise.iter().for_each(|e| vis.visit_expr(*e));
148 }
149 ExprKind::Index(array, index) => {
150 vis.visit_expr(*array);
151 vis.visit_expr(*index);
152 }
153 ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
154 vis.visit_expr(*expr);
155 }
156 ExprKind::Range(start, step, end) => {
157 start.iter().for_each(|s| vis.visit_expr(*s));
158 step.iter().for_each(|s| vis.visit_expr(*s));
159 end.iter().for_each(|e| vis.visit_expr(*e));
160 }
161 ExprKind::String(components) => {
162 for component in components {
163 match component {
164 StringComponent::Expr(expr) => vis.visit_expr(*expr),
165 StringComponent::Lit(_) => {}
166 }
167 }
168 }
169 ExprKind::UpdateIndex(e1, e2, e3) => {
170 vis.visit_expr(*e1);
171 vis.visit_expr(*e2);
172 vis.visit_expr(*e3);
173 }
174 ExprKind::Tuple(exprs) => exprs.iter().for_each(|e| vis.visit_expr(*e)),
175 ExprKind::While(cond, block) => {
176 vis.visit_expr(*cond);
177 vis.visit_block(*block);
178 }
179 ExprKind::Closure(_, _) | ExprKind::Hole | ExprKind::Lit(_) | ExprKind::Var(_, _) => {}
180 }
181}
182
183pub fn walk_pat<'a>(vis: &mut impl MutVisitor<'a>, pat: PatId) {
184 let pat = vis.get_pat(pat);
185 match &mut pat.kind {
186 PatKind::Bind(name) => vis.visit_ident(name),
187 PatKind::Discard => {}
188 PatKind::Tuple(pats) => pats.iter().for_each(|p| vis.visit_pat(*p)),
189 }
190}
191
192pub fn walk_qubit_init<'a>(vis: &mut impl MutVisitor<'a>, init: &'a mut QubitInit) {
193 match &mut init.kind {
194 QubitInitKind::Array(len) => vis.visit_expr(*len),
195 QubitInitKind::Single => {}
196 QubitInitKind::Tuple(inits) => inits.iter_mut().for_each(|i| vis.visit_qubit_init(i)),
197 }
198}
199