microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
billt/revert-mimalloc

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/visit.rs

305lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::ast::{
5 Attr, Block, CallableBody, CallableDecl, Expr, ExprKind, FunctorExpr, FunctorExprKind, Ident,
6 Item, ItemKind, Namespace, Package, Pat, PatKind, Path, QubitInit, QubitInitKind, SpecBody,
7 SpecDecl, Stmt, StmtKind, StringComponent, TopLevelNode, Ty, TyDef, TyDefKind, TyKind,
8 Visibility,
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_visibility(&mut self, _: &'a Visibility) {}
29
30 fn visit_ty_def(&mut self, def: &'a TyDef) {
31 walk_ty_def(self, def);
32 }
33
34 fn visit_callable_decl(&mut self, decl: &'a CallableDecl) {
35 walk_callable_decl(self, decl);
36 }
37
38 fn visit_spec_decl(&mut self, decl: &'a SpecDecl) {
39 walk_spec_decl(self, decl);
40 }
41
42 fn visit_functor_expr(&mut self, expr: &'a FunctorExpr) {
43 walk_functor_expr(self, expr);
44 }
45
46 fn visit_ty(&mut self, ty: &'a Ty) {
47 walk_ty(self, ty);
48 }
49
50 fn visit_block(&mut self, block: &'a Block) {
51 walk_block(self, block);
52 }
53
54 fn visit_stmt(&mut self, stmt: &'a Stmt) {
55 walk_stmt(self, stmt);
56 }
57
58 fn visit_expr(&mut self, expr: &'a Expr) {
59 walk_expr(self, expr);
60 }
61
62 fn visit_pat(&mut self, pat: &'a Pat) {
63 walk_pat(self, pat);
64 }
65
66 fn visit_qubit_init(&mut self, init: &'a QubitInit) {
67 walk_qubit_init(self, init);
68 }
69
70 fn visit_path(&mut self, path: &'a Path) {
71 walk_path(self, path);
72 }
73
74 fn visit_ident(&mut self, _: &'a Ident) {}
75}
76
77pub fn walk_package<'a>(vis: &mut impl Visitor<'a>, package: &'a Package) {
78 package.nodes.iter().for_each(|n| match n {
79 TopLevelNode::Namespace(ns) => vis.visit_namespace(ns),
80 TopLevelNode::Stmt(stmt) => vis.visit_stmt(stmt),
81 });
82 package.entry.iter().for_each(|e| vis.visit_expr(e));
83}
84
85pub fn walk_namespace<'a>(vis: &mut impl Visitor<'a>, namespace: &'a Namespace) {
86 vis.visit_ident(&namespace.name);
87 namespace.items.iter().for_each(|i| vis.visit_item(i));
88}
89
90pub fn walk_item<'a>(vis: &mut impl Visitor<'a>, item: &'a Item) {
91 item.attrs.iter().for_each(|a| vis.visit_attr(a));
92 item.visibility.iter().for_each(|v| vis.visit_visibility(v));
93 match &*item.kind {
94 ItemKind::Err => {}
95 ItemKind::Callable(decl) => vis.visit_callable_decl(decl),
96 ItemKind::Open(ns, alias) => {
97 vis.visit_ident(ns);
98 alias.iter().for_each(|a| vis.visit_ident(a));
99 }
100 ItemKind::Ty(ident, def) => {
101 vis.visit_ident(ident);
102 vis.visit_ty_def(def);
103 }
104 }
105}
106
107pub fn walk_attr<'a>(vis: &mut impl Visitor<'a>, attr: &'a Attr) {
108 vis.visit_ident(&attr.name);
109 vis.visit_expr(&attr.arg);
110}
111
112pub fn walk_ty_def<'a>(vis: &mut impl Visitor<'a>, def: &'a TyDef) {
113 match &*def.kind {
114 TyDefKind::Field(name, ty) => {
115 name.iter().for_each(|n| vis.visit_ident(n));
116 vis.visit_ty(ty);
117 }
118 TyDefKind::Paren(def) => vis.visit_ty_def(def),
119 TyDefKind::Tuple(defs) => defs.iter().for_each(|d| vis.visit_ty_def(d)),
120 TyDefKind::Err => {}
121 }
122}
123
124pub fn walk_callable_decl<'a>(vis: &mut impl Visitor<'a>, decl: &'a CallableDecl) {
125 vis.visit_ident(&decl.name);
126 decl.generics.iter().for_each(|p| vis.visit_ident(p));
127 vis.visit_pat(&decl.input);
128 vis.visit_ty(&decl.output);
129 decl.functors.iter().for_each(|f| vis.visit_functor_expr(f));
130 match &*decl.body {
131 CallableBody::Block(block) => vis.visit_block(block),
132 CallableBody::Specs(specs) => specs.iter().for_each(|s| vis.visit_spec_decl(s)),
133 }
134}
135
136pub fn walk_spec_decl<'a>(vis: &mut impl Visitor<'a>, decl: &'a SpecDecl) {
137 match &decl.body {
138 SpecBody::Gen(_) => {}
139 SpecBody::Impl(pat, block) => {
140 vis.visit_pat(pat);
141 vis.visit_block(block);
142 }
143 }
144}
145
146pub fn walk_functor_expr<'a>(vis: &mut impl Visitor<'a>, expr: &'a FunctorExpr) {
147 match &*expr.kind {
148 FunctorExprKind::BinOp(_, lhs, rhs) => {
149 vis.visit_functor_expr(lhs);
150 vis.visit_functor_expr(rhs);
151 }
152 FunctorExprKind::Lit(_) => {}
153 FunctorExprKind::Paren(expr) => vis.visit_functor_expr(expr),
154 }
155}
156
157pub fn walk_ty<'a>(vis: &mut impl Visitor<'a>, ty: &'a Ty) {
158 match &*ty.kind {
159 TyKind::Array(item) => vis.visit_ty(item),
160 TyKind::Arrow(_, lhs, rhs, functors) => {
161 vis.visit_ty(lhs);
162 vis.visit_ty(rhs);
163 functors.iter().for_each(|f| vis.visit_functor_expr(f));
164 }
165 TyKind::Hole | TyKind::Err => {}
166 TyKind::Paren(ty) => vis.visit_ty(ty),
167 TyKind::Path(path) => vis.visit_path(path),
168 TyKind::Param(name) => vis.visit_ident(name),
169 TyKind::Tuple(tys) => tys.iter().for_each(|t| vis.visit_ty(t)),
170 }
171}
172
173pub fn walk_block<'a>(vis: &mut impl Visitor<'a>, block: &'a Block) {
174 block.stmts.iter().for_each(|s| vis.visit_stmt(s));
175}
176
177pub fn walk_stmt<'a>(vis: &mut impl Visitor<'a>, stmt: &'a Stmt) {
178 match &*stmt.kind {
179 StmtKind::Empty | StmtKind::Err => {}
180 StmtKind::Expr(expr) | StmtKind::Semi(expr) => vis.visit_expr(expr),
181 StmtKind::Item(item) => vis.visit_item(item),
182 StmtKind::Local(_, pat, value) => {
183 vis.visit_pat(pat);
184 vis.visit_expr(value);
185 }
186 StmtKind::Qubit(_, pat, init, block) => {
187 vis.visit_pat(pat);
188 vis.visit_qubit_init(init);
189 block.iter().for_each(|b| vis.visit_block(b));
190 }
191 }
192}
193
194pub fn walk_expr<'a>(vis: &mut impl Visitor<'a>, expr: &'a Expr) {
195 match &*expr.kind {
196 ExprKind::Array(exprs) => exprs.iter().for_each(|e| vis.visit_expr(e)),
197 ExprKind::ArrayRepeat(item, size) => {
198 vis.visit_expr(item);
199 vis.visit_expr(size);
200 }
201 ExprKind::Assign(lhs, rhs)
202 | ExprKind::AssignOp(_, lhs, rhs)
203 | ExprKind::BinOp(_, lhs, rhs) => {
204 vis.visit_expr(lhs);
205 vis.visit_expr(rhs);
206 }
207 ExprKind::AssignUpdate(record, index, value) => {
208 vis.visit_expr(record);
209 vis.visit_expr(index);
210 vis.visit_expr(value);
211 }
212 ExprKind::Block(block) => vis.visit_block(block),
213 ExprKind::Call(callee, arg) => {
214 vis.visit_expr(callee);
215 vis.visit_expr(arg);
216 }
217 ExprKind::Conjugate(within, apply) => {
218 vis.visit_block(within);
219 vis.visit_block(apply);
220 }
221 ExprKind::Fail(msg) => vis.visit_expr(msg),
222 ExprKind::Field(record, name) => {
223 vis.visit_expr(record);
224 vis.visit_ident(name);
225 }
226 ExprKind::For(pat, iter, block) => {
227 vis.visit_pat(pat);
228 vis.visit_expr(iter);
229 vis.visit_block(block);
230 }
231 ExprKind::If(cond, body, otherwise) => {
232 vis.visit_expr(cond);
233 vis.visit_block(body);
234 otherwise.iter().for_each(|e| vis.visit_expr(e));
235 }
236 ExprKind::Index(array, index) => {
237 vis.visit_expr(array);
238 vis.visit_expr(index);
239 }
240 ExprKind::Interpolate(components) => {
241 for component in components.as_ref() {
242 match component {
243 StringComponent::Expr(expr) => vis.visit_expr(expr.as_ref()),
244 StringComponent::Lit(_) => {}
245 }
246 }
247 }
248 ExprKind::Lambda(_, pat, expr) => {
249 vis.visit_pat(pat);
250 vis.visit_expr(expr);
251 }
252 ExprKind::Paren(expr) | ExprKind::Return(expr) | ExprKind::UnOp(_, expr) => {
253 vis.visit_expr(expr);
254 }
255 ExprKind::Path(path) => vis.visit_path(path),
256 ExprKind::Range(start, step, end) => {
257 start.iter().for_each(|s| vis.visit_expr(s));
258 step.iter().for_each(|s| vis.visit_expr(s));
259 end.iter().for_each(|e| vis.visit_expr(e));
260 }
261 ExprKind::Repeat(body, until, fixup) => {
262 vis.visit_block(body);
263 vis.visit_expr(until);
264 fixup.iter().for_each(|f| vis.visit_block(f));
265 }
266 ExprKind::TernOp(_, e1, e2, e3) => {
267 vis.visit_expr(e1);
268 vis.visit_expr(e2);
269 vis.visit_expr(e3);
270 }
271 ExprKind::Tuple(exprs) => exprs.iter().for_each(|e| vis.visit_expr(e)),
272 ExprKind::While(cond, block) => {
273 vis.visit_expr(cond);
274 vis.visit_block(block);
275 }
276 ExprKind::Err | ExprKind::Hole | ExprKind::Lit(_) => {}
277 }
278}
279
280pub fn walk_pat<'a>(vis: &mut impl Visitor<'a>, pat: &'a Pat) {
281 match &*pat.kind {
282 PatKind::Bind(name, ty) => {
283 vis.visit_ident(name);
284 ty.iter().for_each(|t| vis.visit_ty(t));
285 }
286 PatKind::Discard(ty) => ty.iter().for_each(|t| vis.visit_ty(t)),
287 PatKind::Elided | PatKind::Err => {}
288 PatKind::Paren(pat) => vis.visit_pat(pat),
289 PatKind::Tuple(pats) => pats.iter().for_each(|p| vis.visit_pat(p)),
290 }
291}
292
293pub fn walk_qubit_init<'a>(vis: &mut impl Visitor<'a>, init: &'a QubitInit) {
294 match &*init.kind {
295 QubitInitKind::Array(len) => vis.visit_expr(len),
296 QubitInitKind::Paren(init) => vis.visit_qubit_init(init),
297 QubitInitKind::Single | QubitInitKind::Err => {}
298 QubitInitKind::Tuple(inits) => inits.iter().for_each(|i| vis.visit_qubit_init(i)),
299 }
300}
301
302pub fn walk_path<'a>(vis: &mut impl Visitor<'a>, path: &'a Path) {
303 path.namespace.iter().for_each(|n| vis.visit_ident(n));
304 vis.visit_ident(&path.name);
305}
306