microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.1.3

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/ast.rs

1556lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! The abstract syntax tree (AST) for Q#. The AST directly corresponds to the surface syntax of Q#.
5
6#![warn(missing_docs)]
7
8use indenter::{indented, Format, Indented};
9use num_bigint::BigInt;
10use qsc_data_structures::span::{Span, WithSpan};
11use std::{
12 cmp::Ordering,
13 fmt::{self, Display, Formatter, Write},
14 hash::{Hash, Hasher},
15 rc::Rc,
16};
17
18fn set_indentation<'a, 'b>(
19 indent: Indented<'a, Formatter<'b>>,
20 level: usize,
21) -> Indented<'a, Formatter<'b>> {
22 match level {
23 0 => indent.with_str(""),
24 1 => indent.with_str(" "),
25 2 => indent.with_str(" "),
26 _ => unimplemented!("intentation level not supported"),
27 }
28}
29
30/// The unique identifier for an AST node.
31#[derive(Clone, Copy, Debug)]
32pub struct NodeId(u32);
33
34impl NodeId {
35 const DEFAULT_VALUE: u32 = u32::MAX;
36
37 /// The ID of the first node.
38 pub const FIRST: Self = Self(0);
39
40 /// The successor of this ID.
41 #[must_use]
42 pub fn successor(self) -> Self {
43 Self(self.0 + 1)
44 }
45
46 /// True if this is the default ID.
47 #[must_use]
48 pub fn is_default(self) -> bool {
49 self.0 == Self::DEFAULT_VALUE
50 }
51}
52
53impl Default for NodeId {
54 fn default() -> Self {
55 Self(Self::DEFAULT_VALUE)
56 }
57}
58
59impl Display for NodeId {
60 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
61 if self.is_default() {
62 f.write_str("_id_")
63 } else {
64 self.0.fmt(f)
65 }
66 }
67}
68
69impl From<usize> for NodeId {
70 fn from(value: usize) -> Self {
71 Self(u32::try_from(value).expect("node ID should fit in u32"))
72 }
73}
74
75impl From<NodeId> for usize {
76 fn from(value: NodeId) -> Self {
77 assert!(!value.is_default(), "default node ID should be replaced");
78 value.0 as usize
79 }
80}
81
82impl PartialEq for NodeId {
83 fn eq(&self, other: &Self) -> bool {
84 assert!(!self.is_default(), "default node ID should be replaced");
85 self.0 == other.0
86 }
87}
88
89impl Eq for NodeId {}
90
91impl PartialOrd for NodeId {
92 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
93 Some(self.cmp(other))
94 }
95}
96
97impl Ord for NodeId {
98 fn cmp(&self, other: &Self) -> Ordering {
99 assert!(!self.is_default(), "default node ID should be replaced");
100 self.0.cmp(&other.0)
101 }
102}
103
104impl Hash for NodeId {
105 fn hash<H: Hasher>(&self, state: &mut H) {
106 self.0.hash(state);
107 }
108}
109
110/// The root node of an AST.
111#[derive(Clone, Debug, Default, PartialEq)]
112pub struct Package {
113 /// The node ID.
114 pub id: NodeId,
115 /// The top-level syntax nodes in the package.
116 pub nodes: Box<[TopLevelNode]>,
117 /// The entry expression for an executable package.
118 pub entry: Option<Box<Expr>>,
119}
120
121impl Display for Package {
122 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
123 let mut indent = set_indentation(indented(f), 0);
124 write!(indent, "Package {}:", self.id)?;
125 indent = set_indentation(indent, 1);
126 if let Some(e) = &self.entry {
127 write!(indent, "\nentry expression: {e}")?;
128 }
129 for node in &*self.nodes {
130 write!(indent, "\n{node}")?;
131 }
132 Ok(())
133 }
134}
135
136/// A node that can exist at the top level of a package.
137#[derive(Clone, Debug, PartialEq)]
138pub enum TopLevelNode {
139 /// A namespace
140 Namespace(Namespace),
141 /// A statement
142 Stmt(Box<Stmt>),
143}
144
145impl Display for TopLevelNode {
146 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
147 match self {
148 Self::Namespace(n) => n.fmt(f),
149 Self::Stmt(s) => s.fmt(f),
150 }
151 }
152}
153
154/// A namespace.
155#[derive(Clone, Debug, PartialEq)]
156pub struct Namespace {
157 /// The node ID.
158 pub id: NodeId,
159 /// The span.
160 pub span: Span,
161 /// The documentation.
162 pub doc: Rc<str>,
163 /// The namespace name.
164 pub name: Box<Ident>,
165 /// The items in the namespace.
166 pub items: Box<[Box<Item>]>,
167}
168
169impl Display for Namespace {
170 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
171 let mut indent = set_indentation(indented(f), 0);
172 write!(
173 indent,
174 "Namespace {} {} ({}):",
175 self.id, self.span, self.name
176 )?;
177 indent = set_indentation(indent, 1);
178
179 if !self.doc.is_empty() {
180 write!(indent, "\ndoc:")?;
181 indent = set_indentation(indent, 2);
182 write!(indent, "\n{}", self.doc)?;
183 indent = set_indentation(indent, 1);
184 }
185
186 for i in &*self.items {
187 write!(indent, "\n{i}")?;
188 }
189
190 Ok(())
191 }
192}
193
194/// An item.
195#[derive(Clone, Debug, PartialEq)]
196pub struct Item {
197 /// The ID.
198 pub id: NodeId,
199 /// The span.
200 pub span: Span,
201 /// The documentation.
202 pub doc: Rc<str>,
203 /// The attributes.
204 pub attrs: Box<[Box<Attr>]>,
205 /// The visibility.
206 pub visibility: Option<Visibility>,
207 /// The item kind.
208 pub kind: Box<ItemKind>,
209}
210
211impl Default for Item {
212 fn default() -> Self {
213 Self {
214 id: NodeId::default(),
215 span: Span::default(),
216 doc: "".into(),
217 attrs: Box::default(),
218 visibility: None,
219 kind: Box::default(),
220 }
221 }
222}
223
224impl Display for Item {
225 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
226 let mut indent = set_indentation(indented(f), 0);
227 write!(indent, "Item {} {}:", self.id, self.span)?;
228 indent = set_indentation(indent, 1);
229
230 if !self.doc.is_empty() {
231 write!(indent, "\ndoc:")?;
232 indent = set_indentation(indent, 2);
233 write!(indent, "\n{}", self.doc)?;
234 indent = set_indentation(indent, 1);
235 }
236
237 for attr in &*self.attrs {
238 write!(indent, "\n{attr}")?;
239 }
240
241 if let Some(visibility) = &self.visibility {
242 write!(indent, "\n{visibility}")?;
243 }
244
245 write!(indent, "\n{}", self.kind)?;
246 Ok(())
247 }
248}
249
250/// An item kind.
251#[derive(Clone, Debug, Default, PartialEq)]
252pub enum ItemKind {
253 /// A `function` or `operation` declaration.
254 Callable(Box<CallableDecl>),
255 /// Default item when nothing has been parsed.
256 #[default]
257 Err,
258 /// An `open` item for a namespace with an optional alias.
259 Open(Box<Ident>, Option<Box<Ident>>),
260 /// A `newtype` declaration.
261 Ty(Box<Ident>, Box<TyDef>),
262}
263
264impl Display for ItemKind {
265 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
266 match &self {
267 ItemKind::Callable(decl) => write!(f, "{decl}")?,
268 ItemKind::Err => write!(f, "Err")?,
269 ItemKind::Open(name, alias) => match alias {
270 Some(a) => write!(f, "Open ({name}) ({a})")?,
271 None => write!(f, "Open ({name})")?,
272 },
273 ItemKind::Ty(name, t) => write!(f, "New Type ({name}): {t}")?,
274 }
275 Ok(())
276 }
277}
278
279/// A visibility modifier.
280#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
281pub struct Visibility {
282 /// The node ID.
283 pub id: NodeId,
284 /// The span.
285 pub span: Span,
286 /// The visibility kind.
287 pub kind: VisibilityKind,
288}
289
290impl Display for Visibility {
291 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
292 write!(f, "Visibility {} {} ({:?})", self.id, self.span, self.kind)
293 }
294}
295
296/// An attribute.
297#[derive(Clone, Debug, PartialEq)]
298pub struct Attr {
299 /// The node ID.
300 pub id: NodeId,
301 /// The span.
302 pub span: Span,
303 /// The name of the attribute.
304 pub name: Box<Ident>,
305 /// The argument to the attribute.
306 pub arg: Box<Expr>,
307}
308
309impl Display for Attr {
310 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
311 let mut indent = set_indentation(indented(f), 0);
312 write!(indent, "Attr {} {} ({}):", self.id, self.span, self.name)?;
313 indent = set_indentation(indent, 1);
314 write!(indent, "\n{}", self.arg)?;
315 Ok(())
316 }
317}
318
319/// A type definition.
320#[derive(Clone, Debug, PartialEq, Default)]
321pub struct TyDef {
322 /// The node ID.
323 pub id: NodeId,
324 /// The span.
325 pub span: Span,
326 /// The type definition kind.
327 pub kind: Box<TyDefKind>,
328}
329
330impl Display for TyDef {
331 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
332 write!(f, "TyDef {} {}: {}", self.id, self.span, self.kind)
333 }
334}
335
336impl WithSpan for TyDef {
337 fn with_span(self, span: Span) -> Self {
338 Self { span, ..self }
339 }
340}
341
342/// A type definition kind.
343#[derive(Clone, Debug, PartialEq, Default)]
344pub enum TyDefKind {
345 /// A field definition with an optional name but required type.
346 Field(Option<Box<Ident>>, Box<Ty>),
347 /// A parenthesized type definition.
348 Paren(Box<TyDef>),
349 /// A tuple.
350 Tuple(Box<[Box<TyDef>]>),
351 /// An invalid type definition.
352 #[default]
353 Err,
354}
355
356impl Display for TyDefKind {
357 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
358 let mut indent = set_indentation(indented(f), 0);
359 match &self {
360 TyDefKind::Field(name, t) => {
361 write!(indent, "Field:")?;
362 indent = set_indentation(indent, 1);
363 if let Some(n) = name {
364 write!(indent, "\n{n}")?;
365 }
366 write!(indent, "\n{t}")?;
367 }
368 TyDefKind::Paren(t) => {
369 write!(indent, "Paren:")?;
370 indent = set_indentation(indent, 1);
371 write!(indent, "\n{t}")?;
372 }
373 TyDefKind::Tuple(ts) => {
374 if ts.is_empty() {
375 write!(indent, "Unit")?;
376 } else {
377 write!(indent, "Tuple:")?;
378 indent = set_indentation(indent, 1);
379 for t in ts.iter() {
380 write!(indent, "\n{t}")?;
381 }
382 }
383 }
384 TyDefKind::Err => write!(indent, "Err")?,
385 }
386 Ok(())
387 }
388}
389
390/// A callable declaration header.
391#[derive(Clone, Debug, PartialEq)]
392pub struct CallableDecl {
393 /// The node ID.
394 pub id: NodeId,
395 /// The span.
396 pub span: Span,
397 /// The callable kind.
398 pub kind: CallableKind,
399 /// The name of the callable.
400 pub name: Box<Ident>,
401 /// The generic parameters to the callable.
402 pub generics: Box<[Box<Ident>]>,
403 /// The input to the callable.
404 pub input: Box<Pat>,
405 /// The return type of the callable.
406 pub output: Box<Ty>,
407 /// The functors supported by the callable.
408 pub functors: Option<Box<FunctorExpr>>,
409 /// The body of the callable.
410 pub body: Box<CallableBody>,
411}
412
413impl Display for CallableDecl {
414 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
415 let mut indent = set_indentation(indented(f), 0);
416 write!(
417 indent,
418 "Callable {} {} ({:?}):",
419 self.id, self.span, self.kind
420 )?;
421 indent = set_indentation(indent, 1);
422 write!(indent, "\nname: {}", self.name)?;
423 if !self.generics.is_empty() {
424 write!(indent, "\ngenerics:")?;
425 indent = set_indentation(indent, 2);
426 for param in &*self.generics {
427 write!(indent, "\n{param}")?;
428 }
429 indent = set_indentation(indent, 1);
430 }
431 write!(indent, "\ninput: {}", self.input)?;
432 write!(indent, "\noutput: {}", self.output)?;
433 if let Some(f) = &self.functors {
434 write!(indent, "\nfunctors: {}", f.as_ref())?;
435 }
436 write!(indent, "\nbody: {}", self.body)?;
437 Ok(())
438 }
439}
440
441/// The body of a callable.
442#[derive(Clone, Debug, PartialEq)]
443pub enum CallableBody {
444 /// A block for the callable's body specialization.
445 Block(Box<Block>),
446 /// One or more explicit specializations.
447 Specs(Box<[Box<SpecDecl>]>),
448}
449
450impl Display for CallableBody {
451 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
452 match self {
453 CallableBody::Block(body) => write!(f, "Block: {body}")?,
454 CallableBody::Specs(specs) => {
455 let mut indent = set_indentation(indented(f), 0);
456 write!(indent, "Specializations:")?;
457 indent = set_indentation(indent, 1);
458 for spec in specs.iter() {
459 write!(indent, "\n{spec}")?;
460 }
461 }
462 }
463 Ok(())
464 }
465}
466
467/// A specialization declaration.
468#[derive(Clone, Debug, PartialEq)]
469pub struct SpecDecl {
470 /// The node ID.
471 pub id: NodeId,
472 /// The span.
473 pub span: Span,
474 /// Which specialization is being declared.
475 pub spec: Spec,
476 /// The body of the specialization.
477 pub body: SpecBody,
478}
479
480impl Display for SpecDecl {
481 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
482 write!(
483 f,
484 "SpecDecl {} {} ({:?}): {}",
485 self.id, self.span, self.spec, self.body
486 )
487 }
488}
489
490/// The body of a specialization.
491#[derive(Clone, Debug, PartialEq)]
492pub enum SpecBody {
493 /// The strategy to use to automatically generate the specialization.
494 Gen(SpecGen),
495 /// A manual implementation of the specialization.
496 Impl(Box<Pat>, Box<Block>),
497}
498
499impl Display for SpecBody {
500 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
501 let mut indent = set_indentation(indented(f), 0);
502 match self {
503 SpecBody::Gen(sg) => write!(indent, "Gen: {sg:?}")?,
504 SpecBody::Impl(p, b) => {
505 write!(indent, "Impl:")?;
506 indent = set_indentation(indent, 1);
507 write!(indent, "\n{p}")?;
508 write!(indent, "\n{b}")?;
509 }
510 }
511 Ok(())
512 }
513}
514
515/// An expression that describes a set of functors.
516#[derive(Clone, Debug, Eq, Hash, PartialEq)]
517pub struct FunctorExpr {
518 /// The node ID.
519 pub id: NodeId,
520 /// The span.
521 pub span: Span,
522 /// The functor expression kind.
523 pub kind: Box<FunctorExprKind>,
524}
525
526impl Display for FunctorExpr {
527 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
528 write!(f, "Functor Expr {} {}: {}", self.id, self.span, self.kind)
529 }
530}
531
532/// A functor expression kind.
533#[derive(Clone, Debug, Eq, Hash, PartialEq)]
534pub enum FunctorExprKind {
535 /// A binary operation.
536 BinOp(SetOp, Box<FunctorExpr>, Box<FunctorExpr>),
537 /// A literal for a specific functor.
538 Lit(Functor),
539 /// A parenthesized group.
540 Paren(Box<FunctorExpr>),
541}
542
543impl Display for FunctorExprKind {
544 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
545 match self {
546 FunctorExprKind::BinOp(op, l, r) => write!(f, "BinOp {op:?}: ({l}) ({r})"),
547 FunctorExprKind::Lit(func) => write!(f, "{func:?}"),
548 FunctorExprKind::Paren(func) => write!(f, "Paren: {func}"),
549 }
550 }
551}
552
553/// A type.
554#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
555pub struct Ty {
556 /// The node ID.
557 pub id: NodeId,
558 /// The span.
559 pub span: Span,
560 /// The type kind.
561 pub kind: Box<TyKind>,
562}
563
564impl Display for Ty {
565 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
566 write!(f, "Type {} {}: {}", self.id, self.span, self.kind)
567 }
568}
569
570impl WithSpan for Ty {
571 fn with_span(self, span: Span) -> Self {
572 Self { span, ..self }
573 }
574}
575
576/// A type kind.
577#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
578pub enum TyKind {
579 /// An array type.
580 Array(Box<Ty>),
581 /// An arrow type: `->` for a function or `=>` for an operation.
582 Arrow(CallableKind, Box<Ty>, Box<Ty>, Option<Box<FunctorExpr>>),
583 /// An unspecified type, `_`, which may be inferred.
584 Hole,
585 /// A type wrapped in parentheses.
586 Paren(Box<Ty>),
587 /// A named type.
588 Path(Box<Path>),
589 /// A type parameter.
590 Param(Box<Ident>),
591 /// A tuple type.
592 Tuple(Box<[Ty]>),
593 /// An invalid type.
594 #[default]
595 Err,
596}
597
598impl Display for TyKind {
599 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
600 let mut indent = set_indentation(indented(f), 0);
601 match self {
602 TyKind::Array(item) => write!(indent, "Array: {item}")?,
603 TyKind::Arrow(ck, param, rtrn, functors) => {
604 write!(indent, "Arrow ({ck:?}):")?;
605 indent = set_indentation(indent, 1);
606 write!(indent, "\nparam: {param}")?;
607 write!(indent, "\nreturn: {rtrn}")?;
608 if let Some(f) = functors {
609 write!(indent, "\nfunctors: {f}")?;
610 }
611 }
612 TyKind::Hole => write!(indent, "Hole")?,
613 TyKind::Paren(t) => write!(indent, "Paren: {t}")?,
614 TyKind::Path(p) => write!(indent, "Path: {p}")?,
615 TyKind::Param(name) => write!(indent, "Type Param: {name}")?,
616 TyKind::Tuple(ts) => {
617 if ts.is_empty() {
618 write!(indent, "Unit")?;
619 } else {
620 write!(indent, "Tuple:")?;
621 indent = indent.with_format(Format::Uniform {
622 indentation: " ",
623 });
624 for t in ts.iter() {
625 write!(indent, "\n{t}")?;
626 }
627 }
628 }
629 TyKind::Err => write!(indent, "Err")?,
630 }
631 Ok(())
632 }
633}
634
635/// A sequenced block of statements.
636#[derive(Clone, Debug, PartialEq)]
637pub struct Block {
638 /// The node ID.
639 pub id: NodeId,
640 /// The span.
641 pub span: Span,
642 /// The statements in the block.
643 pub stmts: Box<[Box<Stmt>]>,
644}
645
646impl Display for Block {
647 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
648 if self.stmts.is_empty() {
649 write!(f, "Block {} {}: <empty>", self.id, self.span)?;
650 } else {
651 let mut indent = set_indentation(indented(f), 0);
652 write!(indent, "Block {} {}:", self.id, self.span)?;
653 indent = set_indentation(indent, 1);
654 for s in &*self.stmts {
655 write!(indent, "\n{s}")?;
656 }
657 }
658 Ok(())
659 }
660}
661
662/// A statement.
663#[derive(Clone, Debug, Default, PartialEq)]
664pub struct Stmt {
665 /// The node ID.
666 pub id: NodeId,
667 /// The span.
668 pub span: Span,
669 /// The statement kind.
670 pub kind: Box<StmtKind>,
671}
672
673impl Display for Stmt {
674 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
675 write!(f, "Stmt {} {}: {}", self.id, self.span, self.kind)
676 }
677}
678
679/// A statement kind.
680#[derive(Clone, Debug, Default, PartialEq)]
681pub enum StmtKind {
682 /// An empty statement.
683 Empty,
684 /// An expression without a trailing semicolon.
685 Expr(Box<Expr>),
686 /// A let or mutable binding: `let a = b;` or `mutable x = b;`.
687 Local(Mutability, Box<Pat>, Box<Expr>),
688 /// An item.
689 Item(Box<Item>),
690 /// A use or borrow qubit allocation: `use a = b;` or `borrow a = b;`.
691 Qubit(QubitSource, Box<Pat>, Box<QubitInit>, Option<Box<Block>>),
692 /// An expression with a trailing semicolon.
693 Semi(Box<Expr>),
694 /// An invalid statement.
695 #[default]
696 Err,
697}
698
699impl Display for StmtKind {
700 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
701 let mut indent = set_indentation(indented(f), 0);
702 match self {
703 StmtKind::Empty => write!(indent, "Empty")?,
704 StmtKind::Expr(e) => write!(indent, "Expr: {e}")?,
705 StmtKind::Item(item) => write!(indent, "Item: {item}")?,
706 StmtKind::Local(m, lhs, rhs) => {
707 write!(indent, "Local ({m:?}):")?;
708 indent = set_indentation(indent, 1);
709 write!(indent, "\n{lhs}")?;
710 write!(indent, "\n{rhs}")?;
711 }
712 StmtKind::Qubit(s, lhs, rhs, block) => {
713 write!(indent, "Qubit ({s:?})")?;
714 indent = set_indentation(indent, 1);
715 write!(indent, "\n{lhs}")?;
716 write!(indent, "\n{rhs}")?;
717 if let Some(b) = block {
718 write!(indent, "\n{b}")?;
719 }
720 }
721 StmtKind::Semi(e) => write!(indent, "Semi: {e}")?,
722 StmtKind::Err => indent.write_str("Err")?,
723 }
724 Ok(())
725 }
726}
727
728/// An expression.
729#[derive(Clone, Debug, Default, PartialEq)]
730pub struct Expr {
731 /// The node ID.
732 pub id: NodeId,
733 /// The span.
734 pub span: Span,
735 /// The expression kind.
736 pub kind: Box<ExprKind>,
737}
738
739impl Display for Expr {
740 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
741 write!(f, "Expr {} {}: {}", self.id, self.span, self.kind)
742 }
743}
744
745impl WithSpan for Expr {
746 fn with_span(self, span: Span) -> Self {
747 Self { span, ..self }
748 }
749}
750
751/// An expression kind.
752#[derive(Clone, Debug, Default, PartialEq)]
753pub enum ExprKind {
754 /// An array: `[a, b, c]`.
755 Array(Box<[Box<Expr>]>),
756 /// An array constructed by repeating a value: `[a, size = b]`.
757 ArrayRepeat(Box<Expr>, Box<Expr>),
758 /// An assignment: `set a = b`.
759 Assign(Box<Expr>, Box<Expr>),
760 /// An assignment with a compound operator. For example: `set a += b`.
761 AssignOp(BinOp, Box<Expr>, Box<Expr>),
762 /// An assignment with a compound update operator: `set a w/= b <- c`.
763 AssignUpdate(Box<Expr>, Box<Expr>, Box<Expr>),
764 /// A binary operator.
765 BinOp(BinOp, Box<Expr>, Box<Expr>),
766 /// A block: `{ ... }`.
767 Block(Box<Block>),
768 /// A call: `a(b)`.
769 Call(Box<Expr>, Box<Expr>),
770 /// A conjugation: `within { ... } apply { ... }`.
771 Conjugate(Box<Block>, Box<Block>),
772 /// An expression with invalid syntax that can't be parsed.
773 #[default]
774 Err,
775 /// A failure: `fail "message"`.
776 Fail(Box<Expr>),
777 /// A field accessor: `a::F`.
778 Field(Box<Expr>, Box<Ident>),
779 /// A for loop: `for a in b { ... }`.
780 For(Box<Pat>, Box<Expr>, Box<Block>),
781 /// An unspecified expression, _, which may indicate partial application or a typed hole.
782 Hole,
783 /// An if expression with an optional else block: `if a { ... } else { ... }`.
784 ///
785 /// Note that, as a special case, `elif ...` is effectively parsed as `else if ...`, without a
786 /// block wrapping the `if`. This distinguishes `elif ...` from `else { if ... }`, which does
787 /// have a block.
788 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
789 /// An index accessor: `a[b]`.
790 Index(Box<Expr>, Box<Expr>),
791 /// An interpolated string.
792 Interpolate(Box<[StringComponent]>),
793 /// A lambda: `a -> b` for a function and `a => b` for an operation.
794 Lambda(CallableKind, Box<Pat>, Box<Expr>),
795 /// A literal.
796 Lit(Box<Lit>),
797 /// Parentheses: `(a)`.
798 Paren(Box<Expr>),
799 /// A path: `a` or `a.b`.
800 Path(Box<Path>),
801 /// A range: `start..step..end`, `start..end`, `start...`, `...end`, or `...`.
802 Range(Option<Box<Expr>>, Option<Box<Expr>>, Option<Box<Expr>>),
803 /// A repeat-until loop with an optional fixup: `repeat { ... } until a fixup { ... }`.
804 Repeat(Box<Block>, Box<Expr>, Option<Box<Block>>),
805 /// A return: `return a`.
806 Return(Box<Expr>),
807 /// A ternary operator.
808 TernOp(TernOp, Box<Expr>, Box<Expr>, Box<Expr>),
809 /// A tuple: `(a, b, c)`.
810 Tuple(Box<[Box<Expr>]>),
811 /// A unary operator.
812 UnOp(UnOp, Box<Expr>),
813 /// A while loop: `while a { ... }`.
814 While(Box<Expr>, Box<Block>),
815}
816
817impl Display for ExprKind {
818 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
819 let mut indent = set_indentation(indented(f), 0);
820 match self {
821 ExprKind::Array(exprs) => display_array(indent, exprs)?,
822 ExprKind::ArrayRepeat(val, size) => display_array_repeat(indent, val, size)?,
823 ExprKind::Assign(lhs, rhs) => display_assign(indent, lhs, rhs)?,
824 ExprKind::AssignOp(op, lhs, rhs) => display_assign_op(indent, *op, lhs, rhs)?,
825 ExprKind::AssignUpdate(container, item, val) => {
826 display_assign_update(indent, container, item, val)?;
827 }
828 ExprKind::BinOp(op, lhs, rhs) => display_bin_op(indent, *op, lhs, rhs)?,
829 ExprKind::Block(block) => write!(indent, "Expr Block: {block}")?,
830 ExprKind::Call(callable, arg) => display_call(indent, callable, arg)?,
831 ExprKind::Conjugate(within, apply) => display_conjugate(indent, within, apply)?,
832 ExprKind::Err => write!(indent, "Err")?,
833 ExprKind::Fail(e) => write!(indent, "Fail: {e}")?,
834 ExprKind::Field(expr, id) => display_field(indent, expr, id)?,
835 ExprKind::For(iter, iterable, body) => display_for(indent, iter, iterable, body)?,
836 ExprKind::Hole => write!(indent, "Hole")?,
837 ExprKind::If(cond, body, els) => display_if(indent, cond, body, els)?,
838 ExprKind::Index(array, index) => display_index(indent, array, index)?,
839 ExprKind::Interpolate(components) => display_interpolate(indent, components)?,
840 ExprKind::Lambda(kind, param, expr) => display_lambda(indent, *kind, param, expr)?,
841 ExprKind::Lit(lit) => write!(indent, "Lit: {lit}")?,
842 ExprKind::Paren(e) => write!(indent, "Paren: {e}")?,
843 ExprKind::Path(p) => write!(indent, "Path: {p}")?,
844 ExprKind::Range(start, step, end) => display_range(indent, start, step, end)?,
845 ExprKind::Repeat(repeat, until, fixup) => display_repeat(indent, repeat, until, fixup)?,
846 ExprKind::Return(e) => write!(indent, "Return: {e}")?,
847 ExprKind::TernOp(op, expr1, expr2, expr3) => {
848 display_tern_op(indent, *op, expr1, expr2, expr3)?;
849 }
850 ExprKind::Tuple(exprs) => display_tuple(indent, exprs)?,
851 ExprKind::UnOp(op, expr) => display_un_op(indent, *op, expr)?,
852 ExprKind::While(cond, block) => display_while(indent, cond, block)?,
853 }
854 Ok(())
855 }
856}
857
858fn display_array(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
859 write!(indent, "Array:")?;
860 indent = set_indentation(indent, 1);
861 for e in exprs {
862 write!(indent, "\n{e}")?;
863 }
864 Ok(())
865}
866
867fn display_array_repeat(mut indent: Indented<Formatter>, val: &Expr, size: &Expr) -> fmt::Result {
868 write!(indent, "ArrayRepeat:")?;
869 indent = set_indentation(indent, 1);
870 write!(indent, "\n{val}")?;
871 write!(indent, "\n{size}")?;
872 Ok(())
873}
874
875fn display_assign(mut indent: Indented<Formatter>, lhs: &Expr, rhs: &Expr) -> fmt::Result {
876 write!(indent, "Assign:")?;
877 indent = set_indentation(indent, 1);
878 write!(indent, "\n{lhs}")?;
879 write!(indent, "\n{rhs}")?;
880 Ok(())
881}
882
883fn display_assign_op(
884 mut indent: Indented<Formatter>,
885 op: BinOp,
886 lhs: &Expr,
887 rhs: &Expr,
888) -> fmt::Result {
889 write!(indent, "AssignOp ({op:?}):")?;
890 indent = set_indentation(indent, 1);
891 write!(indent, "\n{lhs}")?;
892 write!(indent, "\n{rhs}")?;
893 Ok(())
894}
895
896fn display_assign_update(
897 mut indent: Indented<Formatter>,
898 container: &Expr,
899 item: &Expr,
900 val: &Expr,
901) -> fmt::Result {
902 write!(indent, "AssignUpdate:")?;
903 indent = set_indentation(indent, 1);
904 write!(indent, "\n{container}")?;
905 write!(indent, "\n{item}")?;
906 write!(indent, "\n{val}")?;
907 Ok(())
908}
909
910fn display_bin_op(
911 mut indent: Indented<Formatter>,
912 op: BinOp,
913 lhs: &Expr,
914 rhs: &Expr,
915) -> fmt::Result {
916 write!(indent, "BinOp ({op:?}):")?;
917 indent = set_indentation(indent, 1);
918 write!(indent, "\n{lhs}")?;
919 write!(indent, "\n{rhs}")?;
920 Ok(())
921}
922
923fn display_call(mut indent: Indented<Formatter>, callable: &Expr, arg: &Expr) -> fmt::Result {
924 write!(indent, "Call:")?;
925 indent = set_indentation(indent, 1);
926 write!(indent, "\n{callable}")?;
927 write!(indent, "\n{arg}")?;
928 Ok(())
929}
930
931fn display_conjugate(
932 mut indent: Indented<Formatter>,
933 within: &Block,
934 apply: &Block,
935) -> fmt::Result {
936 write!(indent, "Conjugate:")?;
937 indent = set_indentation(indent, 1);
938 write!(indent, "\n{within}")?;
939 write!(indent, "\n{apply}")?;
940 Ok(())
941}
942
943fn display_field(mut indent: Indented<Formatter>, expr: &Expr, id: &Ident) -> fmt::Result {
944 write!(indent, "Field:")?;
945 indent = set_indentation(indent, 1);
946 write!(indent, "\n{expr}")?;
947 write!(indent, "\n{id}")?;
948 Ok(())
949}
950
951fn display_for(
952 mut indent: Indented<Formatter>,
953 iter: &Pat,
954 iterable: &Expr,
955 body: &Block,
956) -> fmt::Result {
957 write!(indent, "For:")?;
958 indent = set_indentation(indent, 1);
959 write!(indent, "\n{iter}")?;
960 write!(indent, "\n{iterable}")?;
961 write!(indent, "\n{body}")?;
962 Ok(())
963}
964
965fn display_if(
966 mut indent: Indented<Formatter>,
967 cond: &Expr,
968 body: &Block,
969 els: &Option<Box<Expr>>,
970) -> fmt::Result {
971 write!(indent, "If:")?;
972 indent = set_indentation(indent, 1);
973 write!(indent, "\n{cond}")?;
974 write!(indent, "\n{body}")?;
975 if let Some(e) = els {
976 write!(indent, "\n{e}")?;
977 }
978 Ok(())
979}
980
981fn display_index(mut indent: Indented<Formatter>, array: &Expr, index: &Expr) -> fmt::Result {
982 write!(indent, "Index:")?;
983 indent = set_indentation(indent, 1);
984 write!(indent, "\n{array}")?;
985 write!(indent, "\n{index}")?;
986 Ok(())
987}
988
989fn display_interpolate(
990 mut indent: Indented<Formatter>,
991 components: &[StringComponent],
992) -> fmt::Result {
993 write!(indent, "Interpolate:")?;
994 indent = set_indentation(indent, 1);
995 for component in components {
996 match component {
997 StringComponent::Expr(expr) => write!(indent, "\nExpr: {expr}")?,
998 StringComponent::Lit(str) => write!(indent, "\nLit: {str:?}")?,
999 }
1000 }
1001
1002 Ok(())
1003}
1004
1005fn display_lambda(
1006 mut indent: Indented<Formatter>,
1007 kind: CallableKind,
1008 param: &Pat,
1009 expr: &Expr,
1010) -> fmt::Result {
1011 write!(indent, "Lambda ({kind:?}):")?;
1012 indent = set_indentation(indent, 1);
1013 write!(indent, "\n{param}")?;
1014 write!(indent, "\n{expr}")?;
1015 Ok(())
1016}
1017
1018fn display_range(
1019 mut indent: Indented<Formatter>,
1020 start: &Option<Box<Expr>>,
1021 step: &Option<Box<Expr>>,
1022 end: &Option<Box<Expr>>,
1023) -> fmt::Result {
1024 write!(indent, "Range:")?;
1025 indent = set_indentation(indent, 1);
1026 match start {
1027 Some(e) => write!(indent, "\n{e}")?,
1028 None => write!(indent, "\n<no start>")?,
1029 }
1030 match step {
1031 Some(e) => write!(indent, "\n{e}")?,
1032 None => write!(indent, "\n<no step>")?,
1033 }
1034 match end {
1035 Some(e) => write!(indent, "\n{e}")?,
1036 None => write!(indent, "\n<no end>")?,
1037 }
1038 Ok(())
1039}
1040
1041fn display_repeat(
1042 mut indent: Indented<Formatter>,
1043 repeat: &Block,
1044 until: &Expr,
1045 fixup: &Option<Box<Block>>,
1046) -> fmt::Result {
1047 write!(indent, "Repeat:")?;
1048 indent = set_indentation(indent, 1);
1049 write!(indent, "\n{repeat}")?;
1050 write!(indent, "\n{until}")?;
1051 match fixup {
1052 Some(b) => write!(indent, "\n{b}")?,
1053 None => write!(indent, "\n<no fixup>")?,
1054 }
1055 Ok(())
1056}
1057
1058fn display_tern_op(
1059 mut indent: Indented<Formatter>,
1060 op: TernOp,
1061 expr1: &Expr,
1062 expr2: &Expr,
1063 expr3: &Expr,
1064) -> fmt::Result {
1065 write!(indent, "TernOp ({op:?}):")?;
1066 indent = set_indentation(indent, 1);
1067 write!(indent, "\n{expr1}")?;
1068 write!(indent, "\n{expr2}")?;
1069 write!(indent, "\n{expr3}")?;
1070 Ok(())
1071}
1072
1073fn display_tuple(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
1074 if exprs.is_empty() {
1075 write!(indent, "Unit")?;
1076 } else {
1077 write!(indent, "Tuple:")?;
1078 indent = set_indentation(indent, 1);
1079 for e in exprs {
1080 write!(indent, "\n{e}")?;
1081 }
1082 }
1083 Ok(())
1084}
1085
1086fn display_un_op(mut indent: Indented<Formatter>, op: UnOp, expr: &Expr) -> fmt::Result {
1087 write!(indent, "UnOp ({op}):")?;
1088 indent = set_indentation(indent, 1);
1089 write!(indent, "\n{expr}")?;
1090 Ok(())
1091}
1092
1093fn display_while(mut indent: Indented<Formatter>, cond: &Expr, block: &Block) -> fmt::Result {
1094 write!(indent, "While:")?;
1095 indent = set_indentation(indent, 1);
1096 write!(indent, "\n{cond}")?;
1097 write!(indent, "\n{block}")?;
1098 Ok(())
1099}
1100
1101/// An interpolated string component.
1102#[derive(Clone, Debug, PartialEq)]
1103pub enum StringComponent {
1104 /// An expression.
1105 Expr(Box<Expr>),
1106 /// A string literal.
1107 Lit(Rc<str>),
1108}
1109
1110/// A pattern.
1111#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1112pub struct Pat {
1113 /// The node ID.
1114 pub id: NodeId,
1115 /// The span.
1116 pub span: Span,
1117 /// The pattern kind.
1118 pub kind: Box<PatKind>,
1119}
1120
1121impl Display for Pat {
1122 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1123 write!(f, "Pat {} {}: {}", self.id, self.span, self.kind)
1124 }
1125}
1126
1127impl WithSpan for Pat {
1128 fn with_span(self, span: Span) -> Self {
1129 Self { span, ..self }
1130 }
1131}
1132
1133/// A pattern kind.
1134#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1135pub enum PatKind {
1136 /// A binding with an optional type annotation.
1137 Bind(Box<Ident>, Option<Box<Ty>>),
1138 /// A discarded binding, `_`, with an optional type annotation.
1139 Discard(Option<Box<Ty>>),
1140 /// An elided pattern, `...`, used by specializations.
1141 Elided,
1142 /// Parentheses: `(a)`.
1143 Paren(Box<Pat>),
1144 /// A tuple: `(a, b, c)`.
1145 Tuple(Box<[Box<Pat>]>),
1146 /// An invalid pattern.
1147 #[default]
1148 Err,
1149}
1150
1151impl Display for PatKind {
1152 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1153 let mut indent = set_indentation(indented(f), 0);
1154 match self {
1155 PatKind::Bind(id, ty) => {
1156 write!(indent, "Bind:")?;
1157 indent = set_indentation(indent, 1);
1158 write!(indent, "\n{id}")?;
1159 if let Some(t) = ty {
1160 write!(indent, "\n{t}")?;
1161 }
1162 }
1163 PatKind::Discard(d) => match d {
1164 Some(t) => {
1165 write!(indent, "Discard:")?;
1166 indent = set_indentation(indent, 1);
1167 write!(indent, "\n{t}")?;
1168 }
1169 None => write!(indent, "Discard")?,
1170 },
1171 PatKind::Elided => write!(indent, "Elided")?,
1172 PatKind::Paren(p) => {
1173 write!(indent, "Paren:")?;
1174 indent = set_indentation(indent, 1);
1175 write!(indent, "\n{p}")?;
1176 }
1177 PatKind::Tuple(ps) => {
1178 if ps.is_empty() {
1179 write!(indent, "Unit")?;
1180 } else {
1181 write!(indent, "Tuple:")?;
1182 indent = set_indentation(indent, 1);
1183 for p in ps.iter() {
1184 write!(indent, "\n{p}")?;
1185 }
1186 }
1187 }
1188 PatKind::Err => write!(indent, "Err")?,
1189 }
1190 Ok(())
1191 }
1192}
1193
1194/// A qubit initializer.
1195#[derive(Clone, Debug, PartialEq, Default)]
1196pub struct QubitInit {
1197 /// The node ID.
1198 pub id: NodeId,
1199 /// The span.
1200 pub span: Span,
1201 /// The qubit initializer kind.
1202 pub kind: Box<QubitInitKind>,
1203}
1204
1205impl Display for QubitInit {
1206 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1207 write!(f, "QubitInit {} {} {}", self.id, self.span, self.kind)
1208 }
1209}
1210
1211impl WithSpan for QubitInit {
1212 fn with_span(self, span: Span) -> Self {
1213 Self { span, ..self }
1214 }
1215}
1216
1217/// A qubit initializer kind.
1218#[derive(Clone, Debug, PartialEq, Default)]
1219pub enum QubitInitKind {
1220 /// An array of qubits: `Qubit[a]`.
1221 Array(Box<Expr>),
1222 /// A parenthesized initializer: `(a)`.
1223 Paren(Box<QubitInit>),
1224 /// A single qubit: `Qubit()`.
1225 Single,
1226 /// A tuple: `(a, b, c)`.
1227 Tuple(Box<[Box<QubitInit>]>),
1228 /// An invalid initializer.
1229 #[default]
1230 Err,
1231}
1232
1233impl Display for QubitInitKind {
1234 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1235 let mut indent = set_indentation(indented(f), 0);
1236 match self {
1237 QubitInitKind::Array(e) => {
1238 write!(indent, "Array:")?;
1239 indent = set_indentation(indent, 1);
1240 write!(indent, "\n{e}")?;
1241 }
1242 QubitInitKind::Paren(qi) => {
1243 write!(indent, "Parens:")?;
1244 indent = set_indentation(indent, 1);
1245 write!(indent, "\n{qi}")?;
1246 }
1247 QubitInitKind::Single => write!(indent, "Single")?,
1248 QubitInitKind::Tuple(qis) => {
1249 if qis.is_empty() {
1250 write!(indent, "Unit")?;
1251 } else {
1252 write!(indent, "Tuple:")?;
1253 indent = set_indentation(indent, 1);
1254 for qi in qis.iter() {
1255 write!(indent, "\n{qi}")?;
1256 }
1257 }
1258 }
1259 QubitInitKind::Err => write!(indent, "Err")?,
1260 }
1261 Ok(())
1262 }
1263}
1264
1265/// A path to a declaration.
1266#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1267pub struct Path {
1268 /// The node ID.
1269 pub id: NodeId,
1270 /// The span.
1271 pub span: Span,
1272 /// The namespace.
1273 pub namespace: Option<Box<Ident>>,
1274 /// The declaration name.
1275 pub name: Box<Ident>,
1276}
1277
1278impl Display for Path {
1279 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1280 if let Some(ns) = &self.namespace {
1281 write!(f, "Path {} {} ({}) ({})", self.id, self.span, ns, self.name)?;
1282 } else {
1283 write!(f, "Path {} {} ({})", self.id, self.span, self.name)?;
1284 }
1285 Ok(())
1286 }
1287}
1288
1289impl WithSpan for Path {
1290 fn with_span(self, span: Span) -> Self {
1291 Self { span, ..self }
1292 }
1293}
1294
1295/// An identifier.
1296#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1297pub struct Ident {
1298 /// The node ID.
1299 pub id: NodeId,
1300 /// The span.
1301 pub span: Span,
1302 /// The identifier name.
1303 pub name: Rc<str>,
1304}
1305
1306impl Default for Ident {
1307 fn default() -> Self {
1308 Ident {
1309 id: NodeId::default(),
1310 span: Span::default(),
1311 name: "".into(),
1312 }
1313 }
1314}
1315
1316impl WithSpan for Ident {
1317 fn with_span(self, span: Span) -> Self {
1318 Self { span, ..self }
1319 }
1320}
1321
1322impl Display for Ident {
1323 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1324 write!(f, "Ident {} {} \"{}\"", self.id, self.span, self.name)
1325 }
1326}
1327
1328/// A declaration visibility kind.
1329#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1330pub enum VisibilityKind {
1331 /// Visible everywhere.
1332 Public,
1333 /// Visible within a package.
1334 Internal,
1335}
1336
1337/// A callable kind.
1338#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1339pub enum CallableKind {
1340 /// A function.
1341 Function,
1342 /// An operation.
1343 Operation,
1344}
1345
1346/// The mutability of a binding.
1347#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1348pub enum Mutability {
1349 /// An immutable binding.
1350 Immutable,
1351 /// A mutable binding.
1352 Mutable,
1353}
1354
1355/// The source of an allocated qubit.
1356#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1357pub enum QubitSource {
1358 /// A qubit initialized to the zero state.
1359 Fresh,
1360 /// A qubit borrowed from another part of the program that may be in any state, and is expected
1361 /// to be returned to that state before being released.
1362 Dirty,
1363}
1364
1365/// A literal.
1366#[derive(Clone, Debug, PartialEq)]
1367pub enum Lit {
1368 /// A big integer literal.
1369 BigInt(Box<BigInt>),
1370 /// A boolean literal.
1371 Bool(bool),
1372 /// A floating-point literal.
1373 Double(f64),
1374 /// An integer literal.
1375 Int(i64),
1376 /// A Pauli operator literal.
1377 Pauli(Pauli),
1378 /// A measurement result literal.
1379 Result(Result),
1380 /// A string literal.
1381 String(Rc<str>),
1382}
1383
1384impl Display for Lit {
1385 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1386 match self {
1387 Lit::BigInt(val) => write!(f, "BigInt({val})")?,
1388 Lit::Bool(val) => write!(f, "Bool({val})")?,
1389 Lit::Double(val) => write!(f, "Double({val})")?,
1390 Lit::Int(val) => write!(f, "Int({val})")?,
1391 Lit::Pauli(val) => write!(f, "Pauli({val:?})")?,
1392 Lit::Result(val) => write!(f, "Result({val:?})")?,
1393 Lit::String(val) => write!(f, "String({val:?})")?,
1394 }
1395 Ok(())
1396 }
1397}
1398
1399/// A measurement result.
1400#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1401pub enum Result {
1402 /// The zero eigenvalue.
1403 Zero,
1404 /// The one eigenvalue.
1405 One,
1406}
1407
1408/// A Pauli operator.
1409#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1410pub enum Pauli {
1411 /// The Pauli I operator.
1412 I,
1413 /// The Pauli X operator.
1414 X,
1415 /// The Pauli Y operator.
1416 Y,
1417 /// The Pauli Z operator.
1418 Z,
1419}
1420
1421/// A functor that may be applied to an operation.
1422#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1423pub enum Functor {
1424 /// The adjoint functor.
1425 Adj,
1426 /// The controlled functor.
1427 Ctl,
1428}
1429
1430/// A specialization that may be implemented for an operation.
1431#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1432pub enum Spec {
1433 /// The default specialization.
1434 Body,
1435 /// The adjoint specialization.
1436 Adj,
1437 /// The controlled specialization.
1438 Ctl,
1439 /// The controlled adjoint specialization.
1440 CtlAdj,
1441}
1442
1443impl Display for Spec {
1444 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1445 match self {
1446 Spec::Body => f.write_str("body"),
1447 Spec::Adj => f.write_str("adjoint"),
1448 Spec::Ctl => f.write_str("controlled"),
1449 Spec::CtlAdj => f.write_str("controlled adjoint"),
1450 }
1451 }
1452}
1453
1454/// A strategy for generating a specialization.
1455#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1456pub enum SpecGen {
1457 /// Choose a strategy automatically.
1458 Auto,
1459 /// Distributes controlled qubits.
1460 Distribute,
1461 /// A specialization implementation is not generated, but is instead left as an opaque
1462 /// declaration.
1463 Intrinsic,
1464 /// Inverts the order of operations.
1465 Invert,
1466 /// Uses the body specialization without modification.
1467 Slf,
1468}
1469
1470/// A unary operator.
1471#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1472pub enum UnOp {
1473 /// A functor application.
1474 Functor(Functor),
1475 /// Negation: `-`.
1476 Neg,
1477 /// Bitwise NOT: `~~~`.
1478 NotB,
1479 /// Logical NOT: `not`.
1480 NotL,
1481 /// A leading `+`.
1482 Pos,
1483 /// Unwrap a user-defined type: `!`.
1484 Unwrap,
1485}
1486
1487impl Display for UnOp {
1488 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1489 match self {
1490 UnOp::Functor(func) => write!(f, "Functor {func:?}")?,
1491 _ => fmt::Debug::fmt(self, f)?,
1492 }
1493 Ok(())
1494 }
1495}
1496
1497/// A binary operator.
1498#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1499pub enum BinOp {
1500 /// Addition: `+`.
1501 Add,
1502 /// Bitwise AND: `&&&`.
1503 AndB,
1504 /// Logical AND: `and`.
1505 AndL,
1506 /// Division: `/`.
1507 Div,
1508 /// Equality: `==`.
1509 Eq,
1510 /// Exponentiation: `^`.
1511 Exp,
1512 /// Greater than: `>`.
1513 Gt,
1514 /// Greater than or equal: `>=`.
1515 Gte,
1516 /// Less than: `<`.
1517 Lt,
1518 /// Less than or equal: `<=`.
1519 Lte,
1520 /// Modulus: `%`.
1521 Mod,
1522 /// Multiplication: `*`.
1523 Mul,
1524 /// Inequality: `!=`.
1525 Neq,
1526 /// Bitwise OR: `|||`.
1527 OrB,
1528 /// Logical OR: `or`.
1529 OrL,
1530 /// Shift left: `<<<`.
1531 Shl,
1532 /// Shift right: `>>>`.
1533 Shr,
1534 /// Subtraction: `-`.
1535 Sub,
1536 /// Bitwise XOR: `^^^`.
1537 XorB,
1538}
1539
1540/// A ternary operator.
1541#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1542pub enum TernOp {
1543 /// Conditional: `a ? b | c`.
1544 Cond,
1545 /// Aggregate update: `a w/ b <- c`.
1546 Update,
1547}
1548
1549/// A set operator.
1550#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1551pub enum SetOp {
1552 /// The set union.
1553 Union,
1554 /// The set intersection.
1555 Intersect,
1556}
1557