microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.2.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_eval/src/lower.rs

689lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use qsc_data_structures::index_map::IndexMap;
5use qsc_fir::assigner::Assigner;
6use qsc_fir::fir::{Block, CallableImpl, Expr, Pat, SpecImpl, Stmt};
7use qsc_fir::{
8 fir::{self, BlockId, ExprId, LocalItemId, PatId, StmtId},
9 ty::{Arrow, InferFunctorId, ParamId, Ty},
10};
11use qsc_hir::hir::{self, SpecBody, SpecGen};
12use std::{clone::Clone, rc::Rc};
13
14pub struct Lowerer {
15 nodes: IndexMap<hir::NodeId, fir::NodeId>,
16 locals: IndexMap<hir::NodeId, fir::LocalVarId>,
17 exprs: IndexMap<ExprId, Expr>,
18 pats: IndexMap<PatId, Pat>,
19 stmts: IndexMap<StmtId, Stmt>,
20 blocks: IndexMap<BlockId, Block>,
21 assigner: Assigner,
22}
23
24impl Default for Lowerer {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl Lowerer {
31 #[must_use]
32 pub fn new() -> Self {
33 Self {
34 nodes: IndexMap::new(),
35 locals: IndexMap::new(),
36 exprs: IndexMap::new(),
37 pats: IndexMap::new(),
38 stmts: IndexMap::new(),
39 blocks: IndexMap::new(),
40 assigner: Assigner::new(),
41 }
42 }
43
44 pub fn lower_package(&mut self, package: &hir::Package) -> fir::Package {
45 let entry = package.entry.as_ref().map(|e| self.lower_expr(e));
46 let items: IndexMap<LocalItemId, fir::Item> = package
47 .items
48 .values()
49 .map(|i| self.lower_item(i))
50 .map(|i| (i.id, i))
51 .collect();
52
53 // Lower top-level statements
54 for stmt in &package.stmts {
55 self.lower_stmt(stmt);
56 }
57
58 let blocks: IndexMap<_, _> = self.blocks.drain().collect();
59 let exprs: IndexMap<_, _> = self.exprs.drain().collect();
60 let pats: IndexMap<_, _> = self.pats.drain().collect();
61 let stmts: IndexMap<_, _> = self.stmts.drain().collect();
62
63 let package = fir::Package {
64 items,
65 entry,
66 blocks,
67 exprs,
68 pats,
69 stmts,
70 };
71 qsc_fir::validate::validate(&package);
72 package
73 }
74
75 /// Used to update the package with the lowered items.
76 /// Incremental compilation requires that we update the package
77 /// instead of returning a new one.
78 #[allow(clippy::similar_names)]
79 pub fn lower_and_update_package(
80 &mut self,
81 fir_package: &mut fir::Package,
82 hir_package: &hir::Package,
83 ) -> Vec<StmtId> {
84 let items: IndexMap<LocalItemId, fir::Item> = hir_package
85 .items
86 .values()
87 .map(|i| self.lower_item(i))
88 .map(|i| (i.id, i))
89 .collect();
90
91 let new_stmts = hir_package
92 .stmts
93 .iter()
94 .map(|s| self.lower_stmt(s))
95 .collect();
96
97 self.update_package(fir_package);
98
99 for (k, v) in items {
100 fir_package.items.insert(k, v);
101 }
102
103 qsc_fir::validate::validate(fir_package);
104
105 new_stmts
106 }
107
108 fn update_package(&mut self, package: &mut fir::Package) {
109 for (id, value) in self.blocks.drain() {
110 package.blocks.insert(id, value);
111 }
112
113 for (id, value) in self.exprs.drain() {
114 package.exprs.insert(id, value);
115 }
116
117 for (id, value) in self.pats.drain() {
118 package.pats.insert(id, value);
119 }
120
121 for (id, value) in self.stmts.drain() {
122 package.stmts.insert(id, value);
123 }
124 }
125
126 fn lower_item(&mut self, item: &hir::Item) -> fir::Item {
127 let kind = match &item.kind {
128 hir::ItemKind::Namespace(name, items) => {
129 let name = self.lower_ident(name);
130 let items = items.iter().map(|i| lower_local_item_id(*i)).collect();
131 fir::ItemKind::Namespace(name, items)
132 }
133 hir::ItemKind::Callable(callable) => {
134 let callable = self.lower_callable_decl(callable);
135
136 fir::ItemKind::Callable(callable)
137 }
138 hir::ItemKind::Ty(name, udt) => {
139 let name = self.lower_ident(name);
140 let udt = self.lower_udt(udt);
141
142 fir::ItemKind::Ty(name, udt)
143 }
144 };
145 let attrs = lower_attrs(&item.attrs);
146 fir::Item {
147 id: lower_local_item_id(item.id),
148 span: item.span,
149 parent: item.parent.map(lower_local_item_id),
150 doc: Rc::clone(&item.doc),
151 attrs,
152 visibility: lower_visibility(item.visibility),
153 kind,
154 }
155 }
156
157 fn lower_callable_decl(&mut self, decl: &hir::CallableDecl) -> fir::CallableDecl {
158 let id = self.lower_id(decl.id);
159 let kind = lower_callable_kind(decl.kind);
160 let name = self.lower_ident(&decl.name);
161 let input = self.lower_pat(&decl.input);
162 let generics = lower_generics(&decl.generics);
163 let output = self.lower_ty(&decl.output);
164 let functors = lower_functors(decl.functors);
165 let implementation = if decl.body.body == SpecBody::Gen(SpecGen::Intrinsic) {
166 assert!(
167 !(decl.adj.is_some() || decl.ctl.is_some() || decl.ctl_adj.is_some()),
168 "intrinsic callables should not have specializations"
169 );
170 CallableImpl::Intrinsic
171 } else {
172 let body = self.lower_spec_decl(&decl.body);
173 let adj = decl.adj.as_ref().map(|f| self.lower_spec_decl(f));
174 let ctl = decl.ctl.as_ref().map(|f| self.lower_spec_decl(f));
175 let ctl_adj = decl.ctl_adj.as_ref().map(|f| self.lower_spec_decl(f));
176 let specialized_implementation = SpecImpl {
177 body,
178 adj,
179 ctl,
180 ctl_adj,
181 };
182 CallableImpl::Spec(specialized_implementation)
183 };
184
185 self.assigner.reset_local();
186 self.locals.clear();
187
188 fir::CallableDecl {
189 id,
190 span: decl.span,
191 kind,
192 name,
193 generics,
194 input,
195 output,
196 functors,
197 implementation,
198 }
199 }
200
201 fn lower_spec_decl(&mut self, decl: &hir::SpecDecl) -> fir::SpecDecl {
202 let SpecBody::Impl(pat, block) = &decl.body else {
203 panic!("if a SpecDecl is some, then it must be an implementation");
204 };
205 let input = pat.as_ref().map(|p| self.lower_spec_decl_pat(p));
206 let block = self.lower_block(block);
207 fir::SpecDecl {
208 id: self.lower_id(decl.id),
209 span: decl.span,
210 block,
211 input,
212 }
213 }
214
215 fn lower_spec_decl_pat(&mut self, pat: &hir::Pat) -> PatId {
216 let id = self.assigner.next_pat();
217 let span = pat.span;
218 let ty = self.lower_ty(&pat.ty);
219
220 let kind = match &pat.kind {
221 hir::PatKind::Bind(ident) => fir::PatKind::Bind(self.lower_ident(ident)),
222 hir::PatKind::Discard => fir::PatKind::Discard,
223 hir::PatKind::Tuple(elems) => {
224 fir::PatKind::Tuple(elems.iter().map(|pat| self.lower_pat(pat)).collect())
225 }
226 hir::PatKind::Err => unreachable!("error pat should not be present"),
227 };
228
229 let pat = fir::Pat { id, span, ty, kind };
230 self.pats.insert(id, pat);
231 id
232 }
233
234 fn lower_block(&mut self, block: &hir::Block) -> BlockId {
235 let id = self.assigner.next_block();
236 let block = fir::Block {
237 id,
238 span: block.span,
239 ty: self.lower_ty(&block.ty),
240 stmts: block.stmts.iter().map(|s| self.lower_stmt(s)).collect(),
241 };
242 self.blocks.insert(id, block);
243 id
244 }
245
246 fn lower_stmt(&mut self, stmt: &hir::Stmt) -> fir::StmtId {
247 let id = self.assigner.next_stmt();
248 let kind = match &stmt.kind {
249 hir::StmtKind::Expr(expr) => fir::StmtKind::Expr(self.lower_expr(expr)),
250 hir::StmtKind::Item(item) => fir::StmtKind::Item(lower_local_item_id(*item)),
251 hir::StmtKind::Local(mutability, pat, expr) => fir::StmtKind::Local(
252 lower_mutability(*mutability),
253 self.lower_pat(pat),
254 self.lower_expr(expr),
255 ),
256 hir::StmtKind::Qubit(_, _, _, _) => {
257 panic!("qubit statements should have been eliminated by passes");
258 }
259 hir::StmtKind::Semi(expr) => fir::StmtKind::Semi(self.lower_expr(expr)),
260 };
261 let stmt = fir::Stmt {
262 id,
263 span: stmt.span,
264 kind,
265 };
266 self.stmts.insert(id, stmt);
267 id
268 }
269
270 #[allow(clippy::too_many_lines)]
271 fn lower_expr(&mut self, expr: &hir::Expr) -> ExprId {
272 let id = self.assigner.next_expr();
273 let ty = self.lower_ty(&expr.ty);
274
275 let kind = match &expr.kind {
276 hir::ExprKind::Array(items) => {
277 fir::ExprKind::Array(items.iter().map(|i| self.lower_expr(i)).collect())
278 }
279 hir::ExprKind::ArrayRepeat(value, size) => {
280 fir::ExprKind::ArrayRepeat(self.lower_expr(value), self.lower_expr(size))
281 }
282 hir::ExprKind::Assign(lhs, rhs) => {
283 fir::ExprKind::Assign(self.lower_expr(lhs), self.lower_expr(rhs))
284 }
285 hir::ExprKind::AssignOp(op, lhs, rhs) => fir::ExprKind::AssignOp(
286 lower_binop(*op),
287 self.lower_expr(lhs),
288 self.lower_expr(rhs),
289 ),
290 hir::ExprKind::AssignField(container, field, replace) => {
291 let container = self.lower_expr(container);
292 let field = lower_field(field);
293 let replace = self.lower_expr(replace);
294 fir::ExprKind::AssignField(container, field, replace)
295 }
296 hir::ExprKind::AssignIndex(container, index, replace) => fir::ExprKind::AssignIndex(
297 self.lower_expr(container),
298 self.lower_expr(index),
299 self.lower_expr(replace),
300 ),
301 hir::ExprKind::BinOp(op, lhs, rhs) => {
302 fir::ExprKind::BinOp(lower_binop(*op), self.lower_expr(lhs), self.lower_expr(rhs))
303 }
304 hir::ExprKind::Block(block) => fir::ExprKind::Block(self.lower_block(block)),
305 hir::ExprKind::Call(callee, arg) => {
306 fir::ExprKind::Call(self.lower_expr(callee), self.lower_expr(arg))
307 }
308 hir::ExprKind::Fail(message) => fir::ExprKind::Fail(self.lower_expr(message)),
309 hir::ExprKind::Field(container, field) => {
310 let container = self.lower_expr(container);
311 let field = lower_field(field);
312 fir::ExprKind::Field(container, field)
313 }
314 hir::ExprKind::If(cond, if_true, if_false) => fir::ExprKind::If(
315 self.lower_expr(cond),
316 self.lower_expr(if_true),
317 if_false.as_ref().map(|e| self.lower_expr(e)),
318 ),
319 hir::ExprKind::Index(container, index) => {
320 fir::ExprKind::Index(self.lower_expr(container), self.lower_expr(index))
321 }
322 hir::ExprKind::Lit(lit) => lower_lit(lit),
323 hir::ExprKind::Range(start, step, end) => fir::ExprKind::Range(
324 start.as_ref().map(|s| self.lower_expr(s)),
325 step.as_ref().map(|s| self.lower_expr(s)),
326 end.as_ref().map(|e| self.lower_expr(e)),
327 ),
328 hir::ExprKind::Return(expr) => fir::ExprKind::Return(self.lower_expr(expr)),
329 hir::ExprKind::Tuple(items) => {
330 fir::ExprKind::Tuple(items.iter().map(|i| self.lower_expr(i)).collect())
331 }
332 hir::ExprKind::UnOp(op, operand) => {
333 fir::ExprKind::UnOp(lower_unop(*op), self.lower_expr(operand))
334 }
335 hir::ExprKind::While(cond, body) => {
336 fir::ExprKind::While(self.lower_expr(cond), self.lower_block(body))
337 }
338 hir::ExprKind::Closure(ids, id) => {
339 let ids = ids.iter().map(|id| self.lower_local_id(*id)).collect();
340 fir::ExprKind::Closure(ids, lower_local_item_id(*id))
341 }
342 hir::ExprKind::String(components) => fir::ExprKind::String(
343 components
344 .iter()
345 .map(|c| self.lower_string_component(c))
346 .collect(),
347 ),
348 hir::ExprKind::UpdateIndex(expr1, expr2, expr3) => fir::ExprKind::UpdateIndex(
349 self.lower_expr(expr1),
350 self.lower_expr(expr2),
351 self.lower_expr(expr3),
352 ),
353 hir::ExprKind::UpdateField(record, field, replace) => {
354 let record = self.lower_expr(record);
355 let field = lower_field(field);
356 let replace = self.lower_expr(replace);
357 fir::ExprKind::UpdateField(record, field, replace)
358 }
359 hir::ExprKind::Var(res, args) => {
360 let res = self.lower_res(res);
361 let args = args.iter().map(|arg| self.lower_generic_arg(arg)).collect();
362 fir::ExprKind::Var(res, args)
363 }
364 hir::ExprKind::Conjugate(..) => panic!("conjugate should be eliminated by passes"),
365 hir::ExprKind::Err => panic!("error expr should not be present"),
366 hir::ExprKind::For(..) => panic!("for-loop should be eliminated by passes"),
367 hir::ExprKind::Hole => fir::ExprKind::Hole, // allowed for discards
368 hir::ExprKind::Repeat(..) => panic!("repeat-loop should be eliminated by passes"),
369 };
370
371 let expr = fir::Expr {
372 id,
373 span: expr.span,
374 ty,
375 kind,
376 };
377 self.exprs.insert(id, expr);
378 id
379 }
380
381 fn lower_string_component(&mut self, component: &hir::StringComponent) -> fir::StringComponent {
382 match component {
383 hir::StringComponent::Expr(expr) => fir::StringComponent::Expr(self.lower_expr(expr)),
384 hir::StringComponent::Lit(str) => fir::StringComponent::Lit(Rc::clone(str)),
385 }
386 }
387
388 fn lower_pat(&mut self, pat: &hir::Pat) -> PatId {
389 let id = self.assigner.next_pat();
390 let ty = self.lower_ty(&pat.ty);
391 let kind = match &pat.kind {
392 hir::PatKind::Bind(name) => {
393 let name = self.lower_ident(name);
394 fir::PatKind::Bind(name)
395 }
396 hir::PatKind::Discard => fir::PatKind::Discard,
397 hir::PatKind::Tuple(items) => {
398 fir::PatKind::Tuple(items.iter().map(|i| self.lower_pat(i)).collect())
399 }
400 hir::PatKind::Err => unreachable!("error pat should not be present"),
401 };
402
403 let pat = fir::Pat {
404 id,
405 span: pat.span,
406 ty,
407 kind,
408 };
409 self.pats.insert(id, pat);
410 id
411 }
412
413 fn lower_id(&mut self, id: hir::NodeId) -> fir::NodeId {
414 self.nodes.get(id).copied().unwrap_or_else(|| {
415 let new_id = self.assigner.next_node();
416 self.nodes.insert(id, new_id);
417 new_id
418 })
419 }
420
421 fn lower_local_id(&mut self, id: hir::NodeId) -> fir::LocalVarId {
422 self.locals.get(id).copied().unwrap_or_else(|| {
423 let new_id = self.assigner.next_local();
424 self.locals.insert(id, new_id);
425 new_id
426 })
427 }
428
429 fn lower_res(&mut self, res: &hir::Res) -> fir::Res {
430 match res {
431 hir::Res::Item(item) => fir::Res::Item(lower_item_id(item)),
432 hir::Res::Local(node) => fir::Res::Local(self.lower_local_id(*node)),
433 hir::Res::Err => fir::Res::Err,
434 }
435 }
436
437 fn lower_ident(&mut self, ident: &hir::Ident) -> fir::Ident {
438 fir::Ident {
439 id: self.lower_local_id(ident.id),
440 span: ident.span,
441 name: ident.name.clone(),
442 }
443 }
444
445 fn lower_udt(&mut self, udt: &qsc_hir::ty::Udt) -> qsc_fir::ty::Udt {
446 let span = udt.span;
447 let name = udt.name.clone();
448 let definition = self.lower_udt_defn(&udt.definition);
449 qsc_fir::ty::Udt {
450 span,
451 name,
452 definition,
453 }
454 }
455
456 fn lower_generic_arg(&mut self, arg: &qsc_hir::ty::GenericArg) -> qsc_fir::ty::GenericArg {
457 match &arg {
458 qsc_hir::ty::GenericArg::Ty(ty) => qsc_fir::ty::GenericArg::Ty(self.lower_ty(ty)),
459 qsc_hir::ty::GenericArg::Functor(functors) => {
460 qsc_fir::ty::GenericArg::Functor(lower_functor_set(functors))
461 }
462 }
463 }
464
465 fn lower_udt_defn(&mut self, definition: &qsc_hir::ty::UdtDef) -> qsc_fir::ty::UdtDef {
466 let span = definition.span;
467 let kind = match &definition.kind {
468 qsc_hir::ty::UdtDefKind::Field(field) => {
469 qsc_fir::ty::UdtDefKind::Field(self.lower_udt_field(field))
470 }
471 qsc_hir::ty::UdtDefKind::Tuple(tup) => qsc_fir::ty::UdtDefKind::Tuple(
472 tup.iter().map(|def| self.lower_udt_defn(def)).collect(),
473 ),
474 };
475 qsc_fir::ty::UdtDef { span, kind }
476 }
477
478 fn lower_arrow(&mut self, arrow: &qsc_hir::ty::Arrow) -> Arrow {
479 Arrow {
480 kind: lower_callable_kind(arrow.kind),
481 input: Box::new(self.lower_ty(&arrow.input)),
482 output: Box::new(self.lower_ty(&arrow.output)),
483 functors: lower_functor_set(&arrow.functors),
484 }
485 }
486
487 fn lower_ty(&mut self, ty: &qsc_hir::ty::Ty) -> Ty {
488 match ty {
489 qsc_hir::ty::Ty::Array(array) => qsc_fir::ty::Ty::Array(Box::new(self.lower_ty(array))),
490 qsc_hir::ty::Ty::Arrow(arrow) => {
491 qsc_fir::ty::Ty::Arrow(Box::new(self.lower_arrow(arrow)))
492 }
493 qsc_hir::ty::Ty::Infer(id) => {
494 qsc_fir::ty::Ty::Infer(qsc_fir::ty::InferTyId::from(usize::from(*id)))
495 }
496 qsc_hir::ty::Ty::Param(_, id) => {
497 qsc_fir::ty::Ty::Param(qsc_fir::ty::ParamId::from(usize::from(*id)))
498 }
499 qsc_hir::ty::Ty::Prim(prim) => qsc_fir::ty::Ty::Prim(lower_ty_prim(*prim)),
500 qsc_hir::ty::Ty::Tuple(tys) => {
501 qsc_fir::ty::Ty::Tuple(tys.iter().map(|ty| self.lower_ty(ty)).collect())
502 }
503 qsc_hir::ty::Ty::Udt(_, res) => qsc_fir::ty::Ty::Udt(self.lower_res(res)),
504 qsc_hir::ty::Ty::Err => qsc_fir::ty::Ty::Err,
505 }
506 }
507
508 fn lower_udt_field(&mut self, field: &qsc_hir::ty::UdtField) -> qsc_fir::ty::UdtField {
509 qsc_fir::ty::UdtField {
510 ty: self.lower_ty(&field.ty),
511 name: field.name.clone(),
512 name_span: field.name_span,
513 }
514 }
515}
516
517fn lower_generics(generics: &[qsc_hir::ty::GenericParam]) -> Vec<qsc_fir::ty::GenericParam> {
518 generics.iter().map(lower_generic_param).collect()
519}
520
521fn lower_attrs(attrs: &[hir::Attr]) -> Vec<fir::Attr> {
522 attrs.iter().map(|_| fir::Attr::EntryPoint).collect()
523}
524
525fn lower_functors(functors: qsc_hir::ty::FunctorSetValue) -> qsc_fir::ty::FunctorSetValue {
526 lower_functor_set_value(functors)
527}
528
529fn lower_generic_param(g: &qsc_hir::ty::GenericParam) -> qsc_fir::ty::GenericParam {
530 match g {
531 qsc_hir::ty::GenericParam::Ty(_) => qsc_fir::ty::GenericParam::Ty,
532 qsc_hir::ty::GenericParam::Functor(value) => {
533 qsc_fir::ty::GenericParam::Functor(lower_functor_set_value(*value))
534 }
535 }
536}
537
538fn lower_field(field: &hir::Field) -> fir::Field {
539 match field {
540 hir::Field::Err => fir::Field::Err,
541 hir::Field::Path(path) => fir::Field::Path(fir::FieldPath {
542 indices: path.indices.clone(),
543 }),
544 hir::Field::Prim(field) => fir::Field::Prim(lower_prim_field(*field)),
545 }
546}
547
548fn lower_functor_set(functors: &qsc_hir::ty::FunctorSet) -> qsc_fir::ty::FunctorSet {
549 match *functors {
550 qsc_hir::ty::FunctorSet::Value(v) => {
551 qsc_fir::ty::FunctorSet::Value(lower_functor_set_value(v))
552 }
553 qsc_hir::ty::FunctorSet::Param(p, _) => {
554 qsc_fir::ty::FunctorSet::Param(ParamId::from(usize::from(p)))
555 }
556 qsc_hir::ty::FunctorSet::Infer(i) => {
557 qsc_fir::ty::FunctorSet::Infer(InferFunctorId::from(usize::from(i)))
558 }
559 }
560}
561
562fn lower_prim_field(field: hir::PrimField) -> fir::PrimField {
563 match field {
564 hir::PrimField::Start => fir::PrimField::Start,
565 hir::PrimField::Step => fir::PrimField::Step,
566 hir::PrimField::End => fir::PrimField::End,
567 }
568}
569
570fn lower_item_id(id: &hir::ItemId) -> fir::ItemId {
571 fir::ItemId {
572 item: lower_local_item_id(id.item),
573 package: id.package.map(|p| fir::PackageId::from(usize::from(p))),
574 }
575}
576
577fn lower_ty_prim(prim: qsc_hir::ty::Prim) -> qsc_fir::ty::Prim {
578 match prim {
579 qsc_hir::ty::Prim::Bool => qsc_fir::ty::Prim::Bool,
580 qsc_hir::ty::Prim::Double => qsc_fir::ty::Prim::Double,
581 qsc_hir::ty::Prim::Int => qsc_fir::ty::Prim::Int,
582 qsc_hir::ty::Prim::Qubit => qsc_fir::ty::Prim::Qubit,
583 qsc_hir::ty::Prim::Result => qsc_fir::ty::Prim::Result,
584 qsc_hir::ty::Prim::String => qsc_fir::ty::Prim::String,
585 qsc_hir::ty::Prim::BigInt => qsc_fir::ty::Prim::BigInt,
586 qsc_hir::ty::Prim::RangeTo => qsc_fir::ty::Prim::RangeTo,
587 qsc_hir::ty::Prim::RangeFrom => qsc_fir::ty::Prim::RangeFrom,
588 qsc_hir::ty::Prim::Pauli => qsc_fir::ty::Prim::Pauli,
589 qsc_hir::ty::Prim::RangeFull => qsc_fir::ty::Prim::RangeFull,
590 qsc_hir::ty::Prim::Range => qsc_fir::ty::Prim::Range,
591 }
592}
593
594fn lower_visibility(visibility: hir::Visibility) -> fir::Visibility {
595 match visibility {
596 hir::Visibility::Public => fir::Visibility::Public,
597 hir::Visibility::Internal => fir::Visibility::Internal,
598 }
599}
600
601fn lower_callable_kind(kind: hir::CallableKind) -> fir::CallableKind {
602 match kind {
603 hir::CallableKind::Function => fir::CallableKind::Function,
604 hir::CallableKind::Operation => fir::CallableKind::Operation,
605 }
606}
607
608fn lower_mutability(mutability: hir::Mutability) -> fir::Mutability {
609 match mutability {
610 hir::Mutability::Immutable => fir::Mutability::Immutable,
611 hir::Mutability::Mutable => fir::Mutability::Mutable,
612 }
613}
614
615fn lower_unop(op: hir::UnOp) -> fir::UnOp {
616 match op {
617 hir::UnOp::Functor(f) => fir::UnOp::Functor(lower_functor(f)),
618 hir::UnOp::Neg => fir::UnOp::Neg,
619 hir::UnOp::NotB => fir::UnOp::NotB,
620 hir::UnOp::NotL => fir::UnOp::NotL,
621 hir::UnOp::Pos => fir::UnOp::Pos,
622 hir::UnOp::Unwrap => fir::UnOp::Unwrap,
623 }
624}
625
626fn lower_binop(op: hir::BinOp) -> fir::BinOp {
627 match op {
628 hir::BinOp::Add => fir::BinOp::Add,
629 hir::BinOp::AndB => fir::BinOp::AndB,
630 hir::BinOp::AndL => fir::BinOp::AndL,
631 hir::BinOp::Div => fir::BinOp::Div,
632 hir::BinOp::Eq => fir::BinOp::Eq,
633 hir::BinOp::Exp => fir::BinOp::Exp,
634 hir::BinOp::Gt => fir::BinOp::Gt,
635 hir::BinOp::Gte => fir::BinOp::Gte,
636 hir::BinOp::Lt => fir::BinOp::Lt,
637 hir::BinOp::Lte => fir::BinOp::Lte,
638 hir::BinOp::Mod => fir::BinOp::Mod,
639 hir::BinOp::Mul => fir::BinOp::Mul,
640 hir::BinOp::Neq => fir::BinOp::Neq,
641 hir::BinOp::OrB => fir::BinOp::OrB,
642 hir::BinOp::OrL => fir::BinOp::OrL,
643 hir::BinOp::Shl => fir::BinOp::Shl,
644 hir::BinOp::Shr => fir::BinOp::Shr,
645 hir::BinOp::Sub => fir::BinOp::Sub,
646 hir::BinOp::XorB => fir::BinOp::XorB,
647 }
648}
649
650fn lower_lit(lit: &hir::Lit) -> fir::ExprKind {
651 match lit {
652 hir::Lit::BigInt(value) => fir::ExprKind::Lit(fir::Lit::BigInt(value.clone())),
653 &hir::Lit::Bool(value) => fir::ExprKind::Lit(fir::Lit::Bool(value)),
654 &hir::Lit::Double(value) => fir::ExprKind::Lit(fir::Lit::Double(value)),
655 &hir::Lit::Int(value) => fir::ExprKind::Lit(fir::Lit::Int(value)),
656 hir::Lit::Pauli(hir::Pauli::I) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::I)),
657 hir::Lit::Pauli(hir::Pauli::X) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::X)),
658 hir::Lit::Pauli(hir::Pauli::Y) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::Y)),
659 hir::Lit::Pauli(hir::Pauli::Z) => fir::ExprKind::Lit(fir::Lit::Pauli(fir::Pauli::Z)),
660 hir::Lit::Result(hir::Result::One) => {
661 fir::ExprKind::Lit(fir::Lit::Result(fir::Result::One))
662 }
663 hir::Lit::Result(hir::Result::Zero) => {
664 fir::ExprKind::Lit(fir::Lit::Result(fir::Result::Zero))
665 }
666 }
667}
668
669fn lower_functor(functor: hir::Functor) -> fir::Functor {
670 match functor {
671 hir::Functor::Adj => fir::Functor::Adj,
672 hir::Functor::Ctl => fir::Functor::Ctl,
673 }
674}
675
676fn lower_functor_set_value(value: qsc_hir::ty::FunctorSetValue) -> qsc_fir::ty::FunctorSetValue {
677 match value {
678 qsc_hir::ty::FunctorSetValue::Empty => qsc_fir::ty::FunctorSetValue::Empty,
679 qsc_hir::ty::FunctorSetValue::Adj => qsc_fir::ty::FunctorSetValue::Adj,
680 qsc_hir::ty::FunctorSetValue::Ctl => qsc_fir::ty::FunctorSetValue::Ctl,
681 qsc_hir::ty::FunctorSetValue::CtlAdj => qsc_fir::ty::FunctorSetValue::CtlAdj,
682 }
683}
684
685#[must_use]
686#[allow(clippy::module_name_repetitions)]
687fn lower_local_item_id(id: qsc_hir::hir::LocalItemId) -> LocalItemId {
688 LocalItemId::from(usize::from(id))
689}
690