microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/pythontelem

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/visit.rs

367lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::ast::{
5 Attr, Block, CallableBody, CallableDecl, Expr, ExprKind, FieldAssign, FieldDef, FunctorExpr,
6 FunctorExprKind, Ident, Item, ItemKind, Namespace, Package, Pat, PatKind, Path, PathKind,
7 QubitInit, QubitInitKind, SpecBody, SpecDecl, Stmt, StmtKind, StringComponent, StructDecl,
8 TopLevelNode, Ty, TyDef, TyDefKind, TyKind,
9};
10
11pub trait Visitor<'a>: Sized {
12 fn visit_package(&mut self, package: &'a Package) {
13 walk_package(self, package);
14 }
15
16 fn visit_namespace(&mut self, namespace: &'a Namespace) {
17 walk_namespace(self, namespace);
18 }
19
20 fn visit_item(&mut self, item: &'a Item) {
21 walk_item(self, item);
22 }
23
24 fn visit_attr(&mut self, attr: &'a Attr) {
25 walk_attr(self, attr);
26 }
27
28 fn visit_ty_def(&mut self, def: &'a TyDef) {
29 walk_ty_def(self, def);
30 }
31
32 fn visit_callable_decl(&mut self, decl: &'a CallableDecl) {
33 walk_callable_decl(self, decl);
34 }
35
36 fn visit_struct_decl(&mut self, decl: &'a StructDecl) {
37 walk_struct_decl(self, decl);
38 }
39
40 fn visit_field_def(&mut self, def: &'a FieldDef) {
41 walk_field_def(self, def);
42 }
43
44 fn visit_spec_decl(&mut self, decl: &'a SpecDecl) {
45 walk_spec_decl(self, decl);
46 }
47
48 fn visit_functor_expr(&mut self, expr: &'a FunctorExpr) {
49 walk_functor_expr(self, expr);
50 }
51
52 fn visit_ty(&mut self, ty: &'a Ty) {
53 walk_ty(self, ty);
54 }
55
56 fn visit_block(&mut self, block: &'a Block) {
57 walk_block(self, block);
58 }
59
60 fn visit_stmt(&mut self, stmt: &'a Stmt) {
61 walk_stmt(self, stmt);
62 }
63
64 fn visit_expr(&mut self, expr: &'a Expr) {
65 walk_expr(self, expr);
66 }
67
68 fn visit_field_assign(&mut self, assign: &'a FieldAssign) {
69 walk_field_assign(self, assign);
70 }
71
72 fn visit_pat(&mut self, pat: &'a Pat) {
73 walk_pat(self, pat);
74 }
75
76 fn visit_qubit_init(&mut self, init: &'a QubitInit) {
77 walk_qubit_init(self, init);
78 }
79
80 fn visit_path(&mut self, path: &'a Path) {
81 walk_path(self, path);
82 }
83
84 fn visit_path_kind(&mut self, path: &'a PathKind) {
85 walk_path_kind(self, path);
86 }
87
88 fn visit_ident(&mut self, _: &'a Ident) {}
89
90 fn visit_idents(&mut self, idents: &'a [Ident]) {
91 walk_idents(self, idents);
92 }
93}
94
95pub fn walk_package<'a>(vis: &mut impl Visitor<'a>, package: &'a Package) {
96 package.nodes.iter().for_each(|n| match n {
97 TopLevelNode::Namespace(ns) => vis.visit_namespace(ns),
98 TopLevelNode::Stmt(stmt) => vis.visit_stmt(stmt),
99 });
100 package.entry.iter().for_each(|e| vis.visit_expr(e));
101}
102
103pub fn walk_namespace<'a>(vis: &mut impl Visitor<'a>, namespace: &'a Namespace) {
104 vis.visit_idents(&namespace.name);
105 namespace.items.iter().for_each(|i| vis.visit_item(i));
106}
107
108pub fn walk_item<'a>(vis: &mut impl Visitor<'a>, item: &'a Item) {
109 item.attrs.iter().for_each(|a| vis.visit_attr(a));
110 match &*item.kind {
111 ItemKind::Err => {}
112 ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
113 ItemKind::Open(ns, alias) => {
114 vis.visit_path_kind(ns);
115 alias.iter().for_each(|a| vis.visit_ident(a));
116 }
117 ItemKind::Ty(ident, def) => {
118 vis.visit_ident(ident);
119 vis.visit_ty_def(def);
120 }
121 ItemKind::Struct(decl) => vis.visit_struct_decl(decl),
122 ItemKind::ImportOrExport(decl) => {
123 for item in &decl.items {
124 vis.visit_path_kind(&item.path);
125 if let Some(ref alias) = item.alias {
126 vis.visit_ident(alias);
127 }
128 }
129 }
130 }
131}
132
133pub fn walk_attr<'a>(vis: &mut impl Visitor<'a>, attr: &'a Attr) {
134 vis.visit_ident(&attr.name);
135 vis.visit_expr(&attr.arg);
136}
137
138pub fn walk_ty_def<'a>(vis: &mut impl Visitor<'a>, def: &'a TyDef) {
139 match &*def.kind {
140 TyDefKind::Field(name, ty) => {
141 name.iter().for_each(|n| vis.visit_ident(n));
142 vis.visit_ty(ty);
143 }
144 TyDefKind::Paren(def) => vis.visit_ty_def(def),
145 TyDefKind::Tuple(defs) => defs.iter().for_each(|d| vis.visit_ty_def(d)),
146 TyDefKind::Err => {}
147 }
148}
149
150pub fn walk_callable_decl<'a>(vis: &mut impl Visitor<'a>, decl: &'a CallableDecl) {
151 vis.visit_ident(&decl.name);
152 decl.generics.iter().for_each(|p| vis.visit_ident(p));
153 vis.visit_pat(&decl.input);
154 vis.visit_ty(&decl.output);
155 decl.functors.iter().for_each(|f| vis.visit_functor_expr(f));
156 match &*decl.body {
157 CallableBody::Block(block) => vis.visit_block(block),
158 CallableBody::Specs(specs) => specs.iter().for_each(|s| vis.visit_spec_decl(s)),
159 }
160}
161
162pub fn walk_struct_decl<'a>(vis: &mut impl Visitor<'a>, decl: &'a StructDecl) {
163 vis.visit_ident(&decl.name);
164 decl.fields.iter().for_each(|f| vis.visit_field_def(f));
165}
166
167pub fn walk_field_def<'a>(vis: &mut impl Visitor<'a>, def: &'a FieldDef) {
168 vis.visit_ident(&def.name);
169 vis.visit_ty(&def.ty);
170}
171
172pub fn walk_spec_decl<'a>(vis: &mut impl Visitor<'a>, decl: &'a SpecDecl) {
173 match &decl.body {
174 SpecBody::Gen(_) => {}
175 SpecBody::Impl(pat, block) => {
176 vis.visit_pat(pat);
177 vis.visit_block(block);
178 }
179 }
180}
181
182pub fn walk_functor_expr<'a>(vis: &mut impl Visitor<'a>, expr: &'a FunctorExpr) {
183 match &*expr.kind {
184 FunctorExprKind::BinOp(_, lhs, rhs) => {
185 vis.visit_functor_expr(lhs);
186 vis.visit_functor_expr(rhs);
187 }
188 FunctorExprKind::Lit(_) => {}
189 FunctorExprKind::Paren(expr) => vis.visit_functor_expr(expr),
190 }
191}
192
193pub fn walk_ty<'a>(vis: &mut impl Visitor<'a>, ty: &'a Ty) {
194 match &*ty.kind {
195 TyKind::Array(item) => vis.visit_ty(item),
196 TyKind::Arrow(_, lhs, rhs, functors) => {
197 vis.visit_ty(lhs);
198 vis.visit_ty(rhs);
199 functors.iter().for_each(|f| vis.visit_functor_expr(f));
200 }
201 TyKind::Hole | TyKind::Err => {}
202 TyKind::Paren(ty) => vis.visit_ty(ty),
203 TyKind::Path(path) => vis.visit_path_kind(path),
204 TyKind::Param(name) => vis.visit_ident(name),
205 TyKind::Tuple(tys) => tys.iter().for_each(|t| vis.visit_ty(t)),
206 }
207}
208
209pub fn walk_block<'a>(vis: &mut impl Visitor<'a>, block: &'a Block) {
210 block.stmts.iter().for_each(|s| vis.visit_stmt(s));
211}
212
213pub fn walk_stmt<'a>(vis: &mut impl Visitor<'a>, stmt: &'a Stmt) {
214 match &*stmt.kind {
215 StmtKind::Empty | StmtKind::Err => {}
216 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(expr),
217 StmtKind::Item(item) => vis.visit_item(item),
218 StmtKind::Local(_, pat, value) => {
219 vis.visit_pat(pat);
220 vis.visit_expr(value);
221 }
222 StmtKind::Qubit(_, pat, init, block) => {
223 vis.visit_pat(pat);
224 vis.visit_qubit_init(init);
225 block.iter().for_each(|b| vis.visit_block(b));
226 }
227 }
228}
229
230pub fn walk_expr<'a>(vis: &mut impl Visitor<'a>, expr: &'a Expr) {
231 match &*expr.kind {
232 ExprKind::Array(exprs) => exprs.iter().for_each(|e| vis.visit_expr(e)),
233 ExprKind::ArrayRepeat(item, size) => {
234 vis.visit_expr(item);
235 vis.visit_expr(size);
236 }
237 ExprKind::Assign(lhs, rhs)
238 | ExprKind::AssignOp(_, lhs, rhs)
239 | ExprKind::BinOp(_, lhs, rhs) => {
240 vis.visit_expr(lhs);
241 vis.visit_expr(rhs);
242 }
243 ExprKind::AssignUpdate(record, index, value) => {
244 vis.visit_expr(record);
245 vis.visit_expr(index);
246 vis.visit_expr(value);
247 }
248 ExprKind::Block(block) => vis.visit_block(block),
249 ExprKind::Call(callee, arg) => {
250 vis.visit_expr(callee);
251 vis.visit_expr(arg);
252 }
253 ExprKind::Conjugate(within, apply) => {
254 vis.visit_block(within);
255 vis.visit_block(apply);
256 }
257 ExprKind::Fail(msg) => vis.visit_expr(msg),
258 ExprKind::Field(record, name) => {
259 vis.visit_expr(record);
260 vis.visit_ident(name);
261 }
262 ExprKind::For(pat, iter, block) => {
263 vis.visit_pat(pat);
264 vis.visit_expr(iter);
265 vis.visit_block(block);
266 }
267 ExprKind::If(cond, body, otherwise) => {
268 vis.visit_expr(cond);
269 vis.visit_block(body);
270 otherwise.iter().for_each(|e| vis.visit_expr(e));
271 }
272 ExprKind::Index(array, index) => {
273 vis.visit_expr(array);
274 vis.visit_expr(index);
275 }
276 ExprKind::Interpolate(components) => {
277 for component in components.as_ref() {
278 match component {
279 StringComponent::Expr(expr) => vis.visit_expr(expr.as_ref()),
280 StringComponent::Lit(_) => {}
281 }
282 }
283 }
284 ExprKind::Lambda(_, pat, expr) => {
285 vis.visit_pat(pat);
286 vis.visit_expr(expr);
287 }
288 ExprKind::Paren(expr) | ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
289 vis.visit_expr(expr);
290 }
291 ExprKind::Path(path) => vis.visit_path_kind(path),
292 ExprKind::Range(start, step, end) => {
293 start.iter().for_each(|s| vis.visit_expr(s));
294 step.iter().for_each(|s| vis.visit_expr(s));
295 end.iter().for_each(|e| vis.visit_expr(e));
296 }
297 ExprKind::Repeat(body, until, fixup) => {
298 vis.visit_block(body);
299 vis.visit_expr(until);
300 fixup.iter().for_each(|f| vis.visit_block(f));
301 }
302 ExprKind::Struct(name, copy, fields) => {
303 vis.visit_path_kind(name);
304 copy.iter().for_each(|c| vis.visit_expr(c));
305 fields.iter().for_each(|f| vis.visit_field_assign(f));
306 }
307 ExprKind::TernOp(_, e1, e2, e3) => {
308 vis.visit_expr(e1);
309 vis.visit_expr(e2);
310 vis.visit_expr(e3);
311 }
312 ExprKind::Tuple(exprs) => exprs.iter().for_each(|e| vis.visit_expr(e)),
313 ExprKind::While(cond, block) => {
314 vis.visit_expr(cond);
315 vis.visit_block(block);
316 }
317 ExprKind::Err | ExprKind::Hole | ExprKind::Lit(_) => {}
318 }
319}
320
321pub fn walk_field_assign<'a>(vis: &mut impl Visitor<'a>, assign: &'a FieldAssign) {
322 vis.visit_ident(&assign.field);
323 vis.visit_expr(&assign.value);
324}
325
326pub fn walk_pat<'a>(vis: &mut impl Visitor<'a>, pat: &'a Pat) {
327 match &*pat.kind {
328 PatKind::Bind(name, ty) => {
329 vis.visit_ident(name);
330 ty.iter().for_each(|t| vis.visit_ty(t));
331 }
332 PatKind::Discard(ty) => ty.iter().for_each(|t| vis.visit_ty(t)),
333 PatKind::Elided | PatKind::Err => {}
334 PatKind::Paren(pat) => vis.visit_pat(pat),
335 PatKind::Tuple(pats) => pats.iter().for_each(|p| vis.visit_pat(p)),
336 }
337}
338
339pub fn walk_qubit_init<'a>(vis: &mut impl Visitor<'a>, init: &'a QubitInit) {
340 match &*init.kind {
341 QubitInitKind::Array(len) => vis.visit_expr(len),
342 QubitInitKind::Paren(init) => vis.visit_qubit_init(init),
343 QubitInitKind::Single | QubitInitKind::Err => {}
344 QubitInitKind::Tuple(inits) => inits.iter().for_each(|i| vis.visit_qubit_init(i)),
345 }
346}
347
348pub fn walk_path<'a>(vis: &mut impl Visitor<'a>, path: &'a Path) {
349 if let Some(ref parts) = path.segments {
350 vis.visit_idents(parts);
351 }
352 vis.visit_ident(&path.name);
353}
354
355pub fn walk_path_kind<'a>(vis: &mut impl Visitor<'a>, path: &'a PathKind) {
356 match path {
357 PathKind::Ok(path) => vis.visit_path(path),
358 PathKind::Err(Some(incomplete_path)) => {
359 vis.visit_idents(&incomplete_path.segments);
360 }
361 PathKind::Err(None) => {}
362 }
363}
364
365pub fn walk_idents<'a>(vis: &mut impl Visitor<'a>, idents: &'a [Ident]) {
366 idents.iter().for_each(|i| vis.visit_ident(i));
367}
368