microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/second-api-refactor

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/ast.rs

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