microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/replace-qsharp-with-qdk-python-tests

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc_ast/src/ast.rs

2156lines · 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::{Format, Indented, 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 iter::once,
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!("indentation 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: Box<[Ident]>,
169 /// The items in the namespace.
170 pub items: Box<[Box<Item>]>,
171 /// The namespace kind.
172 pub kind: NamespaceKind,
173}
174
175/// A namespace kind.
176#[derive(Clone, Copy, Debug, PartialEq)]
177pub enum NamespaceKind {
178 /// An implicit namespace.
179 Implicit,
180 /// An explicit namespace block.
181 Block,
182}
183
184impl Namespace {
185 /// Returns an iterator over the items in the namespace that are exported.
186 pub fn exports(&self) -> impl Iterator<Item = &ImportOrExportItem> {
187 self.items.iter().flat_map(|i| match i.kind.as_ref() {
188 ItemKind::ImportOrExport(decl) if decl.is_export() => &decl.items[..],
189 _ => &[],
190 })
191 }
192}
193
194impl Display for Namespace {
195 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
196 let mut indent = set_indentation(indented(f), 0);
197 write!(indent, "Namespace {} {} (", self.id, self.span)?;
198
199 let mut buf = Vec::with_capacity(self.name.len());
200
201 for ident in &self.name {
202 buf.push(format!("{ident}"));
203 }
204 if buf.len() > 1 {
205 // use square brackets only if there are more than one ident
206 write!(indent, "[{}]", buf.join(", "))?;
207 } else {
208 write!(indent, "{}", buf[0])?;
209 }
210
211 write!(indent, "):",)?;
212 indent = set_indentation(indent, 1);
213
214 if !self.doc.is_empty() {
215 write!(indent, "\ndoc:")?;
216 indent = set_indentation(indent, 2);
217 write!(indent, "\n{}", self.doc)?;
218 indent = set_indentation(indent, 1);
219 }
220
221 for i in &self.items {
222 write!(indent, "\n{i}")?;
223 }
224
225 Ok(())
226 }
227}
228
229/// An item.
230#[derive(Clone, Debug, PartialEq)]
231pub struct Item {
232 /// The ID.
233 pub id: NodeId,
234 /// The span.
235 pub span: Span,
236 /// The documentation.
237 pub doc: Rc<str>,
238 /// The attributes.
239 pub attrs: Box<[Box<Attr>]>,
240 /// The item kind.
241 pub kind: Box<ItemKind>,
242}
243
244impl Default for Item {
245 fn default() -> Self {
246 Self {
247 id: NodeId::default(),
248 span: Span::default(),
249 doc: "".into(),
250 attrs: Box::default(),
251 kind: Box::default(),
252 }
253 }
254}
255
256impl Display for Item {
257 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
258 let mut indent = set_indentation(indented(f), 0);
259 write!(indent, "Item {} {}:", self.id, self.span)?;
260 indent = set_indentation(indent, 1);
261
262 if !self.doc.is_empty() {
263 write!(indent, "\ndoc:")?;
264 indent = set_indentation(indent, 2);
265 write!(indent, "\n{}", self.doc)?;
266 indent = set_indentation(indent, 1);
267 }
268
269 for attr in &self.attrs {
270 write!(indent, "\n{attr}")?;
271 }
272
273 write!(indent, "\n{}", self.kind)?;
274 Ok(())
275 }
276}
277
278/// An item kind.
279#[derive(Clone, Debug, Default, PartialEq)]
280pub enum ItemKind {
281 /// A `function` or `operation` declaration.
282 Callable(Box<CallableDecl>),
283 /// Default item when nothing has been parsed.
284 #[default]
285 Err,
286 /// An `open` item for a namespace with an optional alias.
287 Open(PathKind, Option<Box<Ident>>),
288 /// A `newtype` declaration.
289 Ty(Box<Ident>, Box<TyDef>),
290 /// A `struct` declaration.
291 Struct(Box<StructDecl>),
292 /// An export declaration
293 ImportOrExport(ImportOrExportDecl),
294}
295
296impl Display for ItemKind {
297 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
298 match &self {
299 ItemKind::Callable(decl) => write!(f, "{decl}")?,
300 ItemKind::Err => write!(f, "Err")?,
301 ItemKind::Open(name, alias) => match alias {
302 Some(a) => write!(f, "Open ({name}) ({a})")?,
303 None => write!(f, "Open ({name})")?,
304 },
305 ItemKind::Ty(name, t) => write!(f, "New Type ({name}): {t}")?,
306 ItemKind::Struct(s) => write!(f, "{s}")?,
307 ItemKind::ImportOrExport(item) => write!(f, "{item}")?,
308 }
309 Ok(())
310 }
311}
312
313/// An attribute.
314#[derive(Clone, Debug, PartialEq)]
315pub struct Attr {
316 /// The node ID.
317 pub id: NodeId,
318 /// The span.
319 pub span: Span,
320 /// The name of the attribute.
321 pub name: Box<Ident>,
322 /// The argument to the attribute.
323 pub arg: Box<Expr>,
324}
325
326impl Display for Attr {
327 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
328 let mut indent = set_indentation(indented(f), 0);
329 write!(indent, "Attr {} {} ({}):", self.id, self.span, self.name)?;
330 indent = set_indentation(indent, 1);
331 write!(indent, "\n{}", self.arg)?;
332 Ok(())
333 }
334}
335
336/// A type definition.
337#[derive(Clone, Debug, PartialEq, Default)]
338pub struct TyDef {
339 /// The node ID.
340 pub id: NodeId,
341 /// The span.
342 pub span: Span,
343 /// The type definition kind.
344 pub kind: Box<TyDefKind>,
345}
346
347impl TyDef {
348 /// Returns true if the type definition satisfies the conditions for a struct.
349 /// Conditions for a struct are that the `TyDef` is a tuple with all its top-level fields named.
350 /// Otherwise, returns false.
351 #[must_use]
352 pub fn is_struct(&self) -> bool {
353 match self.kind.as_ref() {
354 TyDefKind::Paren(inner) => inner.is_struct(),
355 TyDefKind::Tuple(fields) => fields
356 .iter()
357 .all(|field| matches!(field.kind.as_ref(), TyDefKind::Field(Some(_), _, _))),
358 TyDefKind::Err | TyDefKind::Field(..) => false,
359 }
360 }
361}
362
363impl Display for TyDef {
364 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
365 write!(f, "TyDef {} {}: {}", self.id, self.span, self.kind)
366 }
367}
368
369impl WithSpan for TyDef {
370 fn with_span(self, span: Span) -> Self {
371 Self { span, ..self }
372 }
373}
374
375/// A type definition kind.
376#[derive(Clone, Debug, PartialEq, Default)]
377pub enum TyDefKind {
378 /// A field definition with an optional name but required type.
379 /// Additionally, may include documentation for the field.
380 Field(Option<Box<Ident>>, Box<Ty>, Option<Rc<str>>),
381 /// A parenthesized type definition.
382 Paren(Box<TyDef>),
383 /// A tuple.
384 Tuple(Box<[Box<TyDef>]>),
385 /// An invalid type definition.
386 #[default]
387 Err,
388}
389
390impl Display for TyDefKind {
391 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
392 let mut indent = set_indentation(indented(f), 0);
393 match &self {
394 TyDefKind::Field(name, t, doc) => {
395 write!(indent, "Field:")?;
396 indent = set_indentation(indent, 1);
397 if let Some(n) = name {
398 write!(indent, "\nName: {n}")?;
399 }
400 write!(indent, "\nType: {t}")?;
401 if let Some(d) = doc {
402 write!(indent, "\nDoc: {d}")?;
403 }
404 }
405 TyDefKind::Paren(t) => {
406 write!(indent, "Paren:")?;
407 indent = set_indentation(indent, 1);
408 write!(indent, "\n{t}")?;
409 }
410 TyDefKind::Tuple(ts) => {
411 if ts.is_empty() {
412 write!(indent, "Unit")?;
413 } else {
414 write!(indent, "Tuple:")?;
415 indent = set_indentation(indent, 1);
416 for t in ts {
417 write!(indent, "\n{t}")?;
418 }
419 }
420 }
421 TyDefKind::Err => write!(indent, "Err")?,
422 }
423 Ok(())
424 }
425}
426
427/// A struct definition.
428#[derive(Clone, Debug, PartialEq, Default)]
429pub struct StructDecl {
430 /// The node ID.
431 pub id: NodeId,
432 /// The span.
433 pub span: Span,
434 /// The name of the struct.
435 pub name: Box<Ident>,
436 /// The type definition kind.
437 pub fields: Box<[Box<FieldDef>]>,
438}
439
440impl Display for StructDecl {
441 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
442 let mut indent = set_indentation(indented(f), 0);
443 write!(indent, "Struct {} {} ({}):", self.id, self.span, self.name)?;
444 if self.fields.is_empty() {
445 write!(indent, " <empty>")?;
446 } else {
447 indent = set_indentation(indent, 1);
448 for field in &self.fields {
449 write!(indent, "\n{field}")?;
450 }
451 }
452 Ok(())
453 }
454}
455
456impl WithSpan for StructDecl {
457 fn with_span(self, span: Span) -> Self {
458 Self { span, ..self }
459 }
460}
461
462/// A struct field definition.
463#[derive(Clone, Debug, PartialEq, Default)]
464pub struct FieldDef {
465 /// The node ID.
466 pub id: NodeId,
467 /// The span.
468 pub span: Span,
469 /// The documentation.
470 pub doc: Option<Rc<str>>,
471 /// The name of the field.
472 pub name: Box<Ident>,
473 /// The type of the field.
474 pub ty: Box<Ty>,
475}
476
477impl Display for FieldDef {
478 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
479 let mut indent = set_indentation(indented(f), 0);
480 write!(
481 indent,
482 "FieldDef {} {} ({}): {}",
483 self.id, self.span, self.name, self.ty
484 )?;
485 if let Some(doc) = &self.doc {
486 indent = set_indentation(indent, 1);
487 write!(indent, "\nDoc: {doc}")?;
488 }
489 Ok(())
490 }
491}
492
493impl WithSpan for FieldDef {
494 fn with_span(self, span: Span) -> Self {
495 Self { span, ..self }
496 }
497}
498
499/// A callable declaration header.
500#[derive(Clone, Debug, PartialEq)]
501pub struct CallableDecl {
502 /// The node ID.
503 pub id: NodeId,
504 /// The span.
505 pub span: Span,
506 /// The callable kind.
507 pub kind: CallableKind,
508 /// The name of the callable.
509 pub name: Box<Ident>,
510 /// The generic parameters to the callable.
511 pub generics: Box<[TypeParameter]>,
512 /// The input to the callable.
513 pub input: Box<Pat>,
514 /// The return type of the callable.
515 pub output: Box<Ty>,
516 /// The functors supported by the callable.
517 pub functors: Option<Box<FunctorExpr>>,
518 /// The body of the callable.
519 pub body: Box<CallableBody>,
520}
521
522impl Display for CallableDecl {
523 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
524 let mut indent = set_indentation(indented(f), 0);
525 write!(
526 indent,
527 "Callable {} {} ({:?}):",
528 self.id, self.span, self.kind
529 )?;
530 indent = set_indentation(indent, 1);
531 write!(indent, "\nname: {}", self.name)?;
532 if !self.generics.is_empty() {
533 write!(indent, "\ngenerics:")?;
534 indent = set_indentation(indent, 2);
535 let mut buf = Vec::with_capacity(self.generics.len());
536 for param in &self.generics {
537 buf.push(format!("{param}"));
538 }
539
540 let buf = buf.join(",\n");
541 write!(indent, "\n{buf}")?;
542 indent = set_indentation(indent, 1);
543 }
544 write!(indent, "\ninput: {}", self.input)?;
545 write!(indent, "\noutput: {}", self.output)?;
546 if let Some(f) = &self.functors {
547 write!(indent, "\nfunctors: {}", f.as_ref())?;
548 }
549 write!(indent, "\nbody: {}", self.body)?;
550 Ok(())
551 }
552}
553
554/// The body of a callable.
555#[derive(Clone, Debug, PartialEq)]
556pub enum CallableBody {
557 /// A block for the callable's body specialization.
558 Block(Box<Block>),
559 /// One or more explicit specializations.
560 Specs(Box<[Box<SpecDecl>]>),
561}
562
563impl Display for CallableBody {
564 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
565 match self {
566 CallableBody::Block(body) => write!(f, "Block: {body}")?,
567 CallableBody::Specs(specs) => {
568 let mut indent = set_indentation(indented(f), 0);
569 write!(indent, "Specializations:")?;
570 indent = set_indentation(indent, 1);
571 for spec in specs {
572 write!(indent, "\n{spec}")?;
573 }
574 }
575 }
576 Ok(())
577 }
578}
579
580/// A specialization declaration.
581#[derive(Clone, Debug, PartialEq)]
582pub struct SpecDecl {
583 /// The node ID.
584 pub id: NodeId,
585 /// The span.
586 pub span: Span,
587 /// Which specialization is being declared.
588 pub spec: Spec,
589 /// The body of the specialization.
590 pub body: SpecBody,
591}
592
593impl Display for SpecDecl {
594 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
595 write!(
596 f,
597 "SpecDecl {} {} ({:?}): {}",
598 self.id, self.span, self.spec, self.body
599 )
600 }
601}
602
603/// The body of a specialization.
604#[derive(Clone, Debug, PartialEq)]
605pub enum SpecBody {
606 /// The strategy to use to automatically generate the specialization.
607 Gen(SpecGen),
608 /// A manual implementation of the specialization.
609 Impl(Box<Pat>, Box<Block>),
610}
611
612impl Display for SpecBody {
613 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
614 let mut indent = set_indentation(indented(f), 0);
615 match self {
616 SpecBody::Gen(sg) => write!(indent, "Gen: {sg:?}")?,
617 SpecBody::Impl(p, b) => {
618 write!(indent, "Impl:")?;
619 indent = set_indentation(indent, 1);
620 write!(indent, "\n{p}")?;
621 write!(indent, "\n{b}")?;
622 }
623 }
624 Ok(())
625 }
626}
627
628/// An expression that describes a set of functors.
629#[derive(Clone, Debug, Eq, Hash, PartialEq)]
630pub struct FunctorExpr {
631 /// The node ID.
632 pub id: NodeId,
633 /// The span.
634 pub span: Span,
635 /// The functor expression kind.
636 pub kind: Box<FunctorExprKind>,
637}
638
639impl Display for FunctorExpr {
640 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
641 write!(f, "Functor Expr {} {}: {}", self.id, self.span, self.kind)
642 }
643}
644
645/// A functor expression kind.
646#[derive(Clone, Debug, Eq, Hash, PartialEq)]
647pub enum FunctorExprKind {
648 /// A binary operation.
649 BinOp(SetOp, Box<FunctorExpr>, Box<FunctorExpr>),
650 /// A literal for a specific functor.
651 Lit(Functor),
652 /// A parenthesized group.
653 Paren(Box<FunctorExpr>),
654}
655
656impl Display for FunctorExprKind {
657 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
658 match self {
659 FunctorExprKind::BinOp(op, l, r) => write!(f, "BinOp {op:?}: ({l}) ({r})"),
660 FunctorExprKind::Lit(func) => write!(f, "{func:?}"),
661 FunctorExprKind::Paren(func) => write!(f, "Paren: {func}"),
662 }
663 }
664}
665
666/// A type.
667#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
668pub struct Ty {
669 /// The node ID.
670 pub id: NodeId,
671 /// The span.
672 pub span: Span,
673 /// The type kind.
674 pub kind: Box<TyKind>,
675}
676
677impl Display for Ty {
678 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
679 write!(f, "Type {} {}: {}", self.id, self.span, self.kind)
680 }
681}
682
683impl WithSpan for Ty {
684 fn with_span(self, span: Span) -> Self {
685 Self { span, ..self }
686 }
687}
688
689/// A type kind.
690#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
691pub enum TyKind {
692 /// An array type.
693 Array(Box<Ty>),
694 /// An arrow type: `->` for a function or `=>` for an operation.
695 Arrow(CallableKind, Box<Ty>, Box<Ty>, Option<Box<FunctorExpr>>),
696 /// An unspecified type, `_`, which may be inferred.
697 Hole,
698 /// A type wrapped in parentheses.
699 Paren(Box<Ty>),
700 /// A named type.
701 Path(PathKind),
702 /// A type parameter.
703 Param(TypeParameter),
704 /// A tuple type.
705 Tuple(Box<[Ty]>),
706 /// An invalid type.
707 #[default]
708 Err,
709}
710
711impl Display for TyKind {
712 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
713 let mut indent = set_indentation(indented(f), 0);
714 match self {
715 TyKind::Array(item) => write!(indent, "Array: {item}")?,
716 TyKind::Arrow(ck, param, rtrn, functors) => {
717 write!(indent, "Arrow ({ck:?}):")?;
718 indent = set_indentation(indent, 1);
719 write!(indent, "\nparam: {param}")?;
720 write!(indent, "\nreturn: {rtrn}")?;
721 if let Some(f) = functors {
722 write!(indent, "\nfunctors: {f}")?;
723 }
724 }
725 TyKind::Hole => write!(indent, "Hole")?,
726 TyKind::Paren(t) => write!(indent, "Paren: {t}")?,
727 TyKind::Path(p) => write!(indent, "Path: {p}")?,
728 TyKind::Param(name) => write!(indent, "Type Param: {name}")?,
729 TyKind::Tuple(ts) => {
730 if ts.is_empty() {
731 write!(indent, "Unit")?;
732 } else {
733 write!(indent, "Tuple:")?;
734 indent = indent.with_format(Format::Uniform {
735 indentation: " ",
736 });
737 for t in ts {
738 write!(indent, "\n{t}")?;
739 }
740 }
741 }
742 TyKind::Err => write!(indent, "Err")?,
743 }
744 Ok(())
745 }
746}
747
748/// A sequenced block of statements.
749#[derive(Clone, Debug, PartialEq)]
750pub struct Block {
751 /// The node ID.
752 pub id: NodeId,
753 /// The span.
754 pub span: Span,
755 /// The statements in the block.
756 pub stmts: Box<[Box<Stmt>]>,
757}
758
759impl Display for Block {
760 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
761 if self.stmts.is_empty() {
762 write!(f, "Block {} {}: <empty>", self.id, self.span)?;
763 } else {
764 let mut indent = set_indentation(indented(f), 0);
765 write!(indent, "Block {} {}:", self.id, self.span)?;
766 indent = set_indentation(indent, 1);
767 for s in &self.stmts {
768 write!(indent, "\n{s}")?;
769 }
770 }
771 Ok(())
772 }
773}
774
775/// A statement.
776#[derive(Clone, Debug, Default, PartialEq)]
777pub struct Stmt {
778 /// The node ID.
779 pub id: NodeId,
780 /// The span.
781 pub span: Span,
782 /// The statement kind.
783 pub kind: Box<StmtKind>,
784}
785
786impl Display for Stmt {
787 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
788 write!(f, "Stmt {} {}: {}", self.id, self.span, self.kind)
789 }
790}
791
792/// A statement kind.
793#[derive(Clone, Debug, Default, PartialEq)]
794pub enum StmtKind {
795 /// An empty statement.
796 Empty,
797 /// An expression without a trailing semicolon.
798 Expr(Box<Expr>),
799 /// A let or mutable binding: `let a = b;` or `mutable x = b;`.
800 Local(Mutability, Box<Pat>, Box<Expr>),
801 /// An item.
802 Item(Box<Item>),
803 /// A use or borrow qubit allocation: `use a = b;` or `borrow a = b;`.
804 Qubit(QubitSource, Box<Pat>, Box<QubitInit>, Option<Box<Block>>),
805 /// An expression with a trailing semicolon.
806 Semi(Box<Expr>),
807 /// An invalid statement.
808 #[default]
809 Err,
810}
811
812impl Display for StmtKind {
813 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
814 let mut indent = set_indentation(indented(f), 0);
815 match self {
816 StmtKind::Empty => write!(indent, "Empty")?,
817 StmtKind::Expr(e) => write!(indent, "Expr: {e}")?,
818 StmtKind::Item(item) => write!(indent, "Item: {item}")?,
819 StmtKind::Local(m, lhs, rhs) => {
820 write!(indent, "Local ({m:?}):")?;
821 indent = set_indentation(indent, 1);
822 write!(indent, "\n{lhs}")?;
823 write!(indent, "\n{rhs}")?;
824 }
825 StmtKind::Qubit(s, lhs, rhs, block) => {
826 write!(indent, "Qubit ({s:?})")?;
827 indent = set_indentation(indent, 1);
828 write!(indent, "\n{lhs}")?;
829 write!(indent, "\n{rhs}")?;
830 if let Some(b) = block {
831 write!(indent, "\n{b}")?;
832 }
833 }
834 StmtKind::Semi(e) => write!(indent, "Semi: {e}")?,
835 StmtKind::Err => indent.write_str("Err")?,
836 }
837 Ok(())
838 }
839}
840
841/// An expression.
842#[derive(Clone, Debug, Default, PartialEq)]
843pub struct Expr {
844 /// The node ID.
845 pub id: NodeId,
846 /// The span.
847 pub span: Span,
848 /// The expression kind.
849 pub kind: Box<ExprKind>,
850}
851
852impl Display for Expr {
853 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
854 write!(f, "Expr {} {}: {}", self.id, self.span, self.kind)
855 }
856}
857
858impl WithSpan for Expr {
859 fn with_span(self, span: Span) -> Self {
860 Self { span, ..self }
861 }
862}
863
864/// The identifier in a field access expression.
865#[derive(Clone, Debug, Default, PartialEq)]
866pub enum FieldAccess {
867 /// The field name.
868 Ok(Box<Ident>),
869 /// The field access was missing a field name.
870 #[default]
871 Err,
872}
873
874/// An expression kind.
875#[derive(Clone, Debug, Default, PartialEq)]
876pub enum ExprKind {
877 /// An array: `[a, b, c]`.
878 Array(Box<[Box<Expr>]>),
879 /// An array constructed by repeating a value: `[a, size = b]`.
880 ArrayRepeat(Box<Expr>, Box<Expr>),
881 /// An assignment: `set a = b`.
882 Assign(Box<Expr>, Box<Expr>),
883 /// An assignment with a compound operator. For example: `set a += b`.
884 AssignOp(BinOp, Box<Expr>, Box<Expr>),
885 /// An assignment with a compound update operator: `set a w/= b <- c`.
886 AssignUpdate(Box<Expr>, Box<Expr>, Box<Expr>),
887 /// A binary operator.
888 BinOp(BinOp, Box<Expr>, Box<Expr>),
889 /// A block: `{ ... }`.
890 Block(Box<Block>),
891 /// A call: `a(b)`.
892 Call(Box<Expr>, Box<Expr>),
893 /// A conjugation: `within { ... } apply { ... }`.
894 Conjugate(Box<Block>, Box<Block>),
895 /// An expression with invalid syntax that can't be parsed.
896 #[default]
897 Err,
898 /// A failure: `fail "message"`.
899 Fail(Box<Expr>),
900 /// A field accessor: `a::F` or `a.F`.
901 Field(Box<Expr>, FieldAccess),
902 /// A for loop: `for a in b { ... }`.
903 For(Box<Pat>, Box<Expr>, Box<Block>),
904 /// An unspecified expression, _, which may indicate partial application or a typed hole.
905 Hole,
906 /// An if expression with an optional else block: `if a { ... } else { ... }`.
907 ///
908 /// Note that, as a special case, `elif ...` is effectively parsed as `else if ...`, without a
909 /// block wrapping the `if`. This distinguishes `elif ...` from `else { if ... }`, which does
910 /// have a block.
911 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
912 /// An index accessor: `a[b]`.
913 Index(Box<Expr>, Box<Expr>),
914 /// An interpolated string.
915 Interpolate(Box<[StringComponent]>),
916 /// A lambda: `a -> b` for a function and `a => b` for an operation.
917 Lambda(CallableKind, Box<Pat>, Box<Expr>),
918 /// A literal.
919 Lit(Box<Lit>),
920 /// Parentheses: `(a)`.
921 Paren(Box<Expr>),
922 /// A path: `a` or `a.b`.
923 Path(PathKind),
924 /// A range: `start..step..end`, `start..end`, `start...`, `...end`, or `...`.
925 Range(Option<Box<Expr>>, Option<Box<Expr>>, Option<Box<Expr>>),
926 /// A repeat-until loop with an optional fixup: `repeat { ... } until a fixup { ... }`.
927 Repeat(Box<Block>, Box<Expr>, Option<Box<Block>>),
928 /// A return: `return a`.
929 Return(Box<Expr>),
930 /// A struct constructor.
931 Struct(PathKind, Option<Box<Expr>>, Box<[Box<FieldAssign>]>),
932 /// A ternary operator.
933 TernOp(TernOp, Box<Expr>, Box<Expr>, Box<Expr>),
934 /// A tuple: `(a, b, c)`.
935 Tuple(Box<[Box<Expr>]>),
936 /// A unary operator.
937 UnOp(UnOp, Box<Expr>),
938 /// A while loop: `while a { ... }`.
939 While(Box<Expr>, Box<Block>),
940}
941
942impl Display for ExprKind {
943 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
944 let mut indent = set_indentation(indented(f), 0);
945 match self {
946 ExprKind::Array(exprs) => display_array(indent, exprs)?,
947 ExprKind::ArrayRepeat(val, size) => display_array_repeat(indent, val, size)?,
948 ExprKind::Assign(lhs, rhs) => display_assign(indent, lhs, rhs)?,
949 ExprKind::AssignOp(op, lhs, rhs) => display_assign_op(indent, *op, lhs, rhs)?,
950 ExprKind::AssignUpdate(container, item, val) => {
951 display_assign_update(indent, container, item, val)?;
952 }
953 ExprKind::BinOp(op, lhs, rhs) => display_bin_op(indent, *op, lhs, rhs)?,
954 ExprKind::Block(block) => write!(indent, "Expr Block: {block}")?,
955 ExprKind::Call(callable, arg) => display_call(indent, callable, arg)?,
956 ExprKind::Conjugate(within, apply) => display_conjugate(indent, within, apply)?,
957 ExprKind::Err => write!(indent, "Err")?,
958 ExprKind::Fail(e) => write!(indent, "Fail: {e}")?,
959 ExprKind::Field(expr, id) => display_field(indent, expr, id)?,
960 ExprKind::For(iter, iterable, body) => display_for(indent, iter, iterable, body)?,
961 ExprKind::Hole => write!(indent, "Hole")?,
962 ExprKind::If(cond, body, els) => display_if(indent, cond, body, els.as_deref())?,
963 ExprKind::Index(array, index) => display_index(indent, array, index)?,
964 ExprKind::Interpolate(components) => display_interpolate(indent, components)?,
965 ExprKind::Lambda(kind, param, expr) => display_lambda(indent, *kind, param, expr)?,
966 ExprKind::Lit(lit) => write!(indent, "Lit: {lit}")?,
967 ExprKind::Paren(e) => write!(indent, "Paren: {e}")?,
968 ExprKind::Path(p) => write!(indent, "Path: {p}")?,
969 ExprKind::Range(start, step, end) => {
970 display_range(indent, start.as_deref(), step.as_deref(), end.as_deref())?;
971 }
972 ExprKind::Repeat(repeat, until, fixup) => {
973 display_repeat(indent, repeat, until, fixup.as_deref())?;
974 }
975 ExprKind::Return(e) => write!(indent, "Return: {e}")?,
976 ExprKind::Struct(name, copy, fields) => {
977 display_struct(indent, name, copy.as_deref(), fields)?;
978 }
979 ExprKind::TernOp(op, expr1, expr2, expr3) => {
980 display_tern_op(indent, *op, expr1, expr2, expr3)?;
981 }
982 ExprKind::Tuple(exprs) => display_tuple(indent, exprs)?,
983 ExprKind::UnOp(op, expr) => display_un_op(indent, *op, expr)?,
984 ExprKind::While(cond, block) => display_while(indent, cond, block)?,
985 }
986 Ok(())
987 }
988}
989
990fn display_array(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
991 write!(indent, "Array:")?;
992 indent = set_indentation(indent, 1);
993 for e in exprs {
994 write!(indent, "\n{e}")?;
995 }
996 Ok(())
997}
998
999fn display_array_repeat(mut indent: Indented<Formatter>, val: &Expr, size: &Expr) -> fmt::Result {
1000 write!(indent, "ArrayRepeat:")?;
1001 indent = set_indentation(indent, 1);
1002 write!(indent, "\n{val}")?;
1003 write!(indent, "\n{size}")?;
1004 Ok(())
1005}
1006
1007fn display_assign(mut indent: Indented<Formatter>, lhs: &Expr, rhs: &Expr) -> fmt::Result {
1008 write!(indent, "Assign:")?;
1009 indent = set_indentation(indent, 1);
1010 write!(indent, "\n{lhs}")?;
1011 write!(indent, "\n{rhs}")?;
1012 Ok(())
1013}
1014
1015fn display_assign_op(
1016 mut indent: Indented<Formatter>,
1017 op: BinOp,
1018 lhs: &Expr,
1019 rhs: &Expr,
1020) -> fmt::Result {
1021 write!(indent, "AssignOp ({op:?}):")?;
1022 indent = set_indentation(indent, 1);
1023 write!(indent, "\n{lhs}")?;
1024 write!(indent, "\n{rhs}")?;
1025 Ok(())
1026}
1027
1028fn display_assign_update(
1029 mut indent: Indented<Formatter>,
1030 container: &Expr,
1031 item: &Expr,
1032 val: &Expr,
1033) -> fmt::Result {
1034 write!(indent, "AssignUpdate:")?;
1035 indent = set_indentation(indent, 1);
1036 write!(indent, "\n{container}")?;
1037 write!(indent, "\n{item}")?;
1038 write!(indent, "\n{val}")?;
1039 Ok(())
1040}
1041
1042fn display_bin_op(
1043 mut indent: Indented<Formatter>,
1044 op: BinOp,
1045 lhs: &Expr,
1046 rhs: &Expr,
1047) -> fmt::Result {
1048 write!(indent, "BinOp ({op:?}):")?;
1049 indent = set_indentation(indent, 1);
1050 write!(indent, "\n{lhs}")?;
1051 write!(indent, "\n{rhs}")?;
1052 Ok(())
1053}
1054
1055fn display_call(mut indent: Indented<Formatter>, callable: &Expr, arg: &Expr) -> fmt::Result {
1056 write!(indent, "Call:")?;
1057 indent = set_indentation(indent, 1);
1058 write!(indent, "\n{callable}")?;
1059 write!(indent, "\n{arg}")?;
1060 Ok(())
1061}
1062
1063fn display_conjugate(
1064 mut indent: Indented<Formatter>,
1065 within: &Block,
1066 apply: &Block,
1067) -> fmt::Result {
1068 write!(indent, "Conjugate:")?;
1069 indent = set_indentation(indent, 1);
1070 write!(indent, "\n{within}")?;
1071 write!(indent, "\n{apply}")?;
1072 Ok(())
1073}
1074
1075fn display_field(mut indent: Indented<Formatter>, expr: &Expr, field: &FieldAccess) -> fmt::Result {
1076 write!(indent, "Field:")?;
1077 indent = set_indentation(indent, 1);
1078 write!(indent, "\n{expr}")?;
1079 match field {
1080 FieldAccess::Ok(i) => write!(indent, "\n{i}")?,
1081 FieldAccess::Err => write!(indent, "\nErr")?,
1082 }
1083 Ok(())
1084}
1085
1086fn display_for(
1087 mut indent: Indented<Formatter>,
1088 iter: &Pat,
1089 iterable: &Expr,
1090 body: &Block,
1091) -> fmt::Result {
1092 write!(indent, "For:")?;
1093 indent = set_indentation(indent, 1);
1094 write!(indent, "\n{iter}")?;
1095 write!(indent, "\n{iterable}")?;
1096 write!(indent, "\n{body}")?;
1097 Ok(())
1098}
1099
1100fn display_if(
1101 mut indent: Indented<Formatter>,
1102 cond: &Expr,
1103 body: &Block,
1104 els: Option<&Expr>,
1105) -> fmt::Result {
1106 write!(indent, "If:")?;
1107 indent = set_indentation(indent, 1);
1108 write!(indent, "\n{cond}")?;
1109 write!(indent, "\n{body}")?;
1110 if let Some(e) = els {
1111 write!(indent, "\n{e}")?;
1112 }
1113 Ok(())
1114}
1115
1116fn display_index(mut indent: Indented<Formatter>, array: &Expr, index: &Expr) -> fmt::Result {
1117 write!(indent, "Index:")?;
1118 indent = set_indentation(indent, 1);
1119 write!(indent, "\n{array}")?;
1120 write!(indent, "\n{index}")?;
1121 Ok(())
1122}
1123
1124fn display_interpolate(
1125 mut indent: Indented<Formatter>,
1126 components: &[StringComponent],
1127) -> fmt::Result {
1128 write!(indent, "Interpolate:")?;
1129 indent = set_indentation(indent, 1);
1130 for component in components {
1131 match component {
1132 StringComponent::Expr(expr) => write!(indent, "\nExpr: {expr}")?,
1133 StringComponent::Lit(str) => write!(indent, "\nLit: {str:?}")?,
1134 }
1135 }
1136
1137 Ok(())
1138}
1139
1140fn display_lambda(
1141 mut indent: Indented<Formatter>,
1142 kind: CallableKind,
1143 param: &Pat,
1144 expr: &Expr,
1145) -> fmt::Result {
1146 write!(indent, "Lambda ({kind:?}):")?;
1147 indent = set_indentation(indent, 1);
1148 write!(indent, "\n{param}")?;
1149 write!(indent, "\n{expr}")?;
1150 Ok(())
1151}
1152
1153fn display_range(
1154 mut indent: Indented<Formatter>,
1155 start: Option<&Expr>,
1156 step: Option<&Expr>,
1157 end: Option<&Expr>,
1158) -> fmt::Result {
1159 write!(indent, "Range:")?;
1160 indent = set_indentation(indent, 1);
1161 match start {
1162 Some(e) => write!(indent, "\n{e}")?,
1163 None => write!(indent, "\n<no start>")?,
1164 }
1165 match step {
1166 Some(e) => write!(indent, "\n{e}")?,
1167 None => write!(indent, "\n<no step>")?,
1168 }
1169 match end {
1170 Some(e) => write!(indent, "\n{e}")?,
1171 None => write!(indent, "\n<no end>")?,
1172 }
1173 Ok(())
1174}
1175
1176fn display_repeat(
1177 mut indent: Indented<Formatter>,
1178 repeat: &Block,
1179 until: &Expr,
1180 fixup: Option<&Block>,
1181) -> fmt::Result {
1182 write!(indent, "Repeat:")?;
1183 indent = set_indentation(indent, 1);
1184 write!(indent, "\n{repeat}")?;
1185 write!(indent, "\n{until}")?;
1186 match fixup {
1187 Some(b) => write!(indent, "\n{b}")?,
1188 None => write!(indent, "\n<no fixup>")?,
1189 }
1190 Ok(())
1191}
1192
1193fn display_struct(
1194 mut indent: Indented<Formatter>,
1195 name: &PathKind,
1196 copy: Option<&Expr>,
1197 fields: &[Box<FieldAssign>],
1198) -> fmt::Result {
1199 write!(indent, "Struct ({name}):")?;
1200 if copy.is_none() && fields.is_empty() {
1201 write!(indent, " <empty>")?;
1202 return Ok(());
1203 }
1204 indent = set_indentation(indent, 1);
1205 if let Some(copy) = copy {
1206 write!(indent, "\nCopy: {copy}")?;
1207 }
1208 for field in fields {
1209 write!(indent, "\n{field}")?;
1210 }
1211 Ok(())
1212}
1213
1214fn display_tern_op(
1215 mut indent: Indented<Formatter>,
1216 op: TernOp,
1217 expr1: &Expr,
1218 expr2: &Expr,
1219 expr3: &Expr,
1220) -> fmt::Result {
1221 write!(indent, "TernOp ({op:?}):")?;
1222 indent = set_indentation(indent, 1);
1223 write!(indent, "\n{expr1}")?;
1224 write!(indent, "\n{expr2}")?;
1225 write!(indent, "\n{expr3}")?;
1226 Ok(())
1227}
1228
1229fn display_tuple(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
1230 if exprs.is_empty() {
1231 write!(indent, "Unit")?;
1232 } else {
1233 write!(indent, "Tuple:")?;
1234 indent = set_indentation(indent, 1);
1235 for e in exprs {
1236 write!(indent, "\n{e}")?;
1237 }
1238 }
1239 Ok(())
1240}
1241
1242fn display_un_op(mut indent: Indented<Formatter>, op: UnOp, expr: &Expr) -> fmt::Result {
1243 write!(indent, "UnOp ({op}):")?;
1244 indent = set_indentation(indent, 1);
1245 write!(indent, "\n{expr}")?;
1246 Ok(())
1247}
1248
1249fn display_while(mut indent: Indented<Formatter>, cond: &Expr, block: &Block) -> fmt::Result {
1250 write!(indent, "While:")?;
1251 indent = set_indentation(indent, 1);
1252 write!(indent, "\n{cond}")?;
1253 write!(indent, "\n{block}")?;
1254 Ok(())
1255}
1256
1257/// A field assignment in a struct constructor expression.
1258#[derive(Clone, Debug, Default, PartialEq)]
1259pub struct FieldAssign {
1260 /// The node ID.
1261 pub id: NodeId,
1262 /// The span.
1263 pub span: Span,
1264 /// The field to assign.
1265 pub field: Box<Ident>,
1266 /// The value to assign to the field.
1267 pub value: Box<Expr>,
1268}
1269
1270impl WithSpan for FieldAssign {
1271 fn with_span(self, span: Span) -> Self {
1272 Self { span, ..self }
1273 }
1274}
1275
1276impl Display for FieldAssign {
1277 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1278 write!(
1279 f,
1280 "FieldsAssign {} {}: ({}) {}",
1281 self.id, self.span, self.field, self.value
1282 )
1283 }
1284}
1285
1286/// An interpolated string component.
1287#[derive(Clone, Debug, PartialEq)]
1288pub enum StringComponent {
1289 /// An expression.
1290 Expr(Box<Expr>),
1291 /// A string literal.
1292 Lit(Rc<str>),
1293}
1294
1295/// A pattern.
1296#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1297pub struct Pat {
1298 /// The node ID.
1299 pub id: NodeId,
1300 /// The span.
1301 pub span: Span,
1302 /// The pattern kind.
1303 pub kind: Box<PatKind>,
1304}
1305
1306impl Display for Pat {
1307 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1308 write!(f, "Pat {} {}: {}", self.id, self.span, self.kind)
1309 }
1310}
1311
1312impl WithSpan for Pat {
1313 fn with_span(self, span: Span) -> Self {
1314 Self { span, ..self }
1315 }
1316}
1317
1318/// A pattern kind.
1319#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1320pub enum PatKind {
1321 /// A binding with an optional type annotation.
1322 Bind(Box<Ident>, Option<Box<Ty>>),
1323 /// A discarded binding, `_`, with an optional type annotation.
1324 Discard(Option<Box<Ty>>),
1325 /// An elided pattern, `...`, used by specializations.
1326 Elided,
1327 /// Parentheses: `(a)`.
1328 Paren(Box<Pat>),
1329 /// A tuple: `(a, b, c)`.
1330 Tuple(Box<[Box<Pat>]>),
1331 /// An invalid pattern.
1332 #[default]
1333 Err,
1334}
1335
1336impl Display for PatKind {
1337 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1338 let mut indent = set_indentation(indented(f), 0);
1339 match self {
1340 PatKind::Bind(id, ty) => {
1341 write!(indent, "Bind:")?;
1342 indent = set_indentation(indent, 1);
1343 write!(indent, "\n{id}")?;
1344 if let Some(t) = ty {
1345 write!(indent, "\n{t}")?;
1346 }
1347 }
1348 PatKind::Discard(d) => match d {
1349 Some(t) => {
1350 write!(indent, "Discard:")?;
1351 indent = set_indentation(indent, 1);
1352 write!(indent, "\n{t}")?;
1353 }
1354 None => write!(indent, "Discard")?,
1355 },
1356 PatKind::Elided => write!(indent, "Elided")?,
1357 PatKind::Paren(p) => {
1358 write!(indent, "Paren:")?;
1359 indent = set_indentation(indent, 1);
1360 write!(indent, "\n{p}")?;
1361 }
1362 PatKind::Tuple(ps) => {
1363 if ps.is_empty() {
1364 write!(indent, "Unit")?;
1365 } else {
1366 write!(indent, "Tuple:")?;
1367 indent = set_indentation(indent, 1);
1368 for p in ps {
1369 write!(indent, "\n{p}")?;
1370 }
1371 }
1372 }
1373 PatKind::Err => write!(indent, "Err")?,
1374 }
1375 Ok(())
1376 }
1377}
1378
1379/// A qubit initializer.
1380#[derive(Clone, Debug, PartialEq, Default)]
1381pub struct QubitInit {
1382 /// The node ID.
1383 pub id: NodeId,
1384 /// The span.
1385 pub span: Span,
1386 /// The qubit initializer kind.
1387 pub kind: Box<QubitInitKind>,
1388}
1389
1390impl Display for QubitInit {
1391 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1392 write!(f, "QubitInit {} {} {}", self.id, self.span, self.kind)
1393 }
1394}
1395
1396impl WithSpan for QubitInit {
1397 fn with_span(self, span: Span) -> Self {
1398 Self { span, ..self }
1399 }
1400}
1401
1402/// A qubit initializer kind.
1403#[derive(Clone, Debug, PartialEq, Default)]
1404pub enum QubitInitKind {
1405 /// An array of qubits: `Qubit[a]`.
1406 Array(Box<Expr>),
1407 /// A parenthesized initializer: `(a)`.
1408 Paren(Box<QubitInit>),
1409 /// A single qubit: `Qubit()`.
1410 Single,
1411 /// A tuple: `(a, b, c)`.
1412 Tuple(Box<[Box<QubitInit>]>),
1413 /// An invalid initializer.
1414 #[default]
1415 Err,
1416}
1417
1418impl Display for QubitInitKind {
1419 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1420 let mut indent = set_indentation(indented(f), 0);
1421 match self {
1422 QubitInitKind::Array(e) => {
1423 write!(indent, "Array:")?;
1424 indent = set_indentation(indent, 1);
1425 write!(indent, "\n{e}")?;
1426 }
1427 QubitInitKind::Paren(qi) => {
1428 write!(indent, "Parens:")?;
1429 indent = set_indentation(indent, 1);
1430 write!(indent, "\n{qi}")?;
1431 }
1432 QubitInitKind::Single => write!(indent, "Single")?,
1433 QubitInitKind::Tuple(qis) => {
1434 if qis.is_empty() {
1435 write!(indent, "Unit")?;
1436 } else {
1437 write!(indent, "Tuple:")?;
1438 indent = set_indentation(indent, 1);
1439 for qi in qis {
1440 write!(indent, "\n{qi}")?;
1441 }
1442 }
1443 }
1444 QubitInitKind::Err => write!(indent, "Err")?,
1445 }
1446 Ok(())
1447 }
1448}
1449
1450/// A path that may or may not have been successfully parsed.
1451#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1452pub enum PathKind {
1453 /// A successfully parsed path.
1454 Ok(Box<Path>),
1455
1456 /// An invalid path.
1457 Err(Option<Box<IncompletePath>>),
1458}
1459
1460impl Default for PathKind {
1461 fn default() -> Self {
1462 PathKind::Err(None)
1463 }
1464}
1465
1466/// A path that was successfully parsed up to a certain `.`,
1467/// but is missing its final identifier.
1468#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1469pub struct IncompletePath {
1470 /// The whole span of the incomplete path,
1471 /// including the final `.` and any whitespace or keyword
1472 /// that follows it.
1473 pub span: Span,
1474 /// Any segments that were successfully parsed before the final `.`.
1475 pub segments: Box<[Ident]>,
1476 /// Whether a keyword exists after the final `.`.
1477 /// This keyword can be presumed to be a partially typed identifier.
1478 pub keyword: bool,
1479}
1480
1481impl Display for PathKind {
1482 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1483 match self {
1484 PathKind::Ok(path) => write!(f, "{path}")?,
1485 PathKind::Err(Some(incomplete_path)) => {
1486 let mut indent = set_indentation(indented(f), 0);
1487 write!(indent, "Err IncompletePath {}:", incomplete_path.span)?;
1488 indent = set_indentation(indent, 1);
1489 for part in &incomplete_path.segments {
1490 write!(indent, "\n{part}")?;
1491 }
1492 }
1493 PathKind::Err(None) => write!(f, "Err",)?,
1494 }
1495 Ok(())
1496 }
1497}
1498
1499/// A path to a declaration or a field access expression,
1500/// to be disambiguated during name resolution.
1501#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1502pub struct Path {
1503 /// The node ID.
1504 pub id: NodeId,
1505 /// The span.
1506 pub span: Span,
1507 /// The segments that make up the front of the path before the final `.`.
1508 pub segments: Option<Box<[Ident]>>,
1509 /// The declaration or field name.
1510 pub name: Box<Ident>,
1511}
1512
1513impl Display for Path {
1514 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1515 if self.segments.is_none() {
1516 write!(f, "Path {} {} ({})", self.id, self.span, self.name)?;
1517 } else {
1518 let mut indent = set_indentation(indented(f), 0);
1519 write!(indent, "Path {} {}:", self.id, self.span)?;
1520 indent = set_indentation(indent, 1);
1521 if let Some(parts) = &self.segments {
1522 for part in parts {
1523 write!(indent, "\n{part}")?;
1524 }
1525 }
1526 write!(indent, "\n{}", self.name)?;
1527 }
1528 Ok(())
1529 }
1530}
1531
1532impl WithSpan for Path {
1533 fn with_span(self, span: Span) -> Self {
1534 Self { span, ..self }
1535 }
1536}
1537
1538/// An identifier.
1539#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1540pub struct Ident {
1541 /// The node ID.
1542 pub id: NodeId,
1543 /// The span.
1544 pub span: Span,
1545 /// The identifier name.
1546 pub name: Rc<str>,
1547}
1548
1549impl Default for Ident {
1550 fn default() -> Self {
1551 Ident {
1552 id: NodeId::default(),
1553 span: Span::default(),
1554 name: "".into(),
1555 }
1556 }
1557}
1558
1559impl WithSpan for Ident {
1560 fn with_span(self, span: Span) -> Self {
1561 Self { span, ..self }
1562 }
1563}
1564
1565impl Display for Ident {
1566 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1567 write!(f, "Ident {} {} \"{}\"", self.id, self.span, self.name)
1568 }
1569}
1570
1571/// Trait for working with dot-separated sequences of identifiers,
1572/// intended to unify the different representations that can appear
1573/// in the AST (`Path`s and `Ident` slices).
1574pub trait Idents {
1575 /// Iterates over the [`Ident`]s in this sequence.
1576 fn iter(&self) -> impl Iterator<Item = &Ident>;
1577
1578 /// The full dot-separated name represented by this [`Ident`] sequence.
1579 /// E.g. `a.b.c`
1580 fn full_name(&self) -> Rc<str> {
1581 let mut strs = self.rc_str_iter();
1582 let first = strs.next();
1583 let Some(first) = first else {
1584 // No parts, empty string
1585 return "".into();
1586 };
1587
1588 let next = strs.next();
1589 let Some(mut part) = next else {
1590 // Only one ident, return it directly
1591 return first.clone();
1592 };
1593
1594 // More than one ident, build up a dotted string
1595 let mut buf = String::new();
1596 buf.push_str(first);
1597 loop {
1598 buf.push('.');
1599 buf.push_str(part);
1600 part = match strs.next() {
1601 Some(part) => part,
1602 None => {
1603 break;
1604 }
1605 };
1606 }
1607 buf.into()
1608 }
1609
1610 /// Iterates over the identifier names as string slices.
1611 fn str_iter(&self) -> impl Iterator<Item = &str> {
1612 self.iter().map(|ident| ident.name.as_ref())
1613 }
1614
1615 /// Iterates over the identifier names as `Rc<str>`s.
1616 fn rc_str_iter(&self) -> impl Iterator<Item = &Rc<str>> {
1617 self.iter().map(|ident| &ident.name)
1618 }
1619
1620 /// Returns the conjoined span of all [`Ident`]s in this collection.
1621 #[must_use]
1622 fn full_span(&self) -> Span {
1623 let mut idents = self.iter().peekable();
1624 Span {
1625 lo: idents.peek().map(|i| i.span.lo).unwrap_or_default(),
1626 hi: idents.last().map(|i| i.span.hi).unwrap_or_default(),
1627 }
1628 }
1629}
1630
1631impl Idents for Box<[Ident]> {
1632 fn iter(&self) -> impl Iterator<Item = &Ident> {
1633 self.as_ref().iter() // invokes the slice iterator
1634 }
1635}
1636
1637impl Idents for &[Ident] {
1638 fn iter(&self) -> impl Iterator<Item = &Ident> {
1639 (*self).iter() // invokes the slice iterator
1640 }
1641}
1642
1643impl<T, U> Idents for (T, U)
1644where
1645 T: Idents,
1646 U: Idents,
1647{
1648 fn iter(&self) -> impl Iterator<Item = &Ident> {
1649 self.0.iter().chain(self.1.iter())
1650 }
1651}
1652
1653impl Idents for Ident {
1654 fn iter(&self) -> impl Iterator<Item = &Ident> {
1655 once(self)
1656 }
1657}
1658
1659impl Idents for &Ident {
1660 fn iter(&self) -> impl Iterator<Item = &Ident> {
1661 once(*self)
1662 }
1663}
1664
1665impl Idents for Path {
1666 fn iter(&self) -> impl Iterator<Item = &Ident> {
1667 self.segments
1668 .iter()
1669 .flat_map(Idents::iter)
1670 .chain(once(self.name.as_ref()))
1671 }
1672}
1673
1674/// A callable kind.
1675#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1676pub enum CallableKind {
1677 /// A function.
1678 Function,
1679 /// An operation.
1680 Operation,
1681}
1682
1683/// The mutability of a binding.
1684#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1685pub enum Mutability {
1686 /// An immutable binding.
1687 Immutable,
1688 /// A mutable binding.
1689 Mutable,
1690}
1691
1692/// The source of an allocated qubit.
1693#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1694pub enum QubitSource {
1695 /// A qubit initialized to the zero state.
1696 Fresh,
1697 /// A qubit borrowed from another part of the program that may be in any state, and is expected
1698 /// to be returned to that state before being released.
1699 Dirty,
1700}
1701
1702/// A literal.
1703#[derive(Clone, Debug, PartialEq)]
1704pub enum Lit {
1705 /// A big integer literal.
1706 BigInt(Box<BigInt>),
1707 /// A boolean literal.
1708 Bool(bool),
1709 /// A floating-point literal.
1710 Double(f64),
1711 /// A floating-point imaginary literal, e.g `1.0i`.
1712 Imaginary(f64),
1713 /// An integer literal.
1714 Int(i64),
1715 /// A Pauli operator literal.
1716 Pauli(Pauli),
1717 /// A measurement result literal.
1718 Result(Result),
1719 /// A string literal.
1720 String(Rc<str>),
1721}
1722
1723impl Display for Lit {
1724 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1725 match self {
1726 Lit::BigInt(val) => write!(f, "BigInt({val})")?,
1727 Lit::Bool(val) => write!(f, "Bool({val})")?,
1728 Lit::Double(val) => write!(f, "Double({val})")?,
1729 Lit::Imaginary(val) => write!(f, "Imaginary({val})")?,
1730 Lit::Int(val) => write!(f, "Int({val})")?,
1731 Lit::Pauli(val) => write!(f, "Pauli({val:?})")?,
1732 Lit::Result(val) => write!(f, "Result({val:?})")?,
1733 Lit::String(val) => write!(f, "String({val:?})")?,
1734 }
1735 Ok(())
1736 }
1737}
1738
1739/// A measurement result.
1740#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1741pub enum Result {
1742 /// The zero eigenvalue.
1743 Zero,
1744 /// The one eigenvalue.
1745 One,
1746}
1747
1748impl From<bool> for Result {
1749 fn from(b: bool) -> Self {
1750 if b { Result::One } else { Result::Zero }
1751 }
1752}
1753
1754/// A Pauli operator.
1755#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1756pub enum Pauli {
1757 /// The Pauli I operator.
1758 I,
1759 /// The Pauli X operator.
1760 X,
1761 /// The Pauli Y operator.
1762 Y,
1763 /// The Pauli Z operator.
1764 Z,
1765}
1766
1767/// A functor that may be applied to an operation.
1768#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1769pub enum Functor {
1770 /// The adjoint functor.
1771 Adj,
1772 /// The controlled functor.
1773 Ctl,
1774}
1775
1776/// A specialization that may be implemented for an operation.
1777#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1778pub enum Spec {
1779 /// The default specialization.
1780 Body,
1781 /// The adjoint specialization.
1782 Adj,
1783 /// The controlled specialization.
1784 Ctl,
1785 /// The controlled adjoint specialization.
1786 CtlAdj,
1787}
1788
1789impl Display for Spec {
1790 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1791 match self {
1792 Spec::Body => f.write_str("body"),
1793 Spec::Adj => f.write_str("adjoint"),
1794 Spec::Ctl => f.write_str("controlled"),
1795 Spec::CtlAdj => f.write_str("controlled adjoint"),
1796 }
1797 }
1798}
1799
1800/// A strategy for generating a specialization.
1801#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1802pub enum SpecGen {
1803 /// Choose a strategy automatically.
1804 Auto,
1805 /// Distributes controlled qubits.
1806 Distribute,
1807 /// A specialization implementation is not generated, but is instead left as an opaque
1808 /// declaration.
1809 Intrinsic,
1810 /// Inverts the order of operations.
1811 Invert,
1812 /// Uses the body specialization without modification.
1813 Slf,
1814}
1815
1816/// A unary operator.
1817#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1818pub enum UnOp {
1819 /// A functor application.
1820 Functor(Functor),
1821 /// Negation: `-`.
1822 Neg,
1823 /// Bitwise NOT: `~~~`.
1824 NotB,
1825 /// Logical NOT: `not`.
1826 NotL,
1827 /// A leading `+`.
1828 Pos,
1829 /// Unwrap a user-defined type: `!`.
1830 Unwrap,
1831}
1832
1833impl Display for UnOp {
1834 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1835 match self {
1836 UnOp::Functor(func) => write!(f, "Functor {func:?}")?,
1837 _ => fmt::Debug::fmt(self, f)?,
1838 }
1839 Ok(())
1840 }
1841}
1842
1843/// A binary operator.
1844#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1845pub enum BinOp {
1846 /// Addition: `+`.
1847 Add,
1848 /// Bitwise AND: `&&&`.
1849 AndB,
1850 /// Logical AND: `and`.
1851 AndL,
1852 /// Division: `/`.
1853 Div,
1854 /// Equality: `==`.
1855 Eq,
1856 /// Exponentiation: `^`.
1857 Exp,
1858 /// Greater than: `>`.
1859 Gt,
1860 /// Greater than or equal: `>=`.
1861 Gte,
1862 /// Less than: `<`.
1863 Lt,
1864 /// Less than or equal: `<=`.
1865 Lte,
1866 /// Modulus: `%`.
1867 Mod,
1868 /// Multiplication: `*`.
1869 Mul,
1870 /// Inequality: `!=`.
1871 Neq,
1872 /// Bitwise OR: `|||`.
1873 OrB,
1874 /// Logical OR: `or`.
1875 OrL,
1876 /// Shift left: `<<<`.
1877 Shl,
1878 /// Shift right: `>>>`.
1879 Shr,
1880 /// Subtraction: `-`.
1881 Sub,
1882 /// Bitwise XOR: `^^^`.
1883 XorB,
1884}
1885
1886/// A ternary operator.
1887#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1888pub enum TernOp {
1889 /// Conditional: `a ? b | c`.
1890 Cond,
1891 /// Aggregate update: `a w/ b <- c`.
1892 Update,
1893}
1894
1895/// A set operator.
1896#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1897pub enum SetOp {
1898 /// The set union.
1899 Union,
1900 /// The set intersection.
1901 Intersect,
1902}
1903
1904#[derive(Clone, Debug, Eq, PartialEq)]
1905/// Represents an export declaration.
1906pub struct ImportOrExportDecl {
1907 /// The span.
1908 pub span: Span,
1909 /// The items being exported from this namespace.
1910 pub items: Box<[ImportOrExportItem]>,
1911 /// Whether this is an export declaration or not. If `false`, then this is an `Import`.
1912 is_export: bool,
1913}
1914
1915impl Display for ImportOrExportDecl {
1916 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1917 let mut indent = set_indentation(indented(f), 0);
1918 if self.is_export {
1919 write!(indent, "Export")?;
1920 } else {
1921 write!(indent, "Import")?;
1922 }
1923 write!(indent, " {}:", self.span)?;
1924 indent = set_indentation(indent, 1);
1925 for item in &self.items {
1926 write!(indent, "\n{item}")?;
1927 }
1928 Ok(())
1929 }
1930}
1931
1932impl ImportOrExportDecl {
1933 /// Creates a new `ImportOrExportDecl` with the given span, items, and export flag.
1934 #[must_use]
1935 pub fn new(span: Span, items: Box<[ImportOrExportItem]>, is_export: bool) -> Self {
1936 Self {
1937 span,
1938 items,
1939 is_export,
1940 }
1941 }
1942
1943 /// Returns true if this is an export declaration.
1944 #[must_use]
1945 pub fn is_export(&self) -> bool {
1946 self.is_export
1947 }
1948
1949 /// Returns true if this is an import declaration.
1950 #[must_use]
1951 pub fn is_import(&self) -> bool {
1952 !self.is_export
1953 }
1954}
1955
1956/// An individual item within an [`ImportOrExportDecl`]. This can be a path or a path with an alias.
1957#[derive(Clone, Debug, Eq, PartialEq, Default)]
1958pub struct ImportOrExportItem {
1959 /// The span of the import path including the wildcard and alias, if any.
1960 pub span: Span,
1961 /// The path to the item being exported.
1962 pub path: PathKind,
1963 /// The kind of import being performed, direct or wildcard.
1964 pub kind: ImportKind,
1965}
1966
1967impl Display for ImportOrExportItem {
1968 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1969 write!(f, "{} ", self.span)?;
1970 match &self.kind {
1971 ImportKind::Wildcard => write!(f, "Wildcard")?,
1972 ImportKind::Direct { alias } => {
1973 write!(f, "Direct")?;
1974 if let Some(alias) = alias {
1975 write!(f, " (alias: {alias})")?;
1976 }
1977 }
1978 }
1979 write!(f, ": {}", self.path)
1980 }
1981}
1982
1983impl WithSpan for ImportOrExportItem {
1984 fn with_span(self, span: Span) -> Self {
1985 Self { span, ..self }
1986 }
1987}
1988
1989impl ImportOrExportItem {
1990 /// Returns the alias ident, if any, or the name from the path if no alias is present.
1991 /// Returns `None` if the path has an error.
1992 #[must_use]
1993 pub fn name(&self) -> Option<&Ident> {
1994 match &self.kind {
1995 ImportKind::Wildcard => None,
1996 ImportKind::Direct { alias } => alias.as_ref().or_else(|| match &self.path {
1997 PathKind::Ok(path) => Some(path.name.as_ref()),
1998 PathKind::Err(_) => None,
1999 }),
2000 }
2001 }
2002}
2003
2004/// The kind of import being performed in an `ImportOrExportItem`.
2005#[derive(Clone, Debug, Eq, PartialEq)]
2006pub enum ImportKind {
2007 /// A wildcard import: `import A.*`
2008 Wildcard,
2009 /// A direct import or export: `import A.B`, `export A`, etc.
2010 Direct {
2011 /// An optional alias for the item being imported.
2012 alias: Option<Ident>,
2013 },
2014}
2015
2016impl Default for ImportKind {
2017 fn default() -> Self {
2018 ImportKind::Direct { alias: None }
2019 }
2020}
2021
2022/// A [`TypeParameter`] is a generic type variable with optional bounds (constraints).
2023#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
2024pub struct TypeParameter {
2025 /// Class constraints specified for this type parameter -- any type variable passed in
2026 /// as an argument to these parameters must satisfy these constraints.
2027 pub constraints: ClassConstraints,
2028 /// The name of the type parameter.
2029 pub ty: Ident,
2030 /// The span of the full type parameter, including its name and its constraints.
2031 pub span: Span,
2032}
2033
2034impl WithSpan for TypeParameter {
2035 fn with_span(self, span: Span) -> Self {
2036 Self { span, ..self }
2037 }
2038}
2039
2040impl TypeParameter {
2041 /// Instantiates a new `TypeParameter` with the given type name, constraints, and span.
2042 #[must_use]
2043 pub fn new(ty: Ident, bounds: ClassConstraints, span: Span) -> Self {
2044 Self {
2045 ty,
2046 constraints: bounds,
2047 span,
2048 }
2049 }
2050}
2051
2052impl std::fmt::Display for TypeParameter {
2053 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2054 // 'A: Eq + Ord + Clone
2055 write!(
2056 f,
2057 "{}{}",
2058 self.ty.name,
2059 if self.constraints.0.is_empty() {
2060 Default::default()
2061 } else {
2062 format!(": {}", self.constraints)
2063 }
2064 )
2065 }
2066}
2067
2068/// A list of class constraints, used when constraining a type parameter.
2069#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
2070pub struct ClassConstraints(pub Box<[ClassConstraint]>);
2071
2072/// An individual class constraint, used when constraining a type parameter.
2073/// To understand this concept, think of parameters in a function signature -- the potential arguments that can
2074/// be passed to them are constrained by what type is specified. Type-level parameters are no different, and
2075/// the type variables that are passed to a type parameter must satisfy the constraints specified in the type parameter.
2076#[derive(PartialEq, Eq, Clone, Hash, Debug)]
2077pub struct ClassConstraint {
2078 /// The name of the constraint.
2079 pub name: Ident,
2080 /// Parameters for a constraint. For example, `Iterator` has a parameter `T` in `Iterator<T>` -- this
2081 /// is the type of the item that is coming out of the iterator.
2082 pub parameters: Box<[ConstraintParameter]>,
2083}
2084
2085impl std::fmt::Display for ClassConstraint {
2086 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2087 // Iterator<T>
2088 write!(
2089 f,
2090 "{}{}",
2091 self.name.name,
2092 if self.parameters.is_empty() {
2093 String::new()
2094 } else {
2095 format!(
2096 "[{}]",
2097 self.parameters
2098 .iter()
2099 .map(|x| x.ty.to_string())
2100 .collect::<Vec<_>>()
2101 .join(", ")
2102 )
2103 }
2104 )
2105 }
2106}
2107
2108/// An individual constraint parameter is a type that is passed to a constraint, such as `T` in `Iterator<T>`.
2109/// #[derive(Default, `PartialEq`, Eq, Clone, Hash, Debug)]
2110#[derive(Default, PartialEq, Eq, Clone, Hash, Debug)]
2111pub struct ConstraintParameter {
2112 /// The type variable being passed as a constraint parameter.
2113 pub ty: Ty,
2114}
2115
2116impl WithSpan for ConstraintParameter {
2117 fn with_span(self, span: Span) -> Self {
2118 Self {
2119 ty: self.ty.with_span(span),
2120 }
2121 }
2122}
2123
2124impl ClassConstraint {
2125 /// Getter for the `span` field of the `name` field (the name of the class constraint).
2126 #[must_use]
2127 pub fn span(&self) -> Span {
2128 self.name.span
2129 }
2130}
2131
2132impl ClassConstraints {
2133 /// The conjoined span of all of the bounds
2134 #[must_use]
2135 pub fn span(&self) -> Span {
2136 Span {
2137 lo: self.0.first().map(|i| i.span().lo).unwrap_or_default(),
2138 hi: self.0.last().map(|i| i.span().hi).unwrap_or_default(),
2139 }
2140 }
2141}
2142
2143impl std::fmt::Display for ClassConstraints {
2144 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2145 // A + B + C + D
2146 write!(
2147 f,
2148 "{}",
2149 self.0
2150 .iter()
2151 .map(|x| format!("{}", x.name.name,))
2152 .collect::<Vec<_>>()
2153 .join(" + "),
2154 )
2155 }
2156}
2157