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_hir/src/visit.rs

203lines · modecode

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